Refactor: Remove passkey-related functionality and types

- Deleted passkey-related interfaces and types from index.ts and types.ts.
- Removed passkey handling from App component, including related state and functions.
- Cleaned up API calls in auth.ts, removing passkey registration and login functions.
- Updated vault and import formats to eliminate passkey references.
- Removed passkey support checks and UI elements from AuthViews and SettingsPage.
- Cleaned up unused passkey helper functions and constants.
- Adjusted related components and hooks to ensure consistent functionality without passkey support.
This commit is contained in:
shuaiplus
2026-04-06 00:46:13 +08:00
parent 90a7731351
commit 76623d7201
28 changed files with 28 additions and 1064 deletions
-87
View File
@@ -8,7 +8,6 @@ import type {
TokenSuccess,
} from '../types';
import { parseJson, type AuthedFetch, type SessionSetter } from './shared';
import { createPasskeyCredential, requestPasskeyAssertion } from '../passkey';
const SESSION_KEY = 'nodewarden.web.session.v4';
const DEVICE_IDENTIFIER_KEY = 'nodewarden.web.device.identifier.v1';
@@ -27,14 +26,6 @@ export interface PreloginKdfConfig {
kdfParallelism: number | null;
}
export interface AccountPasskey {
id: string;
name: string;
creationDate: string;
revisionDate: string;
lastUsedDate: string | null;
}
function randomHex(length: number): string {
const bytes = crypto.getRandomValues(new Uint8Array(Math.max(1, Math.ceil(length / 2))));
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('').slice(0, length);
@@ -206,84 +197,6 @@ export async function refreshAccessToken(refreshToken: string): Promise<TokenSuc
return json || null;
}
export async function listAccountPasskeys(authedFetch: AuthedFetch): Promise<AccountPasskey[]> {
const resp = await authedFetch('/api/accounts/passkeys');
if (!resp.ok) throw new Error('Failed to load passkeys');
const body = (await parseJson<{ data?: AccountPasskey[] }>(resp)) || {};
return Array.isArray(body.data) ? body.data : [];
}
export async function registerAccountPasskey(authedFetch: AuthedFetch, name: string, session: SessionState): Promise<void> {
const beginResp = await authedFetch('/api/accounts/passkeys/begin-registration', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: '{}',
});
if (!beginResp.ok) throw new Error('Failed to start passkey registration');
const begin = (await parseJson<{ challengeId: string; publicKey: Record<string, any> }>(beginResp)) || {};
if (!begin.challengeId || !begin.publicKey) throw new Error('Invalid registration challenge');
const credential = await createPasskeyCredential(begin.publicKey);
const finishResp = await authedFetch('/api/accounts/passkeys/finish-registration', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
challengeId: begin.challengeId,
name,
wrappedVaultKeys: JSON.stringify({
symEncKey: session.symEncKey || '',
symMacKey: session.symMacKey || '',
}),
credential,
}),
});
if (!finishResp.ok) {
const err = await parseJson<TokenError>(finishResp);
throw new Error(err?.error_description || err?.error || 'Failed to finish passkey registration');
}
}
export async function renameAccountPasskey(authedFetch: AuthedFetch, passkeyId: string, name: string): Promise<void> {
const resp = await authedFetch(`/api/accounts/passkeys/${passkeyId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name }),
});
if (!resp.ok) throw new Error('Failed to rename passkey');
}
export async function deleteAccountPasskey(authedFetch: AuthedFetch, passkeyId: string): Promise<void> {
const resp = await authedFetch(`/api/accounts/passkeys/${passkeyId}`, { method: 'DELETE' });
if (!resp.ok && resp.status !== 204) throw new Error('Failed to delete passkey');
}
export async function loginWithPasskey(email?: string, totpCode?: string): Promise<TokenSuccess | TokenError> {
const beginResp = await fetch('/identity/passkeys/begin-login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: String(email || '').trim().toLowerCase() || undefined }),
});
if (!beginResp.ok) return ((await parseJson<TokenError>(beginResp)) || {});
const begin = (await parseJson<{ challengeId: string; publicKey: Record<string, any> }>(beginResp)) || {};
if (!begin.challengeId || !begin.publicKey) return { error: 'Passkey challenge missing' };
const credential = await requestPasskeyAssertion(begin.publicKey);
const finishResp = await fetch('/identity/passkeys/finish-login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
challengeId: begin.challengeId,
credential,
deviceIdentifier: getOrCreateDeviceIdentifier(),
deviceName: guessDeviceName(),
deviceType: '14',
twoFactorToken: totpCode || undefined,
}),
});
const result = (await parseJson<TokenSuccess & TokenError>(finishResp)) || {};
return result;
}
export async function registerAccount(args: {
email: string;
name: string;