feat(web): account security page and MFA enrolment wizard
This commit is contained in:
@@ -790,6 +790,70 @@ export const auth = {
|
||||
},
|
||||
};
|
||||
|
||||
export interface MePasskey {
|
||||
id: string;
|
||||
name: string;
|
||||
created_at: string;
|
||||
last_used_at?: string;
|
||||
transports?: string[];
|
||||
}
|
||||
|
||||
export interface MeMfaStatus {
|
||||
totp_enabled: boolean;
|
||||
passkeys: MePasskey[];
|
||||
recovery_remaining: number;
|
||||
/** The instance's require_mfa policy: a removal leaving no factor is refused. */
|
||||
require_mfa: boolean;
|
||||
/** False when an identity provider owns this user's authentication. */
|
||||
applicable: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The signed-in user's own factors, at /api/me/*. Several of these are
|
||||
* guarded by step-up and answer 403 `step_up_required`; that interception is
|
||||
* handled globally elsewhere, not here.
|
||||
*/
|
||||
export const me = {
|
||||
mfa(): Promise<MeMfaStatus> {
|
||||
return request<MeMfaStatus>("/me/mfa");
|
||||
},
|
||||
|
||||
totpSetup(): Promise<{ secret: string; otpauth_uri: string }> {
|
||||
return request("/me/mfa/totp/setup", { method: "POST" });
|
||||
},
|
||||
|
||||
totpConfirm(code: string): Promise<{ ok: true; recovery_codes?: string[] }> {
|
||||
return request("/me/mfa/totp/confirm", { method: "POST", body: JSON.stringify({ code }) });
|
||||
},
|
||||
|
||||
removeTotp(): Promise<void> {
|
||||
return request<void>("/me/mfa/totp", { method: "DELETE" });
|
||||
},
|
||||
|
||||
regenerateRecovery(): Promise<{ recovery_codes: string[] }> {
|
||||
return request("/me/mfa/recovery/regenerate", { method: "POST" });
|
||||
},
|
||||
|
||||
passkeyRegisterBegin(): Promise<{ publicKey: any; ceremony_id: string }> {
|
||||
return request("/me/passkeys/begin", { method: "POST" });
|
||||
},
|
||||
|
||||
passkeyRegisterFinish(ceremonyId: string, credential: unknown, name?: string): Promise<{ ok: true; recovery_codes?: string[] }> {
|
||||
return request("/me/passkeys/finish", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ ceremony_id: ceremonyId, credential, name }),
|
||||
});
|
||||
},
|
||||
|
||||
renamePasskey(id: string, name: string): Promise<void> {
|
||||
return request<void>(`/me/passkeys/${id}`, { method: "PATCH", body: JSON.stringify({ name }) });
|
||||
},
|
||||
|
||||
deletePasskey(id: string): Promise<void> {
|
||||
return request<void>(`/me/passkeys/${id}`, { method: "DELETE" });
|
||||
},
|
||||
};
|
||||
|
||||
export const api = {
|
||||
listInstanceUsers(): Promise<InstanceUser[]> {
|
||||
return request<InstanceUser[]>("/instance/users");
|
||||
|
||||
Reference in New Issue
Block a user