Skip to content

Commit 7fd69c7

Browse files
authored
Merge pull request #1025 from supertokens/fix/webauthn-credential-register-missing-field
fix: Add required recipeUserId field in registerCredential API
2 parents ab1f7fd + 9fce668 commit 7fd69c7

File tree

7 files changed

+70
-0
lines changed

7 files changed

+70
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Updated FDI support to 4.2
1313
- Added `recipeUserId` in the WebAuthn list credentials response
14+
- Added `recipeUserId` as required field for registering new WebAuthn credentials endpoint
1415
- Fix WebAuthn credential listing and removal to work even when the WebAuthn user is not the primary user and when there are multiple WebAuthn users linked
1516
- Prevent removal of WebAuthn credentials unless all session claims are satisfied
1617
- Change how sessions are fetched before listing, removing and adding WebAuthn credentials

lib/build/recipe/webauthn/api/implementation.js

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/build/recipe/webauthn/api/registerCredential.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/build/recipe/webauthn/types.d.ts

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/ts/recipe/webauthn/api/implementation.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ export default function getAPIImplementation(): APIInterface {
10251025
},
10261026

10271027
registerCredentialPOST: async function ({
1028+
recipeUserId,
10281029
webauthnGeneratedOptionsId,
10291030
credential,
10301031
tenantId,
@@ -1050,6 +1051,24 @@ export default function getAPIImplementation(): APIInterface {
10501051
);
10511052
}
10521053

1054+
const user = await getUser(session.getUserId(), userContext);
1055+
if (!user) {
1056+
return {
1057+
status: "GENERAL_ERROR",
1058+
message: "User not found",
1059+
};
1060+
}
1061+
1062+
const loginMethod = user.loginMethods.find(
1063+
(lm) => lm.recipeId === "webauthn" && lm.recipeUserId.getAsString() === recipeUserId
1064+
);
1065+
if (!loginMethod) {
1066+
return {
1067+
status: "GENERAL_ERROR",
1068+
message: "User not found",
1069+
};
1070+
}
1071+
10531072
const generatedOptions = await options.recipeImplementation.getGeneratedOptions({
10541073
webauthnGeneratedOptionsId,
10551074
tenantId,
@@ -1060,6 +1079,12 @@ export default function getAPIImplementation(): APIInterface {
10601079
}
10611080

10621081
const email = generatedOptions.email;
1082+
if (email !== loginMethod.email) {
1083+
return {
1084+
status: "GENERAL_ERROR",
1085+
message: "Email mismatch",
1086+
};
1087+
}
10631088

10641089
// NOTE: Following checks will likely never throw an error as the
10651090
// check for type is done in a parent function but they are kept

lib/ts/recipe/webauthn/api/registerCredential.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { validateWebauthnGeneratedOptionsIdOrThrowError, validateCredentialOrThr
1818
import { APIInterface, APIOptions } from "..";
1919
import { UserContext } from "../../../types";
2020
import Session from "../../session";
21+
import STError from "../../../error";
2122

2223
export default async function registerCredentialAPI(
2324
apiImplementation: APIInterface,
@@ -42,7 +43,16 @@ export default async function registerCredentialAPI(
4243
);
4344
const credential = validateCredentialOrThrowError(requestBody.credential);
4445

46+
const recipeUserId = requestBody.recipeUserId;
47+
if (recipeUserId === undefined) {
48+
throw new STError({
49+
type: STError.BAD_INPUT_ERROR,
50+
message: "Please provide the recipeUserId",
51+
});
52+
}
53+
4554
const result = await apiImplementation.registerCredentialPOST({
55+
recipeUserId,
4656
credential,
4757
webauthnGeneratedOptionsId,
4858
tenantId,

lib/ts/recipe/webauthn/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ export type APIInterface = {
630630
session: SessionContainerInterface;
631631
options: APIOptions;
632632
userContext: UserContext;
633+
recipeUserId: string;
633634
}) => Promise<
634635
| {
635636
status: "OK";

0 commit comments

Comments
 (0)