const mongoose = require('mongoose') const UserModel = require('../models/UserModel') function toObjectId (id) { if (id instanceof mongoose.Types.ObjectId) return id return new mongoose.Types.ObjectId(String(id)) } async function readTotpState (userId) { const doc = await UserModel.collection.findOne( { _id: toObjectId(userId) }, { projection: { totp_secret: 1, totp_pending_secret: 1, totp_enabled: 1 } } ) if (!doc) return null return { totp_secret: doc.totp_secret || null, totp_pending_secret: doc.totp_pending_secret || null, totp_enabled: Boolean(doc.totp_enabled), } } async function setPendingSecret (userId, secret) { const result = await UserModel.updateOne( { _id: toObjectId(userId) }, { $set: { totp_pending_secret: secret } }, { strict: false } ) if (!result.matchedCount) { const err = new Error('USER_NOT_FOUND') err.status = 404 err.userMessage = 'کاربر یافت نشد' throw err } } async function activateTotp (userId, secret) { const result = await UserModel.updateOne( { _id: toObjectId(userId) }, { $set: { totp_secret: secret, totp_enabled: true, }, $unset: { totp_pending_secret: '' }, }, { strict: false } ) if (!result.matchedCount) { const err = new Error('USER_NOT_FOUND') err.status = 404 err.userMessage = 'کاربر یافت نشد' throw err } } async function deactivateTotp (userId) { const result = await UserModel.updateOne( { _id: toObjectId(userId) }, { $set: { totp_enabled: false }, $unset: { totp_secret: '', totp_pending_secret: '' }, }, { strict: false } ) if (!result.matchedCount) { const err = new Error('USER_NOT_FOUND') err.status = 404 err.userMessage = 'کاربر یافت نشد' throw err } } module.exports = { readTotpState, setPendingSecret, activateTotp, deactivateTotp, }