fix: add device verification settings endpoints

This commit is contained in:
shuaiplus
2026-07-06 00:59:34 +08:00
parent 9de0d3bd87
commit e376a840c2
2 changed files with 75 additions and 0 deletions
+64
View File
@@ -819,6 +819,18 @@ function yubiKeyResponse(user: User): Record<string, unknown> {
}; };
} }
function deviceVerificationSettingsResponse(user: User): Record<string, unknown> {
const enabled = user.verifyDevices !== false;
return {
Enabled: enabled,
enabled,
VerifyDevices: enabled,
verifyDevices: enabled,
Object: 'deviceVerificationSettings',
object: 'deviceVerificationSettings',
};
}
async function yubiKeySettingsResponse(storage: StorageService, env: Env, user: User): Promise<Record<string, unknown>> { async function yubiKeySettingsResponse(storage: StorageService, env: Env, user: User): Promise<Record<string, unknown>> {
const credentials = await getStoredYubicoCredentials(storage, env); const credentials = await getStoredYubicoCredentials(storage, env);
return { return {
@@ -893,6 +905,58 @@ export async function handleGetTwoFactorYubiKey(request: Request, env: Env, user
return jsonResponse(await yubiKeySettingsResponse(storage, env, user)); return jsonResponse(await yubiKeySettingsResponse(storage, env, user));
} }
// POST /api/two-factor/get-device-verification-settings
export async function handleGetDeviceVerificationSettings(request: Request, env: Env, userId: string): Promise<Response> {
void request;
const storage = new StorageService(env.DB);
const user = await storage.getUserById(userId);
if (!user) return errorResponse('User not found', 404);
return jsonResponse(deviceVerificationSettingsResponse(user));
}
// PUT/POST /api/two-factor/device-verification-settings
export async function handlePutDeviceVerificationSettings(request: Request, env: Env, userId: string): Promise<Response> {
const storage = new StorageService(env.DB);
const auth = new AuthService(env);
const user = await storage.getUserById(userId);
if (!user) return errorResponse('User not found', 404);
let body: Record<string, unknown>;
try {
body = await readRequestBody(request);
} catch {
return errorResponse('Invalid JSON', 400);
}
const rawEnabled = body.enabled ?? body.Enabled ?? body.verifyDevices ?? body.VerifyDevices;
if (typeof rawEnabled !== 'boolean') {
return errorResponse('enabled must be true or false', 400);
}
const secret = readBodyString(body, ['masterPasswordHash', 'MasterPasswordHash', 'secret', 'Secret']);
const verified = await verifyUserSecret(auth, user, secret);
if (!verified) return errorResponse('User verification failed.', 400);
user.verifyDevices = rawEnabled;
user.updatedAt = new Date().toISOString();
await storage.saveUser(user);
await writeAuditEvent(storage, {
actorUserId: user.id,
action: 'account.verify_devices.update',
category: 'security',
level: 'security',
targetType: 'user',
targetId: user.id,
metadata: {
verifyDevices: user.verifyDevices,
source: 'two-factor.device-verification-settings',
...auditRequestMetadata(request),
},
});
return jsonResponse(deviceVerificationSettingsResponse(user));
}
// PUT/POST /api/two-factor/authenticator // PUT/POST /api/two-factor/authenticator
export async function handlePutTwoFactorAuthenticator(request: Request, env: Env, userId: string): Promise<Response> { export async function handlePutTwoFactorAuthenticator(request: Request, env: Env, userId: string): Promise<Response> {
const storage = new StorageService(env.DB); const storage = new StorageService(env.DB);
+11
View File
@@ -19,6 +19,8 @@ import {
handlePutTwoFactorYubiKey, handlePutTwoFactorYubiKey,
handlePutTwoFactorYubiKeyConfig, handlePutTwoFactorYubiKeyConfig,
handleBootstrapTwoFactorYubiKeyConfig, handleBootstrapTwoFactorYubiKeyConfig,
handleGetDeviceVerificationSettings,
handlePutDeviceVerificationSettings,
handleDisableTwoFactorProvider, handleDisableTwoFactorProvider,
handleGetApiKey, handleGetApiKey,
handleRotateApiKey, handleRotateApiKey,
@@ -153,6 +155,15 @@ export async function handleAuthenticatedRoute(
return handleGetTwoFactorYubiKey(request, env, userId); return handleGetTwoFactorYubiKey(request, env, userId);
} }
if (path === '/api/two-factor/get-device-verification-settings' && method === 'POST') {
return handleGetDeviceVerificationSettings(request, env, userId);
}
if (path === '/api/two-factor/device-verification-settings') {
if (method === 'PUT' || method === 'POST') return handlePutDeviceVerificationSettings(request, env, userId);
return errorResponse('Method not allowed', 405);
}
if (path === '/api/two-factor/get-webauthn' && method === 'POST') { if (path === '/api/two-factor/get-webauthn' && method === 'POST') {
return handleGetTwoFactorWebAuthn(request, env, userId, currentUser); return handleGetTwoFactorWebAuthn(request, env, userId, currentUser);
} }