Skip to content

Commit 79837a8

Browse files
committed
feat(core): update webauthn passkey name
1 parent 9f7f1b9 commit 79837a8

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

packages/core/src/routes/account/index.openapi.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,40 @@
286286
},
287287
"type": {
288288
"description": "The type of the MFA verification."
289+
},
290+
"name": {
291+
"description": "The name of the MFA verification, if not provided, the name will be generated from user agent."
292+
}
293+
}
294+
}
295+
}
296+
}
297+
}
298+
}
299+
},
300+
"/api/my-account/mfa-verifications/{id}/name": {
301+
"patch": {
302+
"tags": ["Dev feature"],
303+
"operationId": "UpdateMfaVerificationName",
304+
"summary": "Update a MFA verification name",
305+
"description": "Update a MFA verification name, a logto-verification-id in header is required for checking sensitive permissions. Only WebAuthn is supported for now.",
306+
"requestBody": {
307+
"content": {
308+
"application/json": {
309+
"schema": {
310+
"properties": {
311+
"name": {
312+
"description": "The name of the MFA verification."
289313
}
290314
}
291315
}
292316
}
293317
}
318+
},
319+
"responses": {
320+
"200": {
321+
"description": "The MFA verification name was updated successfully."
322+
}
294323
}
295324
}
296325
}

packages/core/src/routes/account/mfa-verifications.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default function mfaVerificationsRoutes<T extends UserRouter>(
2626
body: z.object({
2727
type: z.literal(MfaFactor.WebAuthn),
2828
newIdentifierVerificationRecordId: z.string(),
29+
name: z.string().optional(),
2930
}),
3031
status: [204, 400, 401],
3132
}),
@@ -35,7 +36,7 @@ export default function mfaVerificationsRoutes<T extends UserRouter>(
3536
identityVerified,
3637
new RequestError({ code: 'verification_record.permission_denied', status: 401 })
3738
);
38-
const { newIdentifierVerificationRecordId } = ctx.guard.body;
39+
const { newIdentifierVerificationRecordId, name } = ctx.guard.body;
3940
const { fields } = ctx.accountCenter;
4041
assertThat(
4142
fields.mfa === AccountCenterControlValue.Edit,
@@ -71,6 +72,7 @@ export default function mfaVerificationsRoutes<T extends UserRouter>(
7172
...bindMfa,
7273
id: generateStandardId(),
7374
createdAt: new Date().toISOString(),
75+
name,
7476
},
7577
],
7678
});
@@ -82,4 +84,54 @@ export default function mfaVerificationsRoutes<T extends UserRouter>(
8284
return next();
8385
}
8486
);
87+
88+
// Update mfa verification name, only support webauthn
89+
router.patch(
90+
`${accountApiPrefix}/mfa-verifications/:id/name`,
91+
koaGuard({
92+
params: z.object({
93+
id: z.string(),
94+
}),
95+
body: z.object({
96+
name: z.string(),
97+
}),
98+
status: [200, 400, 401],
99+
}),
100+
async (ctx, next) => {
101+
const { id: userId, scopes, identityVerified } = ctx.auth;
102+
assertThat(
103+
identityVerified,
104+
new RequestError({ code: 'verification_record.permission_denied', status: 401 })
105+
);
106+
const { name } = ctx.guard.body;
107+
const { fields } = ctx.accountCenter;
108+
assertThat(
109+
fields.mfa === AccountCenterControlValue.Edit,
110+
'account_center.filed_not_editable'
111+
);
112+
113+
assertThat(scopes.has(UserScope.Identities), 'auth.unauthorized');
114+
115+
const user = await findUserById(userId);
116+
const mfaVerification = user.mfaVerifications.find(
117+
(mfaVerification) =>
118+
mfaVerification.id === ctx.guard.params.id && mfaVerification.type === MfaFactor.WebAuthn
119+
);
120+
assertThat(mfaVerification, 'verification_record.not_found');
121+
122+
const updatedUser = await updateUserById(userId, {
123+
mfaVerifications: user.mfaVerifications.map((mfaVerification) =>
124+
mfaVerification.id === ctx.guard.params.id
125+
? { ...mfaVerification, name }
126+
: mfaVerification
127+
),
128+
});
129+
130+
ctx.appendDataHookContext('User.Data.Updated', { user: updatedUser });
131+
132+
ctx.status = 200;
133+
134+
return next();
135+
}
136+
);
85137
}

0 commit comments

Comments
 (0)