0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(core): add time window validation tolerance for otp authenticator (#4684)

This commit is contained in:
Xiao Yijun 2023-10-18 11:56:01 +08:00 committed by GitHub
parent 248448d13a
commit 8c0b55ab06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 23 deletions

View file

@ -1,6 +1,17 @@
import { authenticator } from 'otplib';
/**
* Note:
* Considering T1 and T2 two consecutive time steps,
* any token generated within T1 but checked with T2 could be considered valid according to [RFC 6238 5.2](https://datatracker.ietf.org/doc/html/rfc6238#section-5.2).
*
* FYI: https://github.com/yeojz/otplib/issues/697#issuecomment-1655749578
*/
// eslint-disable-next-line @silverhand/fp/no-mutation
authenticator.options = { window: 1 };
export const generateTotpSecret = () => authenticator.generateSecret();
export const validateTotpToken = (secret: string, token: string) =>
authenticator.check(token, secret);
export const validateTotpToken = (secret: string, token: string) => {
return authenticator.check(token, secret);
};

View file

@ -1,6 +1,5 @@
import { authenticator } from 'otplib';
import { demoAppUrl } from '#src/constants.js';
import { waitFor, dcls } from '#src/utils.js';
import ExpectExperience from './expect-experience.js';
@ -35,10 +34,7 @@ export default class ExpectTotpExperience extends ExpectExperience {
const code = authenticator.generate(secret);
for (const [index, char] of code.split('').entries()) {
// eslint-disable-next-line no-await-in-loop
await this.toFillInput(`totpCode_${index}`, char);
}
await this.fillTotpCode(code);
// Wait for the form to commit automatically
await waitFor(500);
@ -64,10 +60,7 @@ export default class ExpectTotpExperience extends ExpectExperience {
const code = authenticator.generate(secret);
for (const [index, char] of code.split('').entries()) {
// eslint-disable-next-line no-await-in-loop
await this.toFillInput(`totpCode_${index}`, char);
}
await this.fillTotpCode(code);
// Wait for the form to commit automatically
await waitFor(500);
@ -76,17 +69,10 @@ export default class ExpectTotpExperience extends ExpectExperience {
}
}
/**
* Assert the page is at the demo app page and get the user ID from the page.
* @returns The user ID.
*/
async getUserIdFromDemoAppPage() {
this.toMatchUrl(demoAppUrl);
const userIdDiv = await expect(this.page).toMatchElement([dcls('infoCard'), 'div'].join(' '), {
text: 'User ID: ',
});
const userIdSpan = await expect(userIdDiv).toMatchElement('span');
return (await userIdSpan.evaluate((element) => element.textContent)) ?? '';
private async fillTotpCode(code: string) {
for (const [index, char] of code.split('').entries()) {
// eslint-disable-next-line no-await-in-loop
await this.toFillInput(`totpCode_${index}`, char);
}
}
}