Skip to content

Commit 706a671

Browse files
Add support for testing sending recovery token properly
1 parent 4fde11d commit 706a671

File tree

5 files changed

+81
-8
lines changed

5 files changed

+81
-8
lines changed

examples/for-tests/src/App.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,9 +1298,7 @@ function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
12981298
};
12991299
}
13001300

1301-
return {
1302-
status: "OK",
1303-
};
1301+
return implementation.generateRecoverAccountToken(...args);
13041302
},
13051303
};
13061304
},

stories/allrecipes.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export const RecoverAccountWithToken: Story = {
138138
"multifactorauth.initialized": false,
139139
"passwordless.initialized": false,
140140
"webauthn.initialized": true,
141-
query: "token=MmEyYjVhYjdiMjA2OTc1NjMwYzM0ZGU5NDliNjhlZTQxYjQ5ZDlkMTQ5YjlhYTc5YmM1N2UxM2U0NzU4ODJmYzMzNTY0MTcyYjE1ZGYxMTMxZjg2YTUzNzNiMDkzZTU2",
141+
query: "token=NThlNDNmMjU4OWRjNDJkYzVmMzhmZDMzMWFkY2YxOTUyYjQ5M2Y2NmNhYjY4MjdmMjJjNTFmMTk0Yzg0MTFkYWUyMTZmNDFlNjFlZWE4MTQ5NWY4ZTMyZWE4OTI1OWUz&tenantId=public",
142142
},
143143
};
144144

test/end-to-end/webauthn.helpers.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TEST_CLIENT_BASE_URL } from "../constants";
1+
import { TEST_CLIENT_BASE_URL, TEST_SERVER_BASE_URL } from "../constants";
22
import { toggleSignInSignUp, setInputValues, submitForm, waitForSTElement } from "../helpers";
33

44
export async function tryWebauthnSignUp(page, email) {
@@ -45,3 +45,29 @@ export async function openRecoveryAccountPage(page, email = null, shouldSubmit =
4545
await submitForm(page);
4646
await new Promise((res) => setTimeout(res, 1000));
4747
}
48+
49+
export async function signUpAndSendRecoveryEmail(page, email) {
50+
await tryWebauthnSignUp(page, email);
51+
52+
// We should be in the confirmation page now.
53+
await submitForm(page);
54+
await new Promise((res) => setTimeout(res, 2000));
55+
56+
// Find the div with classname logoutButton and click it using normal
57+
// puppeteer selector
58+
const logoutButton = await page.waitForSelector("div.logoutButton");
59+
await logoutButton.click();
60+
await new Promise((res) => setTimeout(res, 1000));
61+
62+
// Click the send recovery email button
63+
await openRecoveryAccountPage(page, email, true);
64+
}
65+
66+
export async function getTokenFromEmail(page, email) {
67+
// Make an API call to get the token from the email
68+
// Since the email can contain special characters, we need to encode it
69+
const encodedEmail = encodeURIComponent(email);
70+
const response = await fetch(`${TEST_SERVER_BASE_URL}/test/webauthn/get-token?email=${encodedEmail}`);
71+
const data = await response.json();
72+
return data.token;
73+
}

test/end-to-end/webauthn.recovery_email.test.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
waitForSTElement,
1010
getTestEmail,
1111
} from "../helpers";
12-
import { tryWebauthnSignIn, openRecoveryAccountPage } from "./webauthn.helpers";
12+
import { openRecoveryAccountPage, signUpAndSendRecoveryEmail, getTokenFromEmail } from "./webauthn.helpers";
1313
import assert from "assert";
1414

