From 2007a4b2da5f843a82ca9b46c1130c6615336fb4 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:48:39 +0200 Subject: [PATCH] feat: add passkey types and APP_PASSKEY_REQUIRED handling Extends MfaStatus with passkeyEnrolled/passkeyCount fields, adds PasskeyCredential and AuthPolicy types, expands TenantSettings with passkey fields, handles APP_PASSKEY_REQUIRED 403 redirect, and adds putJson method to the api client for JSON PUT requests. Co-Authored-By: Claude Sonnet 4.6 --- ui/src/api/client.ts | 6 ++++++ ui/src/types/api.ts | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ui/src/api/client.ts b/ui/src/api/client.ts index 67e5ac1..d4c4f71 100644 --- a/ui/src/api/client.ts +++ b/ui/src/api/client.ts @@ -69,6 +69,10 @@ async function apiFetch(path: string, options: RequestInit = {}): Promise window.location.href = '/platform/tenant/settings?mfa=required'; throw new ApiError(403, '{"message":"MFA enrollment required"}'); } + if (errorHeader === 'APP_PASSKEY_REQUIRED') { + window.location.href = '/platform/tenant/settings?passkey=required'; + throw new ApiError(403, '{"message":"Passkey enrollment required"}'); + } } if (!response.ok) { @@ -91,6 +95,8 @@ export const api = { apiFetch(path, { method: 'PATCH', body: JSON.stringify(body) }), put: (path: string, body: FormData) => apiFetch(path, { method: 'PUT', body }), + putJson: (path: string, body: unknown) => + apiFetch(path, { method: 'PUT', body: JSON.stringify(body) }), delete: (path: string) => apiFetch(path, { method: 'DELETE' }), }; diff --git a/ui/src/types/api.ts b/ui/src/types/api.ts index 5f7d8ef..aeab2d2 100644 --- a/ui/src/types/api.ts +++ b/ui/src/types/api.ts @@ -137,6 +137,9 @@ export interface TenantSettings { serverEndpoint: string | null; createdAt: string; mfaRequired?: boolean; + mfaMode?: string; + passkeyEnabled?: boolean; + passkeyMode?: string; } // SSO connector types @@ -245,6 +248,8 @@ export interface TenantMetricsEntry { export interface MfaStatus { enrolled: boolean; hasBackupCodes: boolean; + passkeyEnrolled: boolean; + passkeyCount: number; } export interface MfaSetupResponse { @@ -255,3 +260,16 @@ export interface MfaSetupResponse { export interface BackupCodesResponse { codes: string[]; } + +export interface PasskeyCredential { + id: string; + name: string | null; + agent: string | null; + createdAt: string | null; +} + +export interface AuthPolicy { + mfaMode: string; + passkeyEnabled: boolean; + passkeyMode: string; +}