Skip to content

Commit ffa8a07

Browse files
Add tests and cleanup for recovery with token
1 parent 465d7d2 commit ffa8a07

File tree

5 files changed

+136
-9
lines changed

5 files changed

+136
-9
lines changed

examples/for-tests-react-16/src/App.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ function getThirdPartyConfigs({ staticProviderList, disableDefaultUI, thirdParty
890890
});
891891
}
892892

893-
function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
893+
function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus, webauthnRecoverAccountErrorStatus }) {
894894
return Webauthn.init({
895895
style: `
896896
[data-supertokens~=container] {
@@ -1043,6 +1043,18 @@ function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
10431043

10441044
return implementation.generateRecoverAccountToken(...args);
10451045
},
1046+
recoverAccount(...args) {
1047+
log(`RECOVER ACCOUNT`);
1048+
1049+
// Return error status if the user passed that.
1050+
if (webauthnRecoverAccountErrorStatus) {
1051+
return {
1052+
status: webauthnRecoverAccountErrorStatus,
1053+
};
1054+
}
1055+
1056+
return implementation.recoverAccount(...args);
1057+
},
10461058
};
10471059
},
10481060
},

examples/for-tests-react-16/src/testContext.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function getTestContext() {
2626
localStorage.getItem("disableRedirectionAfterSuccessfulSignInUp") === "true",
2727
throwWebauthnError: localStorage.getItem("throwWebauthnError") === "true",
2828
webauthnErrorStatus: localStorage.getItem("webauthnErrorStatus") || undefined,
29+
webauthnRecoverAccountErrorStatus: localStorage.getItem("webauthnRecoverAccountErrorStatus") || undefined,
2930
};
3031
return ret;
3132
}

examples/for-tests/src/App.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ function setIsNewUserToStorage(recipeName, isNewRecipeUser) {
11521152
localStorage.setItem("isNewUserCheck", `${recipeName}-${isNewRecipeUser}`);
11531153
}
11541154

1155-
function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
1155+
function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus, webauthnRecoverAccountErrorStatus }) {
11561156
return Webauthn.init({
11571157
override: {
11581158
functions: (implementation) => {
@@ -1167,13 +1167,6 @@ function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
11671167
throw new STGeneralError("TEST ERROR");
11681168
}
11691169

1170-
// Return error status if the user passed that.
1171-
if (webauthnErrorStatus) {
1172-
return {
1173-
status: webauthnErrorStatus,
1174-
};
1175-
}
1176-
11771170
return implementation.getRegisterOptions(...args);
11781171
},
11791172
async getSignInOptions(...args) {
@@ -1312,6 +1305,18 @@ function getWebauthnConfigs({ throwWebauthnError, webauthnErrorStatus }) {
13121305

13131306
return implementation.generateRecoverAccountToken(...args);
13141307
},
1308+
recoverAccount(...args) {
1309+
log(`RECOVER ACCOUNT`);
1310+
1311+
// Return error status if the user passed that.
1312+
if (webauthnRecoverAccountErrorStatus) {
1313+
return {
1314+
status: webauthnRecoverAccountErrorStatus,
1315+
};
1316+
}
1317+
1318+
return implementation.recoverAccount(...args);
1319+
},
13151320
};
13161321
},
13171322
},

examples/for-tests/src/testContext.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export function getTestContext() {
2727
localStorage.getItem("disableRedirectionAfterSuccessfulSignInUp") === "true",
2828
throwWebauthnError: localStorage.getItem("throwWebauthnError") === "true",
2929
webauthnErrorStatus: localStorage.getItem("webauthnErrorStatus") || undefined,
30+
webauthnRecoverAccountErrorStatus: localStorage.getItem("webauthnRecoverAccountErrorStatus") || undefined,
3031
};
3132
return ret;
3233
}

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

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ describe("SuperTokens Webauthn Recover Account", () => {
158158
"ST_LOGS WEBAUTHN PRE_API_HOOKS REGISTER_OPTIONS",
159159
"ST_LOGS WEBAUTHN PRE_API_HOOKS REGISTER_OPTIONS",
160160
"ST_LOGS WEBAUTHN OVERRIDE REGISTER CREDENTIAL",
161+
"ST_LOGS WEBAUTHN OVERRIDE RECOVER ACCOUNT",
161162
"ST_LOGS WEBAUTHN PRE_API_HOOKS RECOVER_ACCOUNT",
162163
"ST_LOGS SUPERTOKENS GET_REDIRECTION_URL TO_AUTH",
163164
"ST_LOGS SESSION OVERRIDE ADD_FETCH_INTERCEPTORS_AND_RETURN_MODIFIED_FETCH",
@@ -227,5 +228,112 @@ describe("SuperTokens Webauthn Recover Account", () => {
227228
localStorage.setItem("throwWebauthnError", undefined);
228229
});
229230
});
231+
it("should show error when generated options are invalid", async () => {
232+
// Set the error to be thrown
233+
await page.evaluateOnNewDocument(() => {
234+
localStorage.setItem("webauthnRecoverAccountErrorStatus", "INVALID_GENERATED_OPTIONS_ERROR");
235+
});
236+
237+
// Use the token to recover the account
238+
// Get the token from the email
239+
const token = await getTokenFromEmail(email);
240+
assert.ok(token);
241+
assert.strictEqual(token.length, 128);
242+
await openRecoveryWithToken(page, token);
243+
244+
await submitForm(page);
245+
246+
const errorTextContainer = await waitForSTElement(
247+
page,
248+
"[data-supertokens~='passkeyRecoverableErrorContainer']"
249+
);
250+
const errorText = await errorTextContainer.evaluate((el) => el.textContent);
251+
assert.strictEqual(errorText, "Failed to recover account, please try again.");
252+
253+
await page.evaluateOnNewDocument(() => {
254+
localStorage.setItem("webauthnRecoverAccountErrorStatus", undefined);
255+
});
256+
});
257+
it("should show error when credentials are invalid", async () => {
258+
// Set the error to be thrown
259+
await page.evaluateOnNewDocument(() => {
260+
localStorage.setItem("webauthnRecoverAccountErrorStatus", "INVALID_CREDENTIALS_ERROR");
261+
});
262+
263+
// Use the token to recover the account
264+
// Get the token from the email
265+
const token = await getTokenFromEmail(email);
266+
assert.ok(token);
267+
assert.strictEqual(token.length, 128);
268+
await openRecoveryWithToken(page, token);
269+
270+
await submitForm(page);
271+
272+
const errorTextContainer = await waitForSTElement(
273+
page,
274+
"[data-supertokens~='passkeyRecoverableErrorContainer']"
275+
);
276+
const errorText = await errorTextContainer.evaluate((el) => el.textContent);
277+
assert.strictEqual(
278+
errorText,
279+
"The passkey is invalid, please try again, possibly with a different device."
280+
);
281+
282+
await page.evaluateOnNewDocument(() => {
283+
localStorage.setItem("webauthnRecoverAccountErrorStatus", undefined);
284+
});
285+
});
286+
it("should show error when generated options are not found", async () => {
287+
// Set the error to be thrown
288+
await page.evaluateOnNewDocument(() => {
289+
localStorage.setItem("webauthnRecoverAccountErrorStatus", "GENERATED_OPTIONS_NOT_FOUND_ERROR");
290+
});
291+
292+
// Use the token to recover the account
293+
// Get the token from the email
294+
const token = await getTokenFromEmail(email);
295+
assert.ok(token);
296+
assert.strictEqual(token.length, 128);
297+
await openRecoveryWithToken(page, token);
298+
299+
await submitForm(page);
300+
301+
const errorTextContainer = await waitForSTElement(
302+
page,
303+
"[data-supertokens~='passkeyRecoverableErrorContainer']"
304+
);
305+
const errorText = await errorTextContainer.evaluate((el) => el.textContent);
306+
assert.strictEqual(errorText, "Failed to recover account, please try again.");
307+
308+
await page.evaluateOnNewDocument(() => {
309+
localStorage.setItem("webauthnRecoverAccountErrorStatus", undefined);
310+
});
311+
});
312+
it("should show error when authenticator is invalid", async () => {
313+
// Set the error to be thrown
314+
await page.evaluateOnNewDocument(() => {
315+
localStorage.setItem("webauthnRecoverAccountErrorStatus", "INVALID_AUTHENTICATOR_ERROR");
316+
});
317+
318+
// Use the token to recover the account
319+
// Get the token from the email
320+
const token = await getTokenFromEmail(email);
321+
assert.ok(token);
322+
assert.strictEqual(token.length, 128);
323+
await openRecoveryWithToken(page, token);
324+
325+
await submitForm(page);
326+
327+
const errorTextContainer = await waitForSTElement(
328+
page,
329+
"[data-supertokens~='passkeyRecoverableErrorContainer']"
330+
);
331+
const errorText = await errorTextContainer.evaluate((el) => el.textContent);
332+
assert.strictEqual(errorText, "Invalid authenticator, please try again.");
333+
334+
await page.evaluateOnNewDocument(() => {
335+
localStorage.setItem("webauthnRecoverAccountErrorStatus", undefined);
336+
});
337+
});
230338
});
231339
});

0 commit comments

Comments
 (0)