feat: sign in with a passkey (WebAuthn, ES256, discoverable credentials) and manage your passkeys [CI]

This commit is contained in:
justme committed 2026-10-07 21:57:19 +08:00
1 parent ddb6608e32
commit 6385c1b9a3
31 files changed
+2296 -42

No files matched your search

+385
View File
@@ -327,6 +327,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/admin/auth/passkey/options": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** A challenge for signing in with a passkey (discoverable credential, no username needed) */
post: operations["auth_passkey_options"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/auth/passkey/login": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Sign in with a passkey assertion; same response as the password sign-in */
post: operations["auth_passkey_login"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/releases": {
parameters: {
query?: never;
@@ -362,6 +396,58 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/admin/auth/passkeys": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** The signed-in user's passkeys */
get: operations["auth_passkeys_list"];
put?: never;
/** Register a passkey from a WebAuthn attestation (ES256, user verification required) */
post: operations["auth_passkeys_register"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/auth/passkeys/options": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** A challenge for registering a new passkey (the user must be signed in) */
post: operations["auth_passkeys_options"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/auth/passkeys/{id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** Remove one of your own passkeys */
delete: operations["auth_passkeys_delete"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/admin/auth/me": {
parameters: {
query?: never;
@@ -1574,6 +1660,10 @@ export interface components {
items: components["schemas"]["NodeInfoDto"][];
next_cursor: null | string;
};
PageDtoOfPasskeyDto: {
items: components["schemas"]["PasskeyDto"][];
next_cursor: null | string;
};
PageDtoOfPlanDto: {
items: components["schemas"]["PlanDto"][];
next_cursor: null | string;
@@ -1622,6 +1712,38 @@ export interface components {
values: null | string[];
description: string;
};
PasskeyCreationOptionsDto: {
challenge: string;
rp_id: string;
rp_name: string;
user_id: string;
user_name: string;
exclude_credentials: string[];
/** Format: int32 */
timeout_ms: number | string;
};
PasskeyDto: {
id: string;
name: string;
/** Format: date-time */
created_at: unknown;
/** Format: date-time */
last_used_at: unknown;
transports: string[];
};
PasskeyLoginRequest: {
credential_id: string;
authenticator_data: string;
client_data_json: string;
signature: string;
return_session: null | boolean;
};
PasskeyRequestOptionsDto: {
challenge: string;
rp_id: string;
/** Format: int32 */
timeout_ms: number | string;
};
PatchProbeRequest: {
name: null | string;
};
@@ -1718,6 +1840,13 @@ export interface components {
/** Format: int32 */
queue_length: number | string;
};
RegisterPasskeyRequest: {
name: string;
credential_id: string;
attestation_object: string;
client_data_json: string;
transports: null | string[];
};
RejectedDto: {
id: string;
reason: string;
@@ -2744,6 +2873,86 @@ export interface operations {
};
};
};
auth_passkey_options: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PasskeyRequestOptionsDto"];
};
};
/** @description Too Many Requests */
429: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
auth_passkey_login: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PasskeyLoginRequest"];
};
};
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LoginResponse"];
};
};
/** @description Bad Request */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Too Many Requests */
429: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
releases_list: {
parameters: {
query?: never;
@@ -2871,6 +3080,182 @@ export interface operations {
};
};
};
auth_passkeys_list: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PageDtoOfPasskeyDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
auth_passkeys_register: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["RegisterPasskeyRequest"];
};
};
responses: {
/** @description Created */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PasskeyDto"];
};
};
/** @description Bad Request */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Conflict */
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
auth_passkeys_options: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PasskeyCreationOptionsDto"];
};
};
/** @description Bad Request */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
auth_passkeys_delete: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description No Content */
204: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": unknown;
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["ProblemDto"];
};
};
};
};
auth_me: {
parameters: {
query?: never;