import Controller from "swaf/Controller"; import {RequireAuthMiddleware} from "swaf/auth/AuthComponent"; import {Request, Response} from "express"; import Validator from "swaf/db/Validator"; import {ForbiddenHttpError, NotFoundHttpError} from "swaf/HttpError"; import MailDomain from "../models/MailDomain"; import UserMailIdentityComponent from "../models/UserMailIdentityComponent"; import MailIdentity from "../models/MailIdentity"; import {WhereOperator, WhereTest} from "swaf/db/ModelQuery"; import UserNameComponent from "swaf/auth/models/UserNameComponent"; export default class AccountMailboxController extends Controller { public getRoutesPrefix(): string { return '/account/mailbox'; } public routes(): void { this.get('/', this.getAccountMailbox, 'account-mailbox', RequireAuthMiddleware); this.post('/create-mail-identity', this.postCreateMailIdentity, 'create-mail-identity', RequireAuthMiddleware); this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'delete-mail-identity', RequireAuthMiddleware); } protected async getAccountMailbox(req: Request, res: Response): Promise { const user = req.as(RequireAuthMiddleware).getUser(); const userMailIdentity = user.as(UserMailIdentityComponent); res.render('account-mailbox', { mailboxIdentity: await (await userMailIdentity.mainMailIdentity.get())?.toEmail(), identities: await Promise.all((await userMailIdentity.mailIdentities.get()).map(async identity => ({ id: identity.id, email: await identity.toEmail(), }))), domains: (await MailDomain.select() .where('user_id', user.id) .where('user_id', null, WhereTest.EQ, WhereOperator.OR) .sortBy('user_id', 'DESC') .get()) .map(d => ({ value: d.id, display: d.name, })), }); } protected async postCreateMailIdentity(req: Request, res: Response): Promise { const domain = await MailDomain.getById(req.body.mail_domain_id); if (!domain) throw new NotFoundHttpError('domain', req.url); const user = req.as(RequireAuthMiddleware).getUser(); const mailIdentityComponent = user.as(UserMailIdentityComponent); const identity = MailIdentity.create({ user_id: user.id, name: req.body.name, mail_domain_id: req.body.mail_domain_id, }); // Check whether this identity can be created by this user if (!domain.canCreateAddresses(user)) { throw new ForbiddenHttpError('domain', req.url); } if (domain.isPublic()) { await Validator.validate({ name: new Validator().defined().equals(user.as(UserNameComponent).getName()), }, req.body); const actualPublicAddressesCount = await mailIdentityComponent.getPublicAddressesCount(); const maxPublicAddressesCount = mailIdentityComponent.getMaxPublicAddressesCount(); if (maxPublicAddressesCount >= 0 && actualPublicAddressesCount >= maxPublicAddressesCount) { req.flash('error', 'You have reached maximum public email addresses.'); res.redirect(Controller.route('account-mailbox')); return; } } // Save identity await identity.save(); // Set main mail identity if not already set if (!mailIdentityComponent.main_mail_identity_id) { mailIdentityComponent.main_mail_identity_id = identity.id; await user.save(); req.flash('info', 'Congratulations! You just created your mailbox.'); } req.flash('success', 'Mail identity ' + await identity.toEmail() + ' successfully created.'); res.redirect(Controller.route('account-mailbox')); } protected async postDeleteMailIdentity(req: Request, res: Response): Promise { const user = req.as(RequireAuthMiddleware).getUser(); const identity = await MailIdentity.getById(req.body.id); if (!identity) throw new NotFoundHttpError('Mail identity', req.url); if (identity.user_id !== user.id) throw new ForbiddenHttpError('mail identity', req.url); if (user.as(UserMailIdentityComponent).main_mail_identity_id === identity.id) { req.flash('error', 'Cannot delete your mailbox identity.'); res.redirect(Controller.route('account-mailbox')); return; } await identity.delete(); req.flash('success', 'Identity ' + await identity.toEmail() + ' successfully deleted.'); res.redirect(Controller.route('account-mailbox')); } }