mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-05 06:50:10 +00:00
feat: add passkey-based two-factor authentication
This commit is contained in:
+17
-7
@@ -161,7 +161,7 @@ const STORAGE_SCHEMA_VERSION_KEY = 'schema.version';
|
||||
// Bump this whenever src/services/storage-schema.ts or migrations/0001_init.sql
|
||||
// changes. Existing D1 installs only rerun ensureStorageSchema() when this value
|
||||
// differs from config.schema.version.
|
||||
const STORAGE_SCHEMA_VERSION = '2026-07-03-yubikey-otp';
|
||||
const STORAGE_SCHEMA_VERSION = '2026-07-05-passkey-2fa';
|
||||
const REQUIRED_SCHEMA_TABLES = ['webauthn_credentials', 'webauthn_challenges', 'auth_requests', 'totp_login_replays'] as const;
|
||||
|
||||
// D1-backed storage.
|
||||
@@ -398,8 +398,11 @@ export class StorageService {
|
||||
await saveStoredAccountPasskeyCredential(this.db, this.safeBind.bind(this), credential);
|
||||
}
|
||||
|
||||
async getAccountPasskeyCredentialsByUserId(userId: string): Promise<AccountPasskeyCredential[]> {
|
||||
return listStoredAccountPasskeyCredentialsByUserId(this.db, userId);
|
||||
async getAccountPasskeyCredentialsByUserId(
|
||||
userId: string,
|
||||
purpose: AccountPasskeyCredential['purpose'] = 'login'
|
||||
): Promise<AccountPasskeyCredential[]> {
|
||||
return listStoredAccountPasskeyCredentialsByUserId(this.db, userId, purpose);
|
||||
}
|
||||
|
||||
async getAccountPasskeyCredentialById(userId: string, id: string): Promise<AccountPasskeyCredential | null> {
|
||||
@@ -410,8 +413,11 @@ export class StorageService {
|
||||
return findStoredAccountPasskeyCredentialByCredentialId(this.db, credentialId);
|
||||
}
|
||||
|
||||
async countAccountPasskeyCredentialsByUserId(userId: string): Promise<number> {
|
||||
return countStoredAccountPasskeyCredentialsByUserId(this.db, userId);
|
||||
async countAccountPasskeyCredentialsByUserId(
|
||||
userId: string,
|
||||
purpose: AccountPasskeyCredential['purpose'] = 'login'
|
||||
): Promise<number> {
|
||||
return countStoredAccountPasskeyCredentialsByUserId(this.db, userId, purpose);
|
||||
}
|
||||
|
||||
async updateAccountPasskeyCounter(
|
||||
@@ -442,8 +448,12 @@ export class StorageService {
|
||||
);
|
||||
}
|
||||
|
||||
async deleteAccountPasskeyCredential(userId: string, id: string): Promise<boolean> {
|
||||
return deleteStoredAccountPasskeyCredential(this.db, userId, id);
|
||||
async deleteAccountPasskeyCredential(
|
||||
userId: string,
|
||||
id: string,
|
||||
purpose: AccountPasskeyCredential['purpose'] = 'login'
|
||||
): Promise<boolean> {
|
||||
return deleteStoredAccountPasskeyCredential(this.db, userId, id, purpose);
|
||||
}
|
||||
|
||||
async saveAccountPasskeyChallenge(challenge: AccountPasskeyChallenge): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user