import type { HttpContext } from '@adonisjs/core/http'; // import TotpSecret from 'App/Models/TotpSecret'; import User from '#app/Models/User'; import TwoFactorAuthProvider from '#app/Services/TwoFactorAuthProvider'; import { StatusCodes } from 'http-status-codes'; import { InvalidArgumentException } from 'node-exceptions'; import { TotpState } from '#contracts/enums'; // Here we are generating secret and recovery codes for the user that’s enabling 2FA and storing them to our database. export default class UserController { public async enable({ auth, response, request }: HttpContext) { const user = (await User.find(auth.user?.id)) as User; // await user.load('totp_secret'); // if (!user.totp_secret) { // let totpSecret = new TotpSecret(); // user.related('totp_secret').save(totpSecret); // await user.load('totp_secret'); // } if (!user) { throw new Error('user not available'); } const state: number = request.input('state'); try { switch (state) { case TotpState.STATE_DISABLED: // user.twoFactorSecret = null; // user.twoFactorRecoveryCodes = null; user.twoFactorSecret = ""; user.twoFactorRecoveryCodes = [""]; await user.save(); user.state = TotpState.STATE_DISABLED; await user.save(); return response.status(StatusCodes.OK).json({ state: TotpState.STATE_DISABLED, }); case TotpState.STATE_CREATED: user.twoFactorSecret = TwoFactorAuthProvider.generateSecret(user); user.state = TotpState.STATE_CREATED; await user.save(); let qrcode = await TwoFactorAuthProvider.generateQrCode(user); // throw new InvalidArgumentException('code is missing'); return response.status(StatusCodes.OK).json({ state: user.state, secret: user.twoFactorSecret, url: qrcode.url, svg: qrcode.svg, }); case TotpState.STATE_ENABLED: let code: string = request.input('code'); if (!code) { throw new InvalidArgumentException('code is missing'); } const success = await TwoFactorAuthProvider.enable(user, code) return response.status(StatusCodes.OK).json({ state: success ? TotpState.STATE_ENABLED : TotpState.STATE_CREATED, }); default: throw new InvalidArgumentException('Invalid TOTP state'); } } catch (error) { return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({ message: 'Invalid TOTP state', }); } } // public async fetchRecoveryCodes({ auth, view }) { // const user = auth?.user; // return view.render('pages/settings', { // twoFactorEnabled: user.isTwoFactorEnabled, // recoveryCodes: user.twoFactorRecoveryCodes, // }); // } }