Add Optional 2FA Support (#61)

* Add TOTP MFA Support

* Add Passkey MFA Support

It's not impossible I missed some minor cleanup, but most things make sense and there isn't a lot of obvious duplication anymore.

---------

Co-authored-by: Bruno Bernardino <me@brunobernardino.com>
This commit is contained in:
0xGingi
2025-05-29 12:30:28 -04:00
committed by GitHub
parent 2a77915630
commit 455a7201e9
28 changed files with 2361 additions and 40 deletions

View File

@@ -13,6 +13,7 @@ export interface User {
is_admin?: boolean;
dav_hashed_password?: string;
expenses_currency?: SupportedCurrencySymbol;
multi_factor_auth_methods?: MultiFactorAuthMethod[];
};
created_at: Date;
}
@@ -156,6 +157,8 @@ export interface Config {
enableEmailVerification: boolean;
/** If true, all signups become active for 100 years */
enableForeverSignup: boolean;
/** If true, users can enable multi-factor authentication (TOTP or Passkeys) */
enableMultiFactor: boolean;
/** Can be set to allow more than the baseUrl's domain for session cookies */
allowedCookieDomains: string[];
/** If true, the cookie domain will not be strictly set and checked against. This skipping slightly reduces security, but is usually necessary for reverse proxies like Cloudflare Tunnel. */
@@ -178,3 +181,27 @@ export interface Config {
helpEmail: string;
};
}
export type MultiFactorAuthMethodType = 'totp' | 'passkey';
export interface MultiFactorAuthMethod {
type: MultiFactorAuthMethodType;
id: string;
name: string;
enabled: boolean;
created_at: Date;
metadata: {
totp?: {
hashed_secret: string;
hashed_backup_codes: string[];
};
passkey?: {
credential_id: string;
public_key: string;
counter?: number;
device_type?: string;
backed_up?: boolean;
transports?: AuthenticatorTransport[];
};
};
}