1515
describe("SuperTokens Webauthn Recovery Email", () => {
@@ -58,7 +58,7 @@ describe("SuperTokens Webauthn Recovery Email", () => {
5858
describe("Recovery Email Test", () => {
5959
it("should show the success page when the email is sent", async () => {
6060
const email = await getTestEmail();
61-
await openRecoveryAccountPage(page, email, true);
61+
await signUpAndSendRecoveryEmail(page, email);
6262
await new Promise((res) => setTimeout(res, 1000));
6363

6464
// It should be successful and the user should see the success page
@@ -67,11 +67,32 @@ describe("SuperTokens Webauthn Recovery Email", () => {
6767
assert.strictEqual(emailSentText, "Email sent");
6868

6969
assert.deepStrictEqual(consoleLogs, [
70+
"ST_LOGS SESSION OVERRIDE ADD_FETCH_INTERCEPTORS_AND_RETURN_MODIFIED_FETCH",
71+
"ST_LOGS SESSION OVERRIDE ADD_AXIOS_INTERCEPTORS",
72+
"ST_LOGS WEBAUTHN OVERRIDE GET REGISTER OPTIONS WITH SIGN UP",
73+
"ST_LOGS WEBAUTHN OVERRIDE GET REGISTER OPTIONS",
74+
"ST_LOGS WEBAUTHN PRE_API_HOOKS REGISTER_OPTIONS",
75+
"ST_LOGS WEBAUTHN OVERRIDE REGISTER CREDENTIAL",
76+
"ST_LOGS WEBAUTHN OVERRIDE SIGN UP",
77+
"ST_LOGS WEBAUTHN PRE_API_HOOKS SIGN_UP",
78+
"ST_LOGS SESSION ON_HANDLE_EVENT SESSION_CREATED",
79+
"ST_LOGS SESSION OVERRIDE GET_USER_ID",
80+
"ST_LOGS SUPERTOKENS GET_REDIRECTION_URL SUCCESS undefined",
81+
"ST_LOGS SESSION OVERRIDE GET_USER_ID",
82+
"ST_LOGS SESSION OVERRIDE SIGN_OUT",
83+
"ST_LOGS SESSION PRE_API_HOOKS SIGN_OUT",
84+
"ST_LOGS SESSION ON_HANDLE_EVENT SIGN_OUT",
7085
"ST_LOGS SESSION OVERRIDE ADD_FETCH_INTERCEPTORS_AND_RETURN_MODIFIED_FETCH",
7186
"ST_LOGS SESSION OVERRIDE ADD_AXIOS_INTERCEPTORS",
7287
"ST_LOGS WEBAUTHN GET_REDIRECTION_URL SEND_RECOVERY_EMAIL",
7388
"ST_LOGS WEBAUTHN OVERRIDE GENERATE RECOVER ACCOUNT TOKEN",
89+
"ST_LOGS WEBAUTHN PRE_API_HOOKS GENERATE_RECOVER_ACCOUNT_TOKEN",
7490
]);
91+
92+
// Verify that the email is sent by fetching the token through the API
93+
const token = await getTokenFromEmail(page, email);
94+
assert.ok(token);
95+
assert.strictEqual(token.length, 128);
7596
});
7697
it("change email button should take the user back to the recovery view", async () => {
7798
const email = await getTestEmail();
@@ -87,6 +108,7 @@ describe("SuperTokens Webauthn Recovery Email", () => {
87108
"ST_LOGS SESSION OVERRIDE ADD_AXIOS_INTERCEPTORS",
88109
"ST_LOGS WEBAUTHN GET_REDIRECTION_URL SEND_RECOVERY_EMAIL",
89110
"ST_LOGS WEBAUTHN OVERRIDE GENERATE RECOVER ACCOUNT TOKEN",
111+
"ST_LOGS WEBAUTHN PRE_API_HOOKS GENERATE_RECOVER_ACCOUNT_TOKEN",
90112
]);
91113
const headerTextContainer = await waitForSTElement(
92114
page,

test/server/index.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,23 @@ function saveCode({ email, phoneNumber, preAuthSessionId, urlWithLinkCode, userI
174174
});
175175
deviceStore.set(preAuthSessionId, device);
176176
}
177+
178+
let webauthnStore = new Map();
179+
const saveWebauthnToken = async ({ user, recoverAccountLink }) => {
180+
const webauthn = webauthnStore.get(user.email) || {
181+
email: user.email,
182+
recoverAccountLink: "",
183+
token: "",
184+
};
185+
webauthn.recoverAccountLink = recoverAccountLink;
186+
187+
// Parse the token from the recoverAccountLink
188+
const token = recoverAccountLink.split("token=")[1].replace("&tenantId=public", "");
189+
webauthn.token = token;
190+
191+
webauthnStore.set(user.email, webauthn);
192+
};
193+
177194
const formFields = (process.env.MIN_FIELDS && []) || [
178195
{
179196
id: "name",
@@ -523,6 +540,15 @@ app.post("/test/create-oauth2-client", async (req, res, next) => {
523540
}
524541
});
525542

543+
app.get("/test/webauthn/get-token", async (req, res) => {
544+
const webauthn = webauthnStore.get(req.query.email);
545+
if (!webauthn) {
546+
res.status(404).send({ error: "Webauthn not found" });
547+
return;
548+
}
549+
res.send({ token: webauthn.token });
550+
});
551+
526552
app.post("/test/webauthn/create-and-assert-credential", async (req, res) => {
527553
try {
528554
const { registerOptionsResponse, signInOptionsResponse, rpId, rpName, origin } = req.body;
@@ -753,7 +779,7 @@ function initST() {
753779
return {
754780
...oI,
755781
sendEmail: async (input) => {
756-
console.log(input);
782+
await saveWebauthnToken(input);
757783
},
758784
};
759785
},
@@ -1006,6 +1032,7 @@ function initST() {
10061032
supertokens: {
10071033
connectionURI,
10081034
},
1035+
debug: true,
10091036
recipeList:
10101037
enabledRecipes !== undefined
10111038
? recipeList.filter(([key]) => enabledRecipes.includes(key)).map(([_key, recipeFunc]) => recipeFunc)

0 commit comments

Comments
 (0)