diff --git a/services/platform-service/src/modules/auth/mfa/routes.ts b/services/platform-service/src/modules/auth/mfa/routes.ts index 7f0e7a10..3eca9c93 100644 --- a/services/platform-service/src/modules/auth/mfa/routes.ts +++ b/services/platform-service/src/modules/auth/mfa/routes.ts @@ -16,7 +16,6 @@ import type { FastifyInstance } from 'fastify'; import { BadRequestError, UnauthorizedError, ForbiddenError } from '../../../lib/errors.js'; import * as nodeCrypto from 'node:crypto'; -import { getCollection } from '../../../lib/datastore.js'; import * as userRepo from '../repository.js'; import * as mfaRepo from './repository.js'; import * as jwt from '../jwt.js'; @@ -27,7 +26,6 @@ import { MfaDisableSchema, MfaPolicySchema, } from './types.js'; -import type { UserDoc } from '../types.js'; import type { MfaPolicyDoc } from './types.js'; export async function mfaRoutes(app: FastifyInstance) { @@ -44,8 +42,7 @@ export async function mfaRoutes(app: FastifyInstance) { } // Generate TOTP secret (base32) - const { randomBytes } = await import('node:crypto'); - const secretBuffer = randomBytes(20); + const secretBuffer = nodeCrypto.randomBytes(20); const secret = base32Encode(secretBuffer); // Encrypt the secret @@ -113,11 +110,7 @@ export async function mfaRoutes(app: FastifyInstance) { // Update user doc try { - await getCollection('users', '/id').update(payload.sub, payload.sub, { - mfaEnabled: true, - mfaMethods: ['totp'], - updatedAt: now, - } as Partial); + await userRepo.update(payload.sub, { mfaEnabled: true, mfaMethods: ['totp'] }); } catch { // best-effort } @@ -205,12 +198,7 @@ export async function mfaRoutes(app: FastifyInstance) { // Update user doc try { - const now = new Date().toISOString(); - await getCollection('users', '/id').update(payload.sub, payload.sub, { - mfaEnabled: false, - mfaMethods: [], - updatedAt: now, - } as Partial); + await userRepo.update(payload.sub, { mfaEnabled: false, mfaMethods: [] }); } catch { // best-effort } @@ -265,7 +253,7 @@ export async function mfaRoutes(app: FastifyInstance) { return { policy: policy ?? null }; }); - app.put('/auth/mfa/policies/:productId', async (req, _reply) => { + app.put('/auth/mfa/policies/:productId', async req => { const role = req.jwtPayload?.role; if (!role || !['super_admin', 'admin'].includes(role)) { throw new ForbiddenError('Admin access required'); diff --git a/services/platform-service/src/modules/auth/repository.ts b/services/platform-service/src/modules/auth/repository.ts index cd36f3f3..21e378e9 100644 --- a/services/platform-service/src/modules/auth/repository.ts +++ b/services/platform-service/src/modules/auth/repository.ts @@ -88,7 +88,19 @@ export async function countByPlan(productId: string): Promise + Pick< + UserDoc, + | 'displayName' + | 'role' + | 'plan' + | 'status' + | 'phone' + | 'bio' + | 'avatarUrl' + | 'mfaEnabled' + | 'mfaMethods' + | 'emailVerified' + > > ): Promise { try {