Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions packages/functional-tests/lib/pairing-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,26 +612,47 @@ export async function setInputValueByScript(
* Returns the hex-encoded secret for later code generation.
*/
export async function enableTotpOnAccount(
authClient: {
createTotpToken: (
sessionToken: string,
options: object
) => Promise<{ secret: string }>;
verifyTotpSetupCode: (
sessionToken: string,
code: string
) => Promise<{ success: boolean }>;
completeTotpSetup: (
sessionToken: string,
options?: object
) => Promise<{ success: boolean }>;
target: {
authClient: {
mfaRequestOtp: (
sessionToken: string,
action: string
) => Promise<{ status: string }>;
mfaOtpVerify: (
sessionToken: string,
code: string,
action: string
) => Promise<{ accessToken: string }>;
createTotpTokenWithJwt: (
jwt: string,
options: object
) => Promise<{ secret: string }>;
verifyTotpSetupCodeWithJwt: (
jwt: string,
code: string,
options?: object
) => Promise<{ success: boolean }>;
completeTotpSetupWithJwt: (
jwt: string,
options?: object
) => Promise<{ success: boolean }>;
};
emailClient: {
getVerifyAccountChangeCode: (email: string) => Promise<string>;
};
},
sessionToken: string
sessionToken: string,
email: string
): Promise<string> {
const { secret } = await authClient.createTotpToken(sessionToken, {});
const { authClient, emailClient } = target;
await authClient.mfaRequestOtp(sessionToken, '2fa');
const otp = await emailClient.getVerifyAccountChangeCode(email);
const { accessToken } = await authClient.mfaOtpVerify(sessionToken, otp, '2fa');

const { secret } = await authClient.createTotpTokenWithJwt(accessToken, {});
const code = await getTotpCode(secret);
await authClient.verifyTotpSetupCode(sessionToken, code);
await authClient.completeTotpSetup(sessionToken);
await authClient.verifyTotpSetupCodeWithJwt(accessToken, code);
await authClient.completeTotpSetupWithJwt(accessToken);
return secret;
}

Expand Down
5 changes: 3 additions & 2 deletions packages/functional-tests/tests/cms/cms-2fa.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ test.describe('severity-1 #smoke', () => {
// Enroll TOTP out-of-band so one sign-in hits signin_totp_code (a second
// /pair can't re-sign-in: the signed-in browser shows pairing).
const secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);
// Record the secret so account cleanup can elevate AAL to delete it.
credentials.secret = secret;
Expand Down
5 changes: 3 additions & 2 deletions packages/functional-tests/tests/pairing/pairingFlow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ test.describe('severity-2 #smoke', () => {
await test.step('Create test account with TOTP', async () => {
const creds = await testAccountTracker.signUp();
const totpSecret = await enableTotpOnAccount(
target.authClient,
creds.sessionToken
target,
creds.sessionToken,
creds.email
);
creds.secret = totpSecret;
return { credentials: creds, secret: totpSecret };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ test.describe('severity-2 #smoke', () => {
await test.step('Create test account with TOTP', async () => {
const creds = await testAccountTracker.signUp();
const totpSecret = await enableTotpOnAccount(
target.authClient,
creds.sessionToken
target,
creds.sessionToken,
creds.email
);
creds.secret = totpSecret;
return { credentials: creds, secret: totpSecret };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ test.describe('severity-1 #smoke', () => {
testAccountTracker,
});
credentials.secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);
await settings.signOut();

Expand Down Expand Up @@ -201,8 +202,9 @@ test.describe('severity-1 #smoke', () => {
testAccountTracker,
});
credentials.secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);
await settings.signOut();

Expand Down Expand Up @@ -408,8 +410,9 @@ test.describe('severity-1 #smoke', () => {
testAccountTracker,
});
credentials.secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);
await settings.signOut();

Expand Down Expand Up @@ -548,8 +551,9 @@ test.describe('severity-1 #smoke', () => {
testAccountTracker,
});
credentials.secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);
await settings.signOut();
await signInWithRegisteredPasskey({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ test.describe('severity-1 #smoke', () => {
});
const { email, password } = credentials;
credentials.secret = await enableTotpOnAccount(
target.authClient,
credentials.sessionToken
target,
credentials.sessionToken,
credentials.email
);

await settings.signOut();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ test.describe('severity-1 #smoke', () => {
await testAccountTracker.signUpPasswordless();

// Enrol TOTP and mirror onto the tracker so cleanup can elevate AAL.
const secret = await enableTotpOnAccount(target.authClient, sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);
const account = findPasswordlessAccount(testAccountTracker, email);
account.secret = secret;
account.sessionToken = sessionToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { expect, test } from '../../lib/fixtures/standard';
import { getTotpCode } from '../../lib/totp';
import { enableTotpOnAccount } from '../../lib/pairing-helpers';

const SUPPORTED_SERVICE = 'smoketests';

Expand Down Expand Up @@ -264,13 +265,7 @@ test.describe('severity-2', () => {
);
const password = account?.password || '';

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

if (account) {
account.secret = secret;
Expand Down Expand Up @@ -425,13 +420,7 @@ test.describe('severity-2', () => {
);
const password = account?.password || '';

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

if (account) {
account.secret = secret;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
syncDesktopOAuthQueryParams,
} from '../../lib/query-params';
import { getTotpCode } from '../../lib/totp';
import { enableTotpOnAccount } from '../../lib/pairing-helpers';

test.describe('severity-1 #smoke', () => {
test.describe('Passwordless authentication', () => {
Expand Down Expand Up @@ -155,13 +156,7 @@ test.describe('severity-1 #smoke', () => {
);
const password = account?.password || '';

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

if (account) {
account.secret = secret;
Expand Down Expand Up @@ -267,13 +262,7 @@ test.describe('severity-1 #smoke', () => {
);
const password = account?.password || '';

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

account.secret = secret;
account.sessionToken = sessionToken;
Expand Down Expand Up @@ -722,16 +711,7 @@ test.describe('severity-1 #smoke', () => {
);
const password = account?.password || '';

// Set up TOTP via API using the passwordless session token
const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);

// Verify TOTP setup with a generated code
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

// Store secret and sessionToken in account for cleanup
if (account) {
Expand Down Expand Up @@ -1244,13 +1224,7 @@ test.describe('severity-2', () => {
);
const password = account?.password || '';

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

if (account) {
account.secret = secret;
Expand Down Expand Up @@ -1378,13 +1352,7 @@ test.describe('severity-2', () => {
}
const password = account.password;

const { secret } = await target.authClient.createTotpToken(
sessionToken,
{}
);
const totpCode = await getTotpCode(secret);
await target.authClient.verifyTotpSetupCode(sessionToken, totpCode);
await target.authClient.completeTotpSetup(sessionToken);
const secret = await enableTotpOnAccount(target, sessionToken, email);

if (account) {
account.secret = secret;
Expand Down
Loading