Skip to content

Commit

Permalink
Add support for registering and recovering account in recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
deepjyoti30-st committed Dec 11, 2024
1 parent 0b7d1d4 commit 41da8ab
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
5 changes: 3 additions & 2 deletions lib/ts/recipe/webauthn/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* under the License.
*/

import { AuthenticationResponseJSON, RegistrationResponseJSON } from "@simplewebauthn/browser";
import { GeneralErrorResponse, User } from "../../types";
import { getNormalisedUserContext } from "../../utils";
import { RecipeFunctionOptions } from "../recipeModule/types";
Expand Down Expand Up @@ -144,7 +145,7 @@ export default class RecipeWrapper {
*/
static signUp(input: {
webauthnGeneratedOptionsId: string;
credential: CredentialPayload;
credential: RegistrationResponseJSON;
options?: RecipeFunctionOptions;
userContext: any;
}): Promise<
Expand Down Expand Up @@ -184,7 +185,7 @@ export default class RecipeWrapper {
*/
static signIn(input: {
webauthnGeneratedOptionsId: string;
credential: CredentialPayload;
credential: AuthenticationResponseJSON;
options?: RecipeFunctionOptions;
userContext: any;
}): Promise<
Expand Down
37 changes: 37 additions & 0 deletions lib/ts/recipe/webauthn/recipeImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,43 @@ export default function getRecipeImplementation(
userContext: userContext,
});
},
registerAndRecoverAccount: async function ({ recoverAccountToken, options, userContext }) {
// Get the registration options based on the recoverAccountToken and
// register the device against the user.
const registrationOptions = await this.registerOptions({ options, userContext, recoverAccountToken });
if (registrationOptions?.status !== "OK") {
// If we did not get an OK status, we need to return the error as is.

// If the `status` is `INVALID_EMAIL_ERROR`, we need to throw an
// error since that should never happen as we are registering with a recover account token
// and not an email ID.
if (registrationOptions?.status === "INVALID_EMAIL_ERROR") {
throw new Error("Got `INVALID_EMAIL_ERROR` status that should never happen");
}

return registrationOptions;
}

// We should have received a valid registration options response.
let registrationResponse: RegistrationResponseJSON;
try {
registrationResponse = await startRegistration({ optionsJSON: registrationOptions });
} catch (error: any) {
if (error.name === "InvalidStateError") {
return { status: "AUTHENTICATOR_ALREADY_REGISTERED" };
}

throw error;
}

return await this.recoverAccount({
token: recoverAccountToken,
webauthnGeneratedOptionsId: registrationOptions.webauthnGeneratedOptionsId,
credential: registrationResponse,
options,
userContext,
});
},
};
}

Expand Down
3 changes: 2 additions & 1 deletion lib/ts/recipe/webauthn/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export type RecipeInterface = {
recoverAccount: (input: {
token: string;
webauthnGeneratedOptionsId: string;
credential: CredentialPayload;
credential: RegistrationResponseJSON;
options?: RecipeFunctionOptions;
userContext: any;
}) => Promise<
Expand Down Expand Up @@ -296,5 +296,6 @@ export type RecipeInterface = {
| { status: "GENERATED_OPTIONS_NOT_FOUND_ERROR"; fetchResponse: Response }
| { status: "INVALID_GENERATED_OPTIONS_ERROR"; fetchResponse: Response }
| { status: "INVALID_AUTHENTICATOR_ERROR"; reason: string; fetchResponse: Response }
| { status: "AUTHENTICATOR_ALREADY_REGISTERED" }
>;
};

0 comments on commit 41da8ab

Please sign in to comment.