diff --git a/src/server/api/me/totp.post.ts b/src/server/api/me/totp.post.ts index 53c87f8a..f3782828 100644 --- a/src/server/api/me/totp.post.ts +++ b/src/server/api/me/totp.post.ts @@ -23,6 +23,13 @@ export default definePermissionEventHandler( checkPermissions(user); if (body.type === 'setup') { + if (user.totpVerified) { + throw createError({ + statusCode: 409, + statusMessage: 'TOTP is already enabled', + }); + } + const key = new Secret({ size: 20 }); const totp = new TOTP({ @@ -50,6 +57,13 @@ export default definePermissionEventHandler( type: 'created', } as Response; } else if (body.type === 'delete') { + if (!user.totpVerified) { + throw createError({ + statusCode: 409, + statusMessage: 'TOTP is not enabled', + }); + } + await Database.users.deleteTotpKey(user.id, body.currentPassword); return { diff --git a/src/server/database/repositories/user/service.ts b/src/server/database/repositories/user/service.ts index e3526315..b84ed365 100644 --- a/src/server/database/repositories/user/service.ts +++ b/src/server/database/repositories/user/service.ts @@ -221,6 +221,10 @@ export class UserService { throw new Error('User not found'); } + if (txUser.totpVerified) { + throw new Error('TOTP is already verified'); + } + const totpKey = txUser.totpKey; if (!totpKey) { throw new Error('TOTP key is not set'); diff --git a/src/server/database/repositories/user/types.ts b/src/server/database/repositories/user/types.ts index bb5a7290..9a175a6a 100644 --- a/src/server/database/repositories/user/types.ts +++ b/src/server/database/repositories/user/types.ts @@ -18,7 +18,10 @@ const remember = z.boolean({ message: t('zod.user.remember') }); const totpCode = z .string({ message: t('zod.user.totpCode') }) + // min and max to improve error messages .min(6, t('zod.user.totpCode')) + .max(6, t('zod.user.totpCode')) + .regex(/^\d{6}$/, t('zod.user.totpCode')) .pipe(safeStringRefine); export const UserLoginSchema = z.object({