Skip to content

Commit

Permalink
updated registerOptions to use the core to get the user email when us…
Browse files Browse the repository at this point in the history
…ing a recover token
  • Loading branch information
niftyvictor committed Feb 5, 2025
1 parent 11f52c0 commit 88377de
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 60 deletions.
70 changes: 20 additions & 50 deletions lib/build/recipe/webauthn/recipeImplementation.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,4 @@
"use strict";
var __createBinding =
(this && this.__createBinding) ||
(Object.create
? function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, {
enumerable: true,
get: function () {
return m[k];
},
});
}
: function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
});
var __setModuleDefault =
(this && this.__setModuleDefault) ||
(Object.create
? function (o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}
: function (o, v) {
o["default"] = v;
});
var __importStar =
(this && this.__importStar) ||
function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __rest =
(this && this.__rest) ||
function (s, e) {
Expand All @@ -59,11 +23,11 @@ const recipeUserId_1 = __importDefault(require("../../recipeUserId"));
const constants_1 = require("../multitenancy/constants");
const user_1 = require("../../user");
const authUtils_1 = require("../../authUtils");
const jose = __importStar(require("jose"));
const utils_1 = require("../thirdparty/utils");
function getRecipeInterface(querier, getWebauthnConfig) {
return {
registerOptions: async function (_a) {
var _b;
var {
relyingPartyId,
relyingPartyName,
Expand Down Expand Up @@ -94,17 +58,25 @@ function getRecipeInterface(querier, getWebauthnConfig) {
if (emailInput !== undefined) {
email = emailInput;
} else if (recoverAccountTokenInput !== undefined) {
// the actual validation of the token will be done during consumeRecoverAccountToken
let decoded;
try {
decoded = await jose.decodeJwt(recoverAccountTokenInput);
} catch (e) {
console.error(e);
const result = await this.getUserFromRecoverAccountToken({
token: recoverAccountTokenInput,
tenantId,
userContext,
});
if (result.status !== "OK") {
return result;
}
const user = result.user;
// todo this might be wrong but will have to figure out - what happens when there are multiple webauthn login methods ?
const email =
(_b = user.loginMethods.find((lm) => lm.recipeId === "webauthn")) === null || _b === void 0
? void 0
: _b.email;
if (!email) {
return {
status: "RECOVER_ACCOUNT_TOKEN_INVALID_ERROR",
};
}
email = decoded === null || decoded === void 0 ? void 0 : decoded.email;
}
if (!email) {
return {
Expand Down Expand Up @@ -364,19 +336,17 @@ function getRecipeInterface(querier, getWebauthnConfig) {
new normalisedURLPath_1.default(
`/${
tenantId === undefined ? constants_1.DEFAULT_TENANT_ID : tenantId
}/recipe/webauthn/user/recover/token/${token}`
}/recipe/webauthn/user/recover/token`
),
{},
{ token },
userContext
);
},
removeCredential: async function ({ webauthnCredentialId, recipeUserId, userContext }) {
return await querier.sendDeleteRequest(
new normalisedURLPath_1.default(
`/recipe/webauthn/user/${recipeUserId}/credential/${webauthnCredentialId}`
),
{},
new normalisedURLPath_1.default(`/recipe/webauthn/user/credential/remove`),
{},
{ recipeUserId, webauthnCredentialId },
userContext
);
},
Expand Down
2 changes: 1 addition & 1 deletion lib/build/recipe/webauthn/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ export declare type RecipeInterface = {
}): Promise<{
status: "OK";
credentials: {
id: string;
webauthnCredentialId: string;
relyingPartyId: string;
createdAt: number;
}[];
Expand Down
21 changes: 12 additions & 9 deletions lib/ts/recipe/webauthn/recipeImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import RecipeUserId from "../../recipeUserId";
import { DEFAULT_TENANT_ID } from "../multitenancy/constants";
import { LoginMethod, User } from "../../user";
import { AuthUtils } from "../../authUtils";
import * as jose from "jose";
import { isFakeEmail } from "../thirdparty/utils";

export default function getRecipeInterface(
Expand Down Expand Up @@ -35,19 +34,23 @@ export default function getRecipeInterface(
if (emailInput !== undefined) {
email = emailInput;
} else if (recoverAccountTokenInput !== undefined) {
// the actual validation of the token will be done during consumeRecoverAccountToken
let decoded: jose.JWTPayload | undefined;
try {
decoded = await jose.decodeJwt(recoverAccountTokenInput);
} catch (e) {
console.error(e);
const result = await this.getUserFromRecoverAccountToken({
token: recoverAccountTokenInput,
tenantId,
userContext,
});
if (result.status !== "OK") {
return result;
}

const user = result.user as User;
// todo this might be wrong but will have to figure out - what happens when there are multiple webauthn login methods ?
const email = user.loginMethods.find((lm) => lm.recipeId === "webauthn")?.email;
if (!email) {
return {
status: "RECOVER_ACCOUNT_TOKEN_INVALID_ERROR",
};
}

email = decoded?.email as string | undefined;
}

if (!email) {
Expand Down

0 comments on commit 88377de

Please sign in to comment.