feat: add TOTP multifactor authentication

This commit is contained in:
jb
2026-08-07 13:10:05 -04:00
parent 4777a3abd5
commit e67c3d4cdb
50 changed files with 6646 additions and 539 deletions
+23
View File
@@ -5,6 +5,8 @@ const validAppEnvironment = {
APP_ORIGIN: 'https://stage.shd.build',
ORIGIN: 'https://stage.shd.build',
PASSKEY_RP_ID: 'shd.build',
MFA_TOTP_ENCRYPTION_KEYS:
'primary-2026:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
SCHEDULER_TOKEN: 'scheduler-secret-with-32-characters',
TDR_DATABASE_PATH: '/app/data/shd-build-staging.db',
TDR_AVATAR_STORAGE_PATH: '/app/data/avatars',
@@ -21,6 +23,7 @@ describe('validateRuntimeEnvironment', () => {
'APP_ORIGIN is required.',
'ORIGIN is required.',
'PASSKEY_RP_ID is required.',
'MFA_TOTP_ENCRYPTION_KEYS is required.',
'SCHEDULER_TOKEN is required.',
'TDR_DATABASE_PATH is required.',
'TDR_AVATAR_STORAGE_PATH is required.',
@@ -158,4 +161,24 @@ describe('validateRuntimeEnvironment', () => {
validateRuntimeEnvironment('worker' as 'app', validAppEnvironment),
).toThrow('Unsupported runtime mode: worker');
});
it('validates the MFA encryption keyring without echoing secrets', () => {
expect(
validateRuntimeEnvironment('app', {
...validAppEnvironment,
MFA_TOTP_ENCRYPTION_KEYS:
'one:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,one:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
}),
).toEqual(['MFA_TOTP_ENCRYPTION_KEYS must not repeat key IDs or keys.']);
const errors = validateRuntimeEnvironment('app', {
...validAppEnvironment,
MFA_TOTP_ENCRYPTION_KEYS:
'primary:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
});
expect(errors).toEqual([
'MFA_TOTP_ENCRYPTION_KEYS entries must use key-id and canonical 32-byte Base64URL values.',
]);
expect(errors.join('\n')).not.toContain('primary:');
});
});