fix 2fa and move communication language to setting
Build & Push / Pipeline Tests (push) Failing after 1m26s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 50s
Test / API Unit Tests (push) Failing after 1m6s
Test / Homepage Unit Tests (push) Successful in 48s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 41s
Test / API Integration Tests (push) Successful in 1m6s

This commit is contained in:
root
2026-08-23 00:45:39 -04:00
parent c8d7a3954a
commit e3f80af47d
29 changed files with 890 additions and 255 deletions
+29 -4
View File
@@ -142,14 +142,14 @@ export async function login(email: string, password: string, totpCode?: string,
if (admin.totpEnabled) {
if (!totpCode && !recoveryCode) {
await sendAdminEmailOtp(admin)
return { totpRequired: true } as const
if (!admin.totpSecret) await sendAdminEmailOtp(admin)
return { totpRequired: true, method: admin.totpSecret ? 'authenticator' : 'email' } as const
}
const validTotp = totpCode
const validTotp = totpCode && admin.totpSecret
? authenticator.verify({ token: totpCode, secret: admin.totpSecret! })
: false
const validEmailOtp = !validTotp && await consumeAdminEmailOtp(admin.id, totpCode)
const validEmailOtp = !validTotp && !admin.totpSecret && await consumeAdminEmailOtp(admin.id, totpCode)
const validRecoveryCode = !validTotp && !validEmailOtp && recoveryCode
? await consumeAdminRecoveryCode(admin.id, recoveryCode)
: false
@@ -183,6 +183,31 @@ export async function setupTotp(adminId: string, email: string) {
return { secret, qrCode }
}
export async function setupEmail2fa(adminId: string) {
const admin = await repo.findAdminByIdOrThrow(adminId)
await sendAdminEmailOtp(admin)
return { message: 'Verification code sent.' }
}
export async function verifyEmail2fa(adminId: string, code: string) {
const admin = await repo.findAdminByIdOrThrow(adminId)
const valid = await consumeAdminEmailOtp(adminId, code)
if (!valid) return false
const updated = await repo.enableAdminEmail2fa(adminId)
await repo.createAuditLog({
adminUserId: adminId,
action: 'ADMIN_2FA_EMAIL_ENABLED',
resource: 'AdminUser',
resourceId: adminId,
})
const recoveryCodes = await issueAdminRecoveryCodes(adminId)
return {
...presenter.presentAdminSession({ ...admin, ...updated, totpEnabled: true }, signAdminToken(adminId, Date.now())),
recoveryCodes,
}
}
export async function verifyTotp(adminId: string, code: string) {
const admin = await repo.findAdminByIdOrThrow(adminId)
if (!admin.totpSecret) return false