import Controller from "wms-core/Controller"; import {REQUIRE_AUTH_MIDDLEWARE} from "wms-core/auth/AuthComponent"; import {NextFunction, Request, Response} from "express"; import {ADD_RECOVERY_EMAIL_MAIL_TEMPLATE} from "../Mails"; import Validator, {InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator"; import {EMAIL_REGEX} from "wms-core/db/Model"; import MagicLinkController from "./MagicLinkController"; import {MagicLinkActionType} from "./MagicLinkActionType"; import UserEmail from "wms-core/auth/models/UserEmail"; import {BadRequestError, ForbiddenHttpError, NotFoundHttpError} from "wms-core/HttpError"; export default class AccountController extends Controller { routes(): void { this.get('/account', this.getAccount, 'account', REQUIRE_AUTH_MIDDLEWARE); this.post('/add-recovery-email', this.addRecoveryEmail, 'add-recovery-email', REQUIRE_AUTH_MIDDLEWARE); this.post('/set-main-email', this.postSetMainEmail, 'set-main-email', REQUIRE_AUTH_MIDDLEWARE); this.post('/remove-email', this.postRemoveEmail, 'remove-email', REQUIRE_AUTH_MIDDLEWARE); } protected async getAccount(req: Request, res: Response, next: NextFunction): Promise { res.render('account', { emails: await req.models.user!.emails.get(), }); } protected async addRecoveryEmail(req: Request, res: Response, next: NextFunction): Promise { await this.validate({ email: new Validator().defined().regexp(EMAIL_REGEX), }, req.body); const email = req.body.email; // Existing email if (await UserEmail.select().where('email', email).first()) { const bag = new ValidationBag(); const error = new InvalidFormatValidationError('You already have this email.'); error.thingName = 'email'; bag.addMessage(error); throw bag; } await MagicLinkController.sendMagicLink( req.sessionID!, MagicLinkActionType.ADD_RECOVERY_EMAIL, Controller.route('account'), email, ADD_RECOVERY_EMAIL_MAIL_TEMPLATE, {} ); res.redirect(Controller.route('magic_link_lobby', undefined, { redirect_uri: Controller.route('account'), })); } protected async postSetMainEmail(req: Request, res: Response): Promise { if (!req.body.id) throw new BadRequestError('Missing id field', 'Check form parameters.', req.url); const userEmail = await UserEmail.getById(req.body.id); if (!userEmail) throw new NotFoundHttpError('email', req.url); if (userEmail.user_id !== req.models.user!.id) throw new ForbiddenHttpError('email', req.url); if (userEmail.id === req.models.user!.main_email_id) throw new BadRequestError('This address is already your main address', 'Try refreshing the account page.', req.url); req.models.user!.main_email_id = userEmail.id; await req.models.user!.save(); req.flash('success', 'This email was successfully set as your main address.'); res.redirect(Controller.route('account')); } protected async postRemoveEmail(req: Request, res: Response): Promise { if (!req.body.id) throw new BadRequestError('Missing id field', 'Check form parameters.', req.url); const userEmail = await UserEmail.getById(req.body.id); if (!userEmail) throw new NotFoundHttpError('email', req.url); if (userEmail.user_id !== req.models.user!.id) throw new ForbiddenHttpError('email', req.url); if (userEmail.id === req.models.user!.main_email_id) throw new BadRequestError('Cannot remove main email address', 'Try refreshing the account page.', req.url); await userEmail.delete(); req.flash('success', 'This email was successfully removed from your account.'); res.redirect(Controller.route('account')); } }