import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import User from 'App/Models/User'; import { RenderResponse } from '@ioc:EidelLev/Inertia'; import TwoFactorAuthProvider from 'App/Services/TwoFactorAuthProvider'; import Hash from '@ioc:Adonis/Core/Hash'; import { schema, rules } from '@ioc:Adonis/Core/Validator'; // 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 { /** * Show the user a form to change their personal information & password. * * @return — \Inertia\Response */ public async accountInfo({ inertia, auth }: HttpContextContract): RenderResponse { // const user = auth.user; const user = (await User.find(auth.user?.id)) as User; // const id = request.param('id'); // const user = await User.query().where('id', id).firstOrFail(); return inertia.render('Auth/AccountInfo', { user: user, twoFactorEnabled: user.isTwoFactorEnabled, // code: await TwoFactorAuthProvider.generateQrCode(user), }); } public async accountInfoStore({ auth, request, response, session }) { const passwordSchema = schema.create({ old_password: schema.string({ trim: true }, [rules.required()]), new_password: schema.string({ trim: true }, [rules.minLength(8), rules.maxLength(255), rules.confirmed('confirm_password')]), confirm_password: schema.string({ trim: true }, [rules.required()]), }); try { await request.validate({ schema: passwordSchema }); } catch (error) { // return response.badRequest(error.messages); throw error; } try { const user = await auth.user; const { old_password, new_password } = request.only(['old_password', 'new_password']); // if (!(old_password && new_password && confirm_password)) { // return response.status(400).send({ warning: 'Old password and new password are required.' }); // } // Verify if the provided old password matches the user's current password const isSame = await Hash.verify(user.password, old_password); if (!isSame) { return response.flash({ warning: 'Old password is incorrect.' }).redirect().back(); } // Hash the new password before updating the user's password user.password = new_password; await user.save(); // return response.status(200).send({ message: 'Password updated successfully.' }); session.flash('Password updated successfully.'); return response.redirect().toRoute('settings.user.index'); } catch (error) { // return response.status(500).send({ message: 'Internal server error.' }); return response.flash('warning', `Invalid server state. Internal server error.`).redirect().back(); } } public async enableTwoFactorAuthentication({ auth, response, session }: HttpContextContract): Promise { // const user: User | undefined = auth?.user; const user = (await User.find(auth.user?.id)) as User; user.twoFactorSecret = TwoFactorAuthProvider.generateSecret(user); user.twoFactorRecoveryCodes = await TwoFactorAuthProvider.generateRecoveryCodes(); await user.save(); session.flash('message', 'Two factor authentication enabled.'); return response.redirect().back(); // return inertia.render('Auth/AccountInfo', { // // status: { // // type: 'success', // // message: 'Two factor authentication enabled.', // // }, // user: user, // twoFactorEnabled: user.isTwoFactorEnabled, // code: await TwoFactorAuthProvider.generateQrCode(user), // recoveryCodes: user.twoFactorRecoveryCodes, // }); } public async disableTwoFactorAuthentication({ auth, response, session }): Promise { const user = auth?.user; user.twoFactorSecret = null; user.twoFactorRecoveryCodes = null; await user.save(); session.flash('message', 'Two factor authentication disabled.'); return response.redirect().back(); // return inertia.render('Auth/AccountInfo', { // // status: { // // type: 'success', // // message: 'Two factor authentication disabled.', // // }, // user: user, // twoFactorEnabled: user.isTwoFactorEnabled, // }); } // public async fetchRecoveryCodes({ auth, view }) { // const user = auth?.user; // return view.render('pages/settings', { // twoFactorEnabled: user.isTwoFactorEnabled, // recoveryCodes: user.twoFactorRecoveryCodes, // }); // } }