feat(profile): Passkey-Labels, Sicherheits-Checkliste und Geräte-Block
Erweitert die Profilseite um benennbare Passkeys, Sicherheitsübersicht, Gerät/Sync-Status, Backup-Hinweis in der Gefahrenzone und Dialog beim Löschen des letzten Passkeys. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -546,6 +546,7 @@ export async function deleteAccount(): Promise<boolean> {
|
||||
|
||||
export interface UserProfileCredential {
|
||||
id: string
|
||||
label: string | null
|
||||
credentialIdPreview: string
|
||||
transports: string[]
|
||||
}
|
||||
@@ -579,7 +580,7 @@ async function enrollPrfFromMasterKey(masterKey: ArrayBuffer, prfFirst: ArrayBuf
|
||||
})
|
||||
}
|
||||
|
||||
export async function addPasskey(): Promise<void> {
|
||||
export async function addPasskey(label?: string): Promise<void> {
|
||||
await reauthWithPasskey()
|
||||
|
||||
const options = await apiJson<any>(`${API_BASE}/add-credential-options`, {
|
||||
@@ -613,7 +614,11 @@ export async function addPasskey(): Promise<void> {
|
||||
|
||||
await apiJson(`${API_BASE}/add-credential-verify`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ credentialResponse, challenge: options.challenge })
|
||||
body: JSON.stringify({
|
||||
credentialResponse,
|
||||
challenge: options.challenge,
|
||||
...(label?.trim() ? { label: label.trim() } : {})
|
||||
})
|
||||
})
|
||||
|
||||
const masterKey = getActiveMasterKey()
|
||||
@@ -639,3 +644,10 @@ export async function removePasskey(credentialDbId: string): Promise<void> {
|
||||
throw new Error(body.error || 'Failed to remove passkey')
|
||||
}
|
||||
}
|
||||
|
||||
export async function renamePasskey(credentialDbId: string, label: string): Promise<void> {
|
||||
await apiJson(`${API_BASE}/credentials/${credentialDbId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ label })
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user