From 4fade93b431eb16957c445b47bcbddbb68fb791a Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Sun, 19 Mar 2023 15:51:04 +0530 Subject: [PATCH 01/38] Fix compilation --- src/utils/strings/frenchConstants.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/strings/frenchConstants.tsx b/src/utils/strings/frenchConstants.tsx index e1f236cc7..a073dd56f 100644 --- a/src/utils/strings/frenchConstants.tsx +++ b/src/utils/strings/frenchConstants.tsx @@ -553,7 +553,7 @@ const frenchConstants = { LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE: 'Votre navigateur ou un complément bloque ente qui ne peut sauvegarder les données sur votre stockage local. Veuillez relancer cette page après avoir changé de mode de navigation.', RETRY: 'Réessayer', - SEND_OTT: 'Envoyer l'OTP', + SEND_OTT: "Envoyer l'OTP", EMAIl_ALREADY_OWNED: 'Cet e-mail est déjà pris', EMAIL_UDPATE_SUCCESSFUL: 'Votre e-mail a été mis à jour', UPLOAD_FAILED: 'Échec du chargement', From 6da5198c749f9d1679be6eda0589cd3187c090eb Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Sun, 19 Mar 2023 15:54:23 +0530 Subject: [PATCH 02/38] Add TimerProgress componenet --- src/components/Authenicator/TimerProgress.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/components/Authenicator/TimerProgress.tsx diff --git a/src/components/Authenicator/TimerProgress.tsx b/src/components/Authenicator/TimerProgress.tsx new file mode 100644 index 000000000..c9234f4ac --- /dev/null +++ b/src/components/Authenicator/TimerProgress.tsx @@ -0,0 +1,46 @@ +import React, { useState, useEffect } from 'react'; + +const TimerProgress = ({ period }) => { + const [progress, setProgress] = useState(0); + const [ticker, setTicker] = useState(null); + const microSecondsInPeriod = period * 1000000; + + const startTicker = () => { + const ticker = setInterval(() => { + updateTimeRemaining(); + }, 10); + setTicker(ticker); + }; + + const updateTimeRemaining = () => { + const timeRemaining = + microSecondsInPeriod - + ((new Date().getTime() * 1000) % microSecondsInPeriod); + setProgress(timeRemaining / microSecondsInPeriod); + }; + + useEffect(() => { + startTicker(); + return () => clearInterval(ticker); + }, []); + + const color = progress > 0.4 ? 'green' : 'orange'; + + return ( +
+ {issuer} +
++ {account} +
++ {code} +
++ next +
++ {nextCode} +
+No results found.
+ {/*Add a new secret to get started.
+Download ente auth mobile app to manage your secrets
*/} + => {
+ const masterKey = await getActualKey();
+ try {
+ const authKeyData = await getAuthKey();
+ const cryptoWorker = await ComlinkCryptoWorker.getInstance();
+ const authentitorKey = await cryptoWorker.decryptB64(
+ authKeyData.encryptedKey,
+ authKeyData.header,
+ masterKey
+ );
+ // always fetch all data from server for now
+ const authEntity: AuthEntity[] = await getDiff(0);
+ const authCodes = await Promise.all(
+ authEntity
+ .filter((f) => !f.isDeleted)
+ .map(async (entity) => {
+ const decryptedCode = await cryptoWorker.decryptMetadata(
+ entity.encryptedData,
+ entity.header,
+ authentitorKey
+ );
+ return Code.fromRawData(entity.id, decryptedCode);
+ })
+ );
+ // sort by issuer name which can be undefined also
+ authCodes.sort((a, b) => {
+ if (a.issuer && b.issuer) {
+ return a.issuer.localeCompare(b.issuer);
+ }
+ if (a.issuer) {
+ return -1;
+ }
+ if (b.issuer) {
+ return 1;
+ }
+ return 0;
+ });
+ return authCodes;
+ } catch (e) {
+ logError(e, 'get authenticator entities failed');
+ throw e;
+ }
+};
+
+export const getAuthKey = async () => {
+ try {
+ const resp = await HTTPService.get(
+ `${ENDPOINT}/authenticator/key`,
+ {},
+ {
+ 'X-Auth-Token': getToken(),
+ }
+ );
+ return resp.data;
+ } catch (e) {
+ logError(e, 'Get key failed');
+ throw e;
+ }
+};
+
+// return a promise which resolves to list of AuthEnitity
+export const getDiff = async (
+ sinceTime: number,
+ limit = 2500
+): Promise => {
+ try {
+ const resp = await HTTPService.get(
+ `${ENDPOINT}/authenticator/entity/diff`,
+ {
+ sinceTime,
+ limit,
+ },
+ {
+ 'X-Auth-Token': getToken(),
+ }
+ );
+ return resp.data.diff;
+ } catch (e) {
+ logError(e, 'Get diff failed');
+ throw e;
+ }
+};
From 208e6c07fe80a54b61917b7ae4a609b49e2762fc Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 09:26:29 +0530
Subject: [PATCH 08/38] Refactor
---
src/components/Authenicator/OTPDisplay.tsx | 50 ++++++++++++----------
src/components/Sidebar/UtilitySection.tsx | 2 +-
2 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index b0c1faec3..9be78988c 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import { TOTP, HOTP } from 'otpauth';
+import { Code } from 'types/authenticator/code';
import TimerProgress from './TimerProgress';
const TOTPDisplay = ({ issuer, account, code, nextCode }) => {
@@ -82,59 +83,64 @@ const TOTPDisplay = ({ issuer, account, code, nextCode }) => {
);
};
-const OTPDisplay = ({
- secret,
- type,
- algorithm,
- timePeriod,
- issuer,
- account,
-}) => {
+interface OTPDisplayProps {
+ codeInfo: Code;
+}
+
+const OTPDisplay = (props: OTPDisplayProps) => {
+ const { codeInfo } = props;
const [code, setCode] = useState('');
const [nextcode, setNextCode] = useState('');
const generateCodes = () => {
const currentTime = new Date().getTime();
- if (type.toLowerCase() === 'totp') {
+ if (codeInfo.type.toLowerCase() === 'totp') {
const totp = new TOTP({
- secret,
- algorithm,
- period: timePeriod ?? 30,
+ secret: codeInfo.secret,
+ algorithm: codeInfo.algorithm,
+ period: codeInfo.period ?? Code.defaultPeriod,
+ digits: codeInfo.digits,
});
setCode(totp.generate());
setNextCode(
- totp.generate({ timestamp: currentTime + timePeriod * 1000 })
+ totp.generate({
+ timestamp: currentTime + codeInfo.period * 1000,
+ })
);
- } else if (type.toLowerCase() === 'hotp') {
- const hotp = new HOTP({ secret, counter: 0, algorithm });
+ } else if (codeInfo.type.toLowerCase() === 'hotp') {
+ const hotp = new HOTP({
+ secret: codeInfo.secret,
+ counter: 0,
+ algorithm: codeInfo.algorithm,
+ });
setCode(hotp.generate());
setNextCode(hotp.generate({ counter: 1 }));
}
};
useEffect(() => {
+ generateCodes();
let intervalId;
- // compare case insensitive type
- if (type.toLowerCase() === 'totp') {
+ if (codeInfo.type.toLowerCase() === 'totp') {
intervalId = setInterval(() => {
generateCodes();
}, 1000);
- } else if (type.toLowerCase() === 'hotp') {
+ } else if (codeInfo.type.toLowerCase() === 'hotp') {
intervalId = setInterval(() => {
generateCodes();
}, 1000);
}
return () => clearInterval(intervalId);
- }, [secret, type, algorithm, timePeriod]);
+ }, [codeInfo]);
return (
-
+
diff --git a/src/components/Sidebar/UtilitySection.tsx b/src/components/Sidebar/UtilitySection.tsx
index f797b92cb..5d1ff9142 100644
--- a/src/components/Sidebar/UtilitySection.tsx
+++ b/src/components/Sidebar/UtilitySection.tsx
@@ -99,7 +99,7 @@ export default function UtilitySection({ closeSidebar }) {
{constants.DEDUPLICATE_FILES}
- {isInternalUser() && (
+ {!isInternalUser() && (
{constants.AUTHENTICATOR_SECTION}
From 5618e65fe10e9057eb7cf5d257dcb78be2d503db Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 09:31:12 +0530
Subject: [PATCH 09/38] [ente Authenticator] Remove hardcoded codes
---
src/pages/authenticator/index.tsx | 93 ++++++-------------------------
1 file changed, 17 insertions(+), 76 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 40421483a..05022424a 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -1,83 +1,32 @@
import React, { useEffect, useState } from 'react';
import OTPDisplay from 'components/Authenicator/OTPDisplay';
-const random = [
- {
- issuer: 'Google',
- account: 'example@gmail.com',
- secret: '6GJ2E2RQKJ36BY6A',
- type: 'TOTP',
- algorithm: 'SHA1',
- period: 30,
- },
- {
- issuer: 'Facebook',
- account: 'example@gmail.com',
- secret: 'RVZJ7N6KJKJGQ2VX',
- type: 'TOTP',
- algorithm: 'SHA256',
- period: 60,
- },
- {
- issuer: 'Twitter',
- account: 'example@gmail.com',
- secret: 'ZPUE6KJ3WGZ3HPKJ',
- type: 'TOTP',
- algorithm: 'SHA256',
- period: 60,
- },
- {
- issuer: 'GitHub',
- account: 'example@gmail.com',
- secret: 'AG6U5KJYHPRRNRZI',
- type: 'TOTP',
- algorithm: 'SHA1',
- period: 30,
- },
- {
- issuer: 'Amazon',
- account: 'example@gmail.com',
- secret: 'Q2FR2KJVKJFFKMWZ',
- type: 'TOTP',
- algorithm: 'SHA256',
- period: 60,
- },
- {
- issuer: 'LinkedIn',
- account: 'example@gmail.com',
- secret: 'SWRG4KJ4J3LNDW2Z',
- type: 'TOTP',
- algorithm: 'SHA256',
- period: 60,
- },
- {
- issuer: 'Dropbox',
- account: 'example@gmail.com',
- secret: 'G5U6OKJU3JRM72ZK',
- type: 'TOTP',
- algorithm: 'SHA1',
- period: 30,
- },
-];
+import { getAuthCodes } from 'services/authenticator/authenticatorService';
const OTPPage = () => {
- const [secrets, setSecrets] = useState([]);
+ const [codes, setCodes] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
useEffect(() => {
- const fetchSecrets = async () => {
+ const fetchCodes = async () => {
try {
- setSecrets(random);
+ getAuthCodes().then((res) => {
+ setCodes(res);
+ });
} catch (error) {
console.error(error);
}
};
- fetchSecrets();
+ fetchCodes();
}, []);
- const filteredSecrets = secrets.filter(
+ const filteredCodes = codes.filter(
(secret) =>
- secret.issuer.toLowerCase().includes(searchTerm.toLowerCase()) ||
- secret.account.toLowerCase().includes(searchTerm.toLowerCase())
+ (secret.issuer ?? '')
+ .toLowerCase()
+ .includes(searchTerm.toLowerCase()) ||
+ (secret.account ?? '')
+ .toLowerCase()
+ .includes(searchTerm.toLowerCase())
);
return (
@@ -98,7 +47,7 @@ const OTPPage = () => {
/>
- {filteredSecrets.length === 0 ? (
+ {filteredCodes.length === 0 ? (
{
Download ente auth mobile app to manage your secrets
*/}
) : (
- filteredSecrets.map((secret) => (
-
+ filteredCodes.map((code) => (
+
))
)}
From 937d114f7c220b8a75ad3f4adc71bf3f79952b2d Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 10:23:14 +0530
Subject: [PATCH 10/38] Add hook to download ente auth app
---
src/pages/authenticator/index.tsx | 37 +++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 05022424a..dbb6cee99 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import OTPDisplay from 'components/Authenicator/OTPDisplay';
import { getAuthCodes } from 'services/authenticator/authenticatorService';
+import { Button } from '@mui/material';
const OTPPage = () => {
const [codes, setCodes] = useState([]);
@@ -29,8 +30,31 @@ const OTPPage = () => {
.includes(searchTerm.toLowerCase())
);
+ const DownloadApp = () => {
+ return (
+
+ Download our mobile app to add & manage your secrets.
+
+
+
+
+ );
+ };
+
return (
- // center the page
{
textAlign: 'center',
marginTop: '32px',
}}>
- No results found.
- {/* Add a new secret to get started.
- Download ente auth mobile app to manage your secrets
*/}
+ {searchTerm.length !== 0 ? (
+ No results found.
+ ) : (
+
+ )}
) : (
filteredCodes.map((code) => (
))
)}
+
+
+
);
};
From aaa3a273c0c5d7c1494101a886799d33e0fb5f50 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 10:26:40 +0530
Subject: [PATCH 11/38] Show authenticator section to internal users only
---
src/components/Sidebar/UtilitySection.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/Sidebar/UtilitySection.tsx b/src/components/Sidebar/UtilitySection.tsx
index 5d1ff9142..f797b92cb 100644
--- a/src/components/Sidebar/UtilitySection.tsx
+++ b/src/components/Sidebar/UtilitySection.tsx
@@ -99,7 +99,7 @@ export default function UtilitySection({ closeSidebar }) {
{constants.DEDUPLICATE_FILES}
- {!isInternalUser() && (
+ {isInternalUser() && (
{constants.AUTHENTICATOR_SECTION}
From 7c8739a57b351ef12ee660768b19a5123d469bcf Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 10:43:17 +0530
Subject: [PATCH 12/38] [ente auth] redirect to root if key is missing
---
src/pages/authenticator/index.tsx | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index dbb6cee99..c5f5fab0b 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
import OTPDisplay from 'components/Authenicator/OTPDisplay';
import { getAuthCodes } from 'services/authenticator/authenticatorService';
import { Button } from '@mui/material';
+import { CustomError } from 'utils/error';
const OTPPage = () => {
const [codes, setCodes] = useState([]);
@@ -10,10 +11,20 @@ const OTPPage = () => {
useEffect(() => {
const fetchCodes = async () => {
try {
- getAuthCodes().then((res) => {
- setCodes(res);
- });
+ getAuthCodes()
+ .then((res) => {
+ setCodes(res);
+ })
+ .catch((err) => {
+ if (err.message === CustomError.KEY_MISSING) {
+ window.location.href = '/';
+ return;
+ }
+
+ console.error('something wrong here', err);
+ });
} catch (error) {
+ console.error('something wrong where asdas');
console.error(error);
}
};
From e8d8ffacc995287c6348773e831d406c8abbc4b7 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 11:00:33 +0530
Subject: [PATCH 13/38] Fix routing on redirect to creds page
---
src/pages/authenticator/index.tsx | 9 +++++++--
src/pages/credentials/index.tsx | 4 +++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index c5f5fab0b..967be144b 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -3,8 +3,11 @@ import OTPDisplay from 'components/Authenicator/OTPDisplay';
import { getAuthCodes } from 'services/authenticator/authenticatorService';
import { Button } from '@mui/material';
import { CustomError } from 'utils/error';
+import { PAGES } from 'constants/pages';
+import { useRouter } from 'next/router';
const OTPPage = () => {
+ const router = useRouter();
const [codes, setCodes] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
@@ -17,10 +20,12 @@ const OTPPage = () => {
})
.catch((err) => {
if (err.message === CustomError.KEY_MISSING) {
- window.location.href = '/';
+ router.push({
+ pathname: PAGES.CREDENTIALS,
+ query: { redirectPage: PAGES.AUTHENICATOR },
+ });
return;
}
-
console.error('something wrong here', err);
});
} catch (error) {
diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx
index 02c54f389..2e3359a83 100644
--- a/src/pages/credentials/index.tsx
+++ b/src/pages/credentials/index.tsx
@@ -30,6 +30,8 @@ import VerifyMasterPasswordForm, {
export default function Credentials() {
const router = useRouter();
+ const routeReidrectPage =
+ router.query.redirectPage?.toString() ?? PAGES.GALLERY;
const [keyAttributes, setKeyAttributes] = useState();
const appContext = useContext(AppContext);
const [user, setUser] = useState();
@@ -85,7 +87,7 @@ export default function Credentials() {
await decryptAndStoreToken(key);
const redirectURL = appContext.redirectURL;
appContext.setRedirectURL(null);
- router.push(redirectURL ?? PAGES.GALLERY);
+ router.push(redirectURL ?? routeReidrectPage ?? PAGES.GALLERY);
} catch (e) {
logError(e, 'useMasterPassword failed');
}
From 02e2de1ef588733eb2c743339113f9418aa3b43a Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 11:04:50 +0530
Subject: [PATCH 14/38] Hide search box when there's no entry
---
src/pages/authenticator/index.tsx | 17 +++++++++++------
.../authenticator/authenticatorService.ts | 3 +++
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 967be144b..f40cf5ef1 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -78,13 +78,18 @@ const OTPPage = () => {
alignItems: 'center',
justifyContent: 'flex-start',
}}>
+
ente Authenticator
- setSearchTerm(e.target.value)}
- />
+ {filteredCodes.length === 0 && searchTerm.length === 0 ? (
+ <>>
+ ) : (
+ setSearchTerm(e.target.value)}
+ />
+ )}
{filteredCodes.length === 0 ? (
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index ebe80149e..8027661bd 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -44,6 +44,9 @@ export const getAuthCodes = async (): Promise => {
}
return 0;
});
+ // remove all entries from authCodes
+ authCodes.splice(0, authCodes.length);
+
return authCodes;
} catch (e) {
logError(e, 'get authenticator entities failed');
From 6d094b3bcad17487a02f03b24e38998fc7001e81 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 11:05:57 +0530
Subject: [PATCH 15/38] Undo test changes
---
src/services/authenticator/authenticatorService.ts | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index 8027661bd..ebe80149e 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -44,9 +44,6 @@ export const getAuthCodes = async (): Promise => {
}
return 0;
});
- // remove all entries from authCodes
- authCodes.splice(0, authCodes.length);
-
return authCodes;
} catch (e) {
logError(e, 'get authenticator entities failed');
From 134cd8343bc83204c53e03e3a64c86b4487e9569 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 20 Mar 2023 11:58:39 +0530
Subject: [PATCH 16/38] Handle error in generating code
---
src/components/Authenicator/OTPDisplay.tsx | 77 ++++++++++++-------
.../authenticator/authenticatorService.ts | 13 +++-
2 files changed, 61 insertions(+), 29 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index 9be78988c..f476dc4ff 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -91,30 +91,35 @@ const OTPDisplay = (props: OTPDisplayProps) => {
const { codeInfo } = props;
const [code, setCode] = useState('');
const [nextcode, setNextCode] = useState('');
+ const [codeErr, setCodeErr] = useState('');
const generateCodes = () => {
- const currentTime = new Date().getTime();
- if (codeInfo.type.toLowerCase() === 'totp') {
- const totp = new TOTP({
- secret: codeInfo.secret,
- algorithm: codeInfo.algorithm,
- period: codeInfo.period ?? Code.defaultPeriod,
- digits: codeInfo.digits,
- });
- setCode(totp.generate());
- setNextCode(
- totp.generate({
- timestamp: currentTime + codeInfo.period * 1000,
- })
- );
- } else if (codeInfo.type.toLowerCase() === 'hotp') {
- const hotp = new HOTP({
- secret: codeInfo.secret,
- counter: 0,
- algorithm: codeInfo.algorithm,
- });
- setCode(hotp.generate());
- setNextCode(hotp.generate({ counter: 1 }));
+ try {
+ const currentTime = new Date().getTime();
+ if (codeInfo.type.toLowerCase() === 'totp') {
+ const totp = new TOTP({
+ secret: codeInfo.secret,
+ algorithm: codeInfo.algorithm,
+ period: codeInfo.period ?? Code.defaultPeriod,
+ digits: codeInfo.digits,
+ });
+ setCode(totp.generate());
+ setNextCode(
+ totp.generate({
+ timestamp: currentTime + codeInfo.period * 1000,
+ })
+ );
+ } else if (codeInfo.type.toLowerCase() === 'hotp') {
+ const hotp = new HOTP({
+ secret: codeInfo.secret,
+ counter: 0,
+ algorithm: codeInfo.algorithm,
+ });
+ setCode(hotp.generate());
+ setNextCode(hotp.generate({ counter: 1 }));
+ }
+ } catch (err) {
+ setCodeErr(err.message);
}
};
@@ -138,12 +143,28 @@ const OTPDisplay = (props: OTPDisplayProps) => {
return (
-
+ {codeErr === '' ? (
+
+ ) : (
+
+ {codeErr}
+ {codeInfo.rawData ?? 'no rawdata'}
+
+ )}
);
};
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index ebe80149e..4f64b0811 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -28,8 +28,19 @@ export const getAuthCodes = async (): Promise => {
entity.header,
authentitorKey
);
- return Code.fromRawData(entity.id, decryptedCode);
+ try {
+ return Code.fromRawData(entity.id, decryptedCode);
+ } catch (e) {
+ console.log(
+ 'failed to parse code',
+ e,
+ entity.id,
+ decryptedCode
+ );
+ return null;
+ }
})
+ .filter((f) => f !== null || f !== undefined)
);
// sort by issuer name which can be undefined also
authCodes.sort((a, b) => {
From 6cb022dede77c1e000565dc494b4a2c4c6089a9d Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 21 Mar 2023 14:11:37 +0530
Subject: [PATCH 17/38] Fix code generation
---
src/components/Authenicator/OTPDisplay.tsx | 4 ++--
src/types/authenticator/code.ts | 13 ++++++++++---
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index f476dc4ff..7a851aeca 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -99,9 +99,9 @@ const OTPDisplay = (props: OTPDisplayProps) => {
if (codeInfo.type.toLowerCase() === 'totp') {
const totp = new TOTP({
secret: codeInfo.secret,
- algorithm: codeInfo.algorithm,
+ algorithm: codeInfo.algorithm ?? Code.defaultAlgo,
period: codeInfo.period ?? Code.defaultPeriod,
- digits: codeInfo.digits,
+ digits: codeInfo.digits ?? Code.defaultDigits,
});
setCode(totp.generate());
setNextCode(
diff --git a/src/types/authenticator/code.ts b/src/types/authenticator/code.ts
index 8e94d7b45..cc244a4c4 100644
--- a/src/types/authenticator/code.ts
+++ b/src/types/authenticator/code.ts
@@ -12,6 +12,7 @@ type AlgorithmType =
export class Code {
static readonly defaultDigits = 6;
+ static readonly defaultAlgo = 'sha1';
static readonly defaultPeriod = 30;
// id for the corresponding auth entity
@@ -70,12 +71,14 @@ export class Code {
});
const uri = URI.parse(santizedRawData);
- let uriPath = uri.path;
+ let uriPath = decodeURIComponent(uri.path);
if (
uriPath.startsWith('/otpauth://') ||
uriPath.startsWith('otpauth://')
) {
uriPath = uriPath.split('otpauth://')[1];
+ } else if (uriPath.startsWith('otpauth%3A//')) {
+ uriPath = uriPath.split('otpauth%3A//')[1];
}
return new Code(
@@ -94,7 +97,11 @@ export class Code {
private static _getAccount(uriPath: string): string {
try {
const path = decodeURIComponent(uriPath);
- return path.split(':')[1];
+ if (path.includes(':')) {
+ return path.split(':')[1];
+ } else if (path.includes('/')) {
+ return path.split('/')[1];
+ }
} catch (e) {
return '';
}
@@ -122,7 +129,7 @@ export class Code {
private static _getDigits(uriParams): number {
try {
- return parseInt(uriParams['digits'], 10);
+ return parseInt(uriParams['digits'], 10) || Code.defaultDigits;
} catch (e) {
return Code.defaultDigits;
}
From d2ebf79b47d50cbf6575a4b1cbc9316157eda717 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 21 Mar 2023 14:36:14 +0530
Subject: [PATCH 18/38] Remove logging for rawCode
---
src/services/authenticator/authenticatorService.ts | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index 4f64b0811..cdf31f7ab 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -31,12 +31,7 @@ export const getAuthCodes = async (): Promise => {
try {
return Code.fromRawData(entity.id, decryptedCode);
} catch (e) {
- console.log(
- 'failed to parse code',
- e,
- entity.id,
- decryptedCode
- );
+ console.log('failed to parse code', e, entity.id);
return null;
}
})
From 0746deff74bdf27a9cb2d98fabe95d306338beb1 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 21 Mar 2023 16:23:31 +0530
Subject: [PATCH 19/38] Log codeInfo
---
src/components/Authenicator/OTPDisplay.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index 7a851aeca..bcaecb760 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -119,6 +119,7 @@ const OTPDisplay = (props: OTPDisplayProps) => {
setNextCode(hotp.generate({ counter: 1 }));
}
} catch (err) {
+ console.log('codeInfo', codeInfo);
setCodeErr(err.message);
}
};
From aaa301d09dba71aaf73ae23fcc1c3c4851b15b34 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 22 Mar 2023 12:44:45 +0530
Subject: [PATCH 20/38] [ente authenticator] Handle \r
---
src/types/authenticator/code.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/types/authenticator/code.ts b/src/types/authenticator/code.ts
index cc244a4c4..de32ad611 100644
--- a/src/types/authenticator/code.ts
+++ b/src/types/authenticator/code.ts
@@ -51,7 +51,8 @@ export class Code {
static fromRawData(id: string, rawData: string): Code {
let santizedRawData = rawData
.replace(/\+/g, '%2B')
- .replace(/:/g, '%3A');
+ .replace(/:/g, '%3A')
+ .replaceAll('\r', '');
if (santizedRawData.startsWith('"')) {
santizedRawData = santizedRawData.substring(1);
}
From 3a3b1337b328e95c7dc8b1016b15a14beec1b770 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 22 Mar 2023 13:01:47 +0530
Subject: [PATCH 21/38] [ente auth] improve parsing of issuer from path
---
src/types/authenticator/code.ts | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/types/authenticator/code.ts b/src/types/authenticator/code.ts
index de32ad611..0e2ff8bba 100644
--- a/src/types/authenticator/code.ts
+++ b/src/types/authenticator/code.ts
@@ -121,8 +121,16 @@ export class Code {
}
return issuer;
}
- const path = decodeURIComponent(uriPath);
- return path.split(':')[0].substring(1);
+ let path = decodeURIComponent(uriPath);
+ if (path.startsWith('totp/') || path.startsWith('hotp/')) {
+ path = path.substring(5);
+ }
+ if (path.includes(':')) {
+ return path.split(':')[0];
+ } else if (path.includes('-')) {
+ return path.split('-')[0];
+ }
+ return path;
} catch (e) {
return '';
}
From 76710698cdb6c1eb229caed04f49ebd5f18f2baa Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 22 Mar 2023 13:10:52 +0530
Subject: [PATCH 22/38] [ente auth] Improve bad code display
---
src/components/Authenicator/OTPDisplay.tsx | 35 +++++++++++++---------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index bcaecb760..fd328041b 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -83,6 +83,26 @@ const TOTPDisplay = ({ issuer, account, code, nextCode }) => {
);
};
+function BadCodeInfo({ codeInfo, codeErr }) {
+ const [showRawData, setShowRawData] = useState(false);
+
+ return (
+
+ {codeInfo.title}
+ {codeErr}
+
+ {showRawData ? (
+ setShowRawData(false)}>
+ {codeInfo.rawData ?? 'no raw data'}
+
+ ) : (
+ setShowRawData(true)}>Show rawData
+ )}
+
+
+ );
+}
+
interface OTPDisplayProps {
codeInfo: Code;
}
@@ -119,7 +139,6 @@ const OTPDisplay = (props: OTPDisplayProps) => {
setNextCode(hotp.generate({ counter: 1 }));
}
} catch (err) {
- console.log('codeInfo', codeInfo);
setCodeErr(err.message);
}
};
@@ -152,19 +171,7 @@ const OTPDisplay = (props: OTPDisplayProps) => {
nextCode={nextcode}
/>
) : (
-
- {codeErr}
- {codeInfo.rawData ?? 'no rawdata'}
-
+
)}
);
From 6d9767db405d57f3f34871ce41a8a46e2e9aeb4d Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:14:08 +0530
Subject: [PATCH 23/38] Remove logging
---
src/pages/authenticator/index.tsx | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index f40cf5ef1..6471d2263 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -26,11 +26,10 @@ const OTPPage = () => {
});
return;
}
- console.error('something wrong here', err);
+ // do not log errors
});
} catch (error) {
- console.error('something wrong where asdas');
- console.error(error);
+ // do not log errors
}
};
fetchCodes();
From 4c190a319c22bf453f31be621eaa50aec79ccd01 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:21:37 +0530
Subject: [PATCH 24/38] Remove exception from log
---
src/services/authenticator/authenticatorService.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index cdf31f7ab..8ef3df69b 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -31,7 +31,10 @@ export const getAuthCodes = async (): Promise => {
try {
return Code.fromRawData(entity.id, decryptedCode);
} catch (e) {
- console.log('failed to parse code', e, entity.id);
+ logError(
+ Error('failed to parse code'),
+ 'codeId = ' + entity.id
+ );
return null;
}
})
From c6da52b1f56dd0ecf850e72b83b6325a38d1eadf Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:23:52 +0530
Subject: [PATCH 25/38] Switch to /auth instead of /authenticator
---
src/components/Sidebar/UtilitySection.tsx | 2 +-
src/constants/pages/index.ts | 3 ++-
src/pages/authenticator/index.tsx | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/components/Sidebar/UtilitySection.tsx b/src/components/Sidebar/UtilitySection.tsx
index fe1db3702..99c199107 100644
--- a/src/components/Sidebar/UtilitySection.tsx
+++ b/src/components/Sidebar/UtilitySection.tsx
@@ -63,7 +63,7 @@ export default function UtilitySection({ closeSidebar }) {
const redirectToDeduplicatePage = () => router.push(PAGES.DEDUPLICATE);
- const redirectToAuthenticatorPage = () => router.push(PAGES.AUTHENICATOR);
+ const redirectToAuthenticatorPage = () => router.push(PAGES.AUTH);
const somethingWentWrong = () =>
setDialogMessage({
diff --git a/src/constants/pages/index.ts b/src/constants/pages/index.ts
index 38f2b3a6a..10594aae6 100644
--- a/src/constants/pages/index.ts
+++ b/src/constants/pages/index.ts
@@ -14,5 +14,6 @@ export enum PAGES {
SHARED_ALBUMS = '/shared-albums',
// ML_DEBUG = '/ml-debug',
DEDUPLICATE = '/deduplicate',
- AUTHENICATOR = '/authenticator',
+ // AUTH page is used to show (auth)enticator codes
+ AUTH = '/auth',
}
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 6471d2263..13aed7dc5 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -22,7 +22,7 @@ const OTPPage = () => {
if (err.message === CustomError.KEY_MISSING) {
router.push({
pathname: PAGES.CREDENTIALS,
- query: { redirectPage: PAGES.AUTHENICATOR },
+ query: { redirectPage: PAGES.AUTH },
});
return;
}
From e63260b5ce4c2388a6e025ecd50779cf4a003c98 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:25:07 +0530
Subject: [PATCH 26/38] Fix typo
---
src/pages/credentials/index.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx
index e9422a8d8..7c0f2c651 100644
--- a/src/pages/credentials/index.tsx
+++ b/src/pages/credentials/index.tsx
@@ -31,7 +31,7 @@ import VerifyMasterPasswordForm, {
export default function Credentials() {
const router = useRouter();
- const routeReidrectPage =
+ const routerRedirectPage =
router.query.redirectPage?.toString() ?? PAGES.GALLERY;
const [keyAttributes, setKeyAttributes] = useState();
const appContext = useContext(AppContext);
@@ -88,7 +88,7 @@ export default function Credentials() {
await decryptAndStoreToken(key);
const redirectURL = appContext.redirectURL;
appContext.setRedirectURL(null);
- router.push(redirectURL ?? routeReidrectPage ?? PAGES.GALLERY);
+ router.push(redirectURL ?? routerRedirectPage ?? PAGES.GALLERY);
} catch (e) {
logError(e, 'useMasterPassword failed');
}
From dcaae1f4787fca75026a63689481662f53c25650 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:28:38 +0530
Subject: [PATCH 27/38] Refactor
---
src/pages/authenticator/index.tsx | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 13aed7dc5..567a98d6f 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -12,24 +12,20 @@ const OTPPage = () => {
const [searchTerm, setSearchTerm] = useState('');
useEffect(() => {
+ // refactor this code
const fetchCodes = async () => {
try {
- getAuthCodes()
- .then((res) => {
- setCodes(res);
- })
- .catch((err) => {
- if (err.message === CustomError.KEY_MISSING) {
- router.push({
- pathname: PAGES.CREDENTIALS,
- query: { redirectPage: PAGES.AUTH },
- });
- return;
- }
- // do not log errors
+ const res = await getAuthCodes();
+ setCodes(res);
+ } catch (err) {
+ if (err.message === CustomError.KEY_MISSING) {
+ router.push({
+ pathname: PAGES.CREDENTIALS,
+ query: { redirectPage: PAGES.AUTH },
});
- } catch (error) {
- // do not log errors
+ } else {
+ // do not log errors
+ }
}
};
fetchCodes();
From ac713bf9d6f0d6d4826eff7b5e5736c180453ee6 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:30:19 +0530
Subject: [PATCH 28/38] Fix typos
---
src/components/Authenicator/OTPDisplay.tsx | 4 ++--
src/services/authenticator/authenticatorService.ts | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index fd328041b..37415e644 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -110,7 +110,7 @@ interface OTPDisplayProps {
const OTPDisplay = (props: OTPDisplayProps) => {
const { codeInfo } = props;
const [code, setCode] = useState('');
- const [nextcode, setNextCode] = useState('');
+ const [nextCode, setNextCode] = useState('');
const [codeErr, setCodeErr] = useState('');
const generateCodes = () => {
@@ -168,7 +168,7 @@ const OTPDisplay = (props: OTPDisplayProps) => {
issuer={codeInfo.issuer}
account={codeInfo.account}
code={code}
- nextCode={nextcode}
+ nextCode={nextCode}
/>
) : (
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index 8ef3df69b..54f010683 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -12,7 +12,7 @@ export const getAuthCodes = async (): Promise => {
try {
const authKeyData = await getAuthKey();
const cryptoWorker = await ComlinkCryptoWorker.getInstance();
- const authentitorKey = await cryptoWorker.decryptB64(
+ const authenticatorKey = await cryptoWorker.decryptB64(
authKeyData.encryptedKey,
authKeyData.header,
masterKey
@@ -26,7 +26,7 @@ export const getAuthCodes = async (): Promise => {
const decryptedCode = await cryptoWorker.decryptMetadata(
entity.encryptedData,
entity.header,
- authentitorKey
+ authenticatorKey
);
try {
return Code.fromRawData(entity.id, decryptedCode);
From f8667bf692b08c53b9ce5cb52a3fe9887d257e39 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:35:44 +0530
Subject: [PATCH 29/38] Simplify if
---
src/components/Authenicator/OTPDisplay.tsx | 24 +++++++++++-----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index 37415e644..a6cf1e263 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -112,6 +112,7 @@ const OTPDisplay = (props: OTPDisplayProps) => {
const [code, setCode] = useState('');
const [nextCode, setNextCode] = useState('');
const [codeErr, setCodeErr] = useState('');
+ const generateCodeInterval = 1000;
const generateCodes = () => {
try {
@@ -145,19 +146,18 @@ const OTPDisplay = (props: OTPDisplayProps) => {
useEffect(() => {
generateCodes();
- let intervalId;
+ const codeType = codeInfo.type;
+ const intervalId =
+ codeType.toLowerCase() === 'totp' ||
+ codeType.toLowerCase() === 'hotp'
+ ? setInterval(() => {
+ generateCodes();
+ }, generateCodeInterval)
+ : null;
- if (codeInfo.type.toLowerCase() === 'totp') {
- intervalId = setInterval(() => {
- generateCodes();
- }, 1000);
- } else if (codeInfo.type.toLowerCase() === 'hotp') {
- intervalId = setInterval(() => {
- generateCodes();
- }, 1000);
- }
-
- return () => clearInterval(intervalId);
+ return () => {
+ if (intervalId) clearInterval(intervalId);
+ };
}, [codeInfo]);
return (
From 2069fff499b2c17672a2d9ebfdc1ff0374195888 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:38:54 +0530
Subject: [PATCH 30/38] Convert pure data class to interface
---
src/types/authenticator/auth_entity.ts | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/src/types/authenticator/auth_entity.ts b/src/types/authenticator/auth_entity.ts
index 083651d31..cd97f5262 100644
--- a/src/types/authenticator/auth_entity.ts
+++ b/src/types/authenticator/auth_entity.ts
@@ -1,23 +1,8 @@
-export class AuthEntity {
+export interface AuthEntity {
id: string;
encryptedData: string | null;
header: string | null;
isDeleted: boolean;
createdAt: number;
updatedAt: number;
- constructor(
- id: string,
- encryptedData: string | null,
- header: string | null,
- isDeleted: boolean,
- createdAt: number,
- updatedAt: number
- ) {
- this.id = id;
- this.encryptedData = encryptedData;
- this.header = header;
- this.isDeleted = isDeleted;
- this.createdAt = createdAt;
- this.updatedAt = updatedAt;
- }
}
From 5688c42d6e4dc9a4fd6ab5684fa296c09ef5a91c Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 07:43:32 +0530
Subject: [PATCH 31/38] Fix string extraction
---
public/locales/en/translation.json | 1 +
src/components/Sidebar/UtilitySection.tsx | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 906b3c264..879208e1c 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -459,6 +459,7 @@
"UPLOAD_GOOGLE_TAKEOUT": "Google takeout",
"CANCEL_UPLOADS": "Cancel uploads",
"DEDUPLICATE_FILES": "Deduplicate files",
+ "AUTHENTICATOR_SECTION": "Authenticator",
"NO_DUPLICATES_FOUND": "You've no duplicate files that can be cleared",
"CLUB_BY_CAPTURE_TIME": "Club by capture time",
"FILES": "Files",
diff --git a/src/components/Sidebar/UtilitySection.tsx b/src/components/Sidebar/UtilitySection.tsx
index 99c199107..a07c70a11 100644
--- a/src/components/Sidebar/UtilitySection.tsx
+++ b/src/components/Sidebar/UtilitySection.tsx
@@ -102,7 +102,7 @@ export default function UtilitySection({ closeSidebar }) {
{isInternalUser() && (
- {constants.AUTHENTICATOR_SECTION}
+ {t('AUTHENTICATOR_SECTION')}
)}
From c2451105e5bf8c3ca3da1a35f92538de6a908c19 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 08:07:19 +0530
Subject: [PATCH 32/38] Wrap decryption inside tryCatch
---
src/services/authenticator/authenticatorService.ts | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index 54f010683..b0ae58ef6 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -23,12 +23,13 @@ export const getAuthCodes = async (): Promise => {
authEntity
.filter((f) => !f.isDeleted)
.map(async (entity) => {
- const decryptedCode = await cryptoWorker.decryptMetadata(
- entity.encryptedData,
- entity.header,
- authenticatorKey
- );
try {
+ const decryptedCode =
+ await cryptoWorker.decryptMetadata(
+ entity.encryptedData,
+ entity.header,
+ authenticatorKey
+ );
return Code.fromRawData(entity.id, decryptedCode);
} catch (e) {
logError(
From 5e7411c405b775d9b60d27d497041a2d7df9c253 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 25 Mar 2023 08:52:01 +0530
Subject: [PATCH 33/38] Extract footer as component
---
src/components/Authenicator/AuthFooder.tsx | 25 +++++++++++++++++++
src/pages/authenticator/index.tsx | 29 ++--------------------
2 files changed, 27 insertions(+), 27 deletions(-)
create mode 100644 src/components/Authenicator/AuthFooder.tsx
diff --git a/src/components/Authenicator/AuthFooder.tsx b/src/components/Authenicator/AuthFooder.tsx
new file mode 100644
index 000000000..64eeb1029
--- /dev/null
+++ b/src/components/Authenicator/AuthFooder.tsx
@@ -0,0 +1,25 @@
+import { Button } from '@mui/material';
+
+export const AuthFooter = () => {
+ return (
+
+ Download our mobile app to add & manage your secrets.
+
+
+
+
+ );
+};
diff --git a/src/pages/authenticator/index.tsx b/src/pages/authenticator/index.tsx
index 567a98d6f..b61adf333 100644
--- a/src/pages/authenticator/index.tsx
+++ b/src/pages/authenticator/index.tsx
@@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react';
import OTPDisplay from 'components/Authenicator/OTPDisplay';
import { getAuthCodes } from 'services/authenticator/authenticatorService';
-import { Button } from '@mui/material';
import { CustomError } from 'utils/error';
import { PAGES } from 'constants/pages';
import { useRouter } from 'next/router';
+import { AuthFooter } from 'components/Authenicator/AuthFooder';
const OTPPage = () => {
const router = useRouter();
@@ -12,7 +12,6 @@ const OTPPage = () => {
const [searchTerm, setSearchTerm] = useState('');
useEffect(() => {
- // refactor this code
const fetchCodes = async () => {
try {
const res = await getAuthCodes();
@@ -41,30 +40,6 @@ const OTPPage = () => {
.includes(searchTerm.toLowerCase())
);
- const DownloadApp = () => {
- return (
-
- Download our mobile app to add & manage your secrets.
-
-
-
-
- );
- };
-
return (
{
))
)}
-
+
);
From 8c8a03db3d66f5714b942cca69e1a8d2d2600ff8 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 3 Apr 2023 11:02:55 +0530
Subject: [PATCH 34/38] refactor
---
src/services/authenticator/authenticatorService.ts | 4 ++--
src/types/authenticator/{auth_entity.ts => api.ts} | 5 +++++
2 files changed, 7 insertions(+), 2 deletions(-)
rename src/types/authenticator/{auth_entity.ts => api.ts} (70%)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index b0ae58ef6..9928f8b41 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -1,5 +1,5 @@
import HTTPService from 'services/HTTPService';
-import { AuthEntity } from 'types/authenticator/auth_entity';
+import { AuthEntity } from 'types/authenticator/api';
import { Code } from 'types/authenticator/code';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import { getEndpoint } from 'utils/common/apiUtil';
@@ -61,7 +61,7 @@ export const getAuthCodes = async (): Promise => {
}
};
-export const getAuthKey = async () => {
+export const getAuthKey = async (): Promise => {
try {
const resp = await HTTPService.get(
`${ENDPOINT}/authenticator/key`,
diff --git a/src/types/authenticator/auth_entity.ts b/src/types/authenticator/api.ts
similarity index 70%
rename from src/types/authenticator/auth_entity.ts
rename to src/types/authenticator/api.ts
index cd97f5262..569df8185 100644
--- a/src/types/authenticator/auth_entity.ts
+++ b/src/types/authenticator/api.ts
@@ -6,3 +6,8 @@ export interface AuthEntity {
createdAt: number;
updatedAt: number;
}
+
+export interface AuthKey {
+ encryptedKey: string;
+ header: string;
+}
From 349d9a3786d7e3edebec0c52efbcd352bdb54732 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 3 Apr 2023 11:06:28 +0530
Subject: [PATCH 35/38] refactor: rename
---
src/pages/{authenticator => auth}/index.tsx | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/pages/{authenticator => auth}/index.tsx (100%)
diff --git a/src/pages/authenticator/index.tsx b/src/pages/auth/index.tsx
similarity index 100%
rename from src/pages/authenticator/index.tsx
rename to src/pages/auth/index.tsx
From db95a096a0e4aaf5ffb3f10761610f460a6a426c Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 3 Apr 2023 11:08:53 +0530
Subject: [PATCH 36/38] Rename OtpPage -> AuthenticatorCodePages
---
src/pages/auth/index.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/auth/index.tsx b/src/pages/auth/index.tsx
index b61adf333..4a0c038a6 100644
--- a/src/pages/auth/index.tsx
+++ b/src/pages/auth/index.tsx
@@ -6,7 +6,7 @@ import { PAGES } from 'constants/pages';
import { useRouter } from 'next/router';
import { AuthFooter } from 'components/Authenicator/AuthFooder';
-const OTPPage = () => {
+const AuthenticatorCodesPage = () => {
const router = useRouter();
const [codes, setCodes] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
@@ -88,4 +88,4 @@ const OTPPage = () => {
);
};
-export default OTPPage;
+export default AuthenticatorCodesPage;
From b25d869d7f8caa603b1f0296dfce890d6bf002de Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 3 Apr 2023 11:16:26 +0530
Subject: [PATCH 37/38] Fix nextCode generation timing
---
src/components/Authenicator/OTPDisplay.tsx | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/components/Authenicator/OTPDisplay.tsx b/src/components/Authenicator/OTPDisplay.tsx
index a6cf1e263..d87d63d53 100644
--- a/src/components/Authenicator/OTPDisplay.tsx
+++ b/src/components/Authenicator/OTPDisplay.tsx
@@ -112,7 +112,6 @@ const OTPDisplay = (props: OTPDisplayProps) => {
const [code, setCode] = useState('');
const [nextCode, setNextCode] = useState('');
const [codeErr, setCodeErr] = useState('');
- const generateCodeInterval = 1000;
const generateCodes = () => {
try {
@@ -145,15 +144,26 @@ const OTPDisplay = (props: OTPDisplayProps) => {
};
useEffect(() => {
+ // this is to set the initial code and nextCode on component mount
generateCodes();
const codeType = codeInfo.type;
- const intervalId =
+ const codePeriodInMs = codeInfo.period * 1000;
+ const timeToNextCode =
+ codePeriodInMs - (new Date().getTime() % codePeriodInMs);
+ const intervalId = null;
+ // wait until we are at the start of the next code period,
+ // and then start the interval loop
+ setTimeout(() => {
+ // we need to call generateCodes() once before the interval loop
+ // to set the initial code and nextCode
+ generateCodes();
codeType.toLowerCase() === 'totp' ||
codeType.toLowerCase() === 'hotp'
? setInterval(() => {
generateCodes();
- }, generateCodeInterval)
+ }, codePeriodInMs)
: null;
+ }, timeToNextCode);
return () => {
if (intervalId) clearInterval(intervalId);
From f9b12ace969d5579e49c248db6d7af3245b34d35 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 3 Apr 2023 11:29:16 +0530
Subject: [PATCH 38/38] Fix lint error
---
src/services/authenticator/authenticatorService.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/services/authenticator/authenticatorService.ts b/src/services/authenticator/authenticatorService.ts
index 9928f8b41..afa07258e 100644
--- a/src/services/authenticator/authenticatorService.ts
+++ b/src/services/authenticator/authenticatorService.ts
@@ -1,5 +1,5 @@
import HTTPService from 'services/HTTPService';
-import { AuthEntity } from 'types/authenticator/api';
+import { AuthEntity, AuthKey } from 'types/authenticator/api';
import { Code } from 'types/authenticator/code';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import { getEndpoint } from 'utils/common/apiUtil';
@@ -61,7 +61,7 @@ export const getAuthCodes = async (): Promise => {
}
};
-export const getAuthKey = async (): Promise => {
+export const getAuthKey = async (): Promise => {
try {
const resp = await HTTPService.get(
`${ENDPOINT}/authenticator/key`,