176 lines
7.2 KiB
TypeScript
176 lines
7.2 KiB
TypeScript
|
import Controller from "wms-core/Controller";
|
||
|
import {REQUIRE_ADMIN_MIDDLEWARE, REQUIRE_AUTH_MIDDLEWARE} from "wms-core/auth/AuthComponent";
|
||
|
import {Request, Response} from "express";
|
||
|
import User from "wms-core/auth/models/User";
|
||
|
import {WhereTest} from "wms-core/db/ModelQuery";
|
||
|
import UserNameComponent from "../models/UserNameComponent";
|
||
|
import UserMailIdentityComponent from "../models/UserMailIdentityComponent";
|
||
|
import {NotFoundHttpError} from "wms-core/HttpError";
|
||
|
import MailDomain from "../models/MailDomain";
|
||
|
import BackendController from "wms-core/helpers/BackendController";
|
||
|
import MailIdentity from "../models/MailIdentity";
|
||
|
|
||
|
export default class MailboxBackendController extends Controller {
|
||
|
public constructor() {
|
||
|
super();
|
||
|
BackendController.registerMenuElement({
|
||
|
getLink: async () => Controller.route('backend-mailboxes'),
|
||
|
getDisplayString: async () => 'Mailboxes',
|
||
|
getDisplayIcon: async () => 'mail',
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public getRoutesPrefix(): string {
|
||
|
return '/backend/mailboxes';
|
||
|
}
|
||
|
|
||
|
public routes(): void {
|
||
|
this.get('/', this.getMailboxesBackend, 'backend-mailboxes', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
|
||
|
this.get('/:id', this.getMailboxBackend, 'backend-mailbox', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
|
||
|
|
||
|
this.post('/add-domain', this.postAddDomain, 'backend-add-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE)
|
||
|
this.post('/remove-domain', this.postRemoveDomain, 'backend-remove-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE)
|
||
|
|
||
|
this.post('/:id/create-mail-identity', this.postCreateMailIdentity, 'backend-create-mail-identity', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
|
||
|
this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'backend-delete-mail-identity', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
|
||
|
}
|
||
|
|
||
|
protected async getMailboxesBackend(req: Request, res: Response): Promise<void> {
|
||
|
const mailDomains = await MailDomain.select()
|
||
|
.with('owner')
|
||
|
.with('identities')
|
||
|
.get();
|
||
|
|
||
|
const users = await User.select()
|
||
|
.where('main_mail_identity_id', null, WhereTest.NE)
|
||
|
.with('mainMailIdentity')
|
||
|
.with('mailIdentities')
|
||
|
.get();
|
||
|
|
||
|
res.render('backend/mailboxes', {
|
||
|
domains: await Promise.all(mailDomains.map(async domain => ({
|
||
|
id: domain.id,
|
||
|
name: domain.name,
|
||
|
owner_name: (await domain.owner.get())?.as(UserNameComponent).name,
|
||
|
identity_count: (await domain.identities.get()).length,
|
||
|
}))),
|
||
|
users: [{
|
||
|
value: 0,
|
||
|
display: 'Public',
|
||
|
}, ...(await User.select().get()).map(u => ({
|
||
|
value: u.id,
|
||
|
display: u.name,
|
||
|
}))],
|
||
|
mailboxes: await Promise.all(users.map(async user => ({
|
||
|
id: user.id,
|
||
|
username: user.as(UserNameComponent).name,
|
||
|
name: await (await user.as(UserMailIdentityComponent).mainMailIdentity.get())?.toEmail(),
|
||
|
identity_count: (await user.as(UserMailIdentityComponent).mailIdentities.get()).length,
|
||
|
domain_count: (await user.as(UserMailIdentityComponent).mailDomains.get()).length,
|
||
|
}))),
|
||
|
});
|
||
|
}
|
||
|
|
||
|
protected async getMailboxBackend(req: Request, res: Response): Promise<void> {
|
||
|
const user = await User.select()
|
||
|
.where('id', req.params.id)
|
||
|
.with('mailIdentities')
|
||
|
.first();
|
||
|
if (!user) throw new NotFoundHttpError('User', req.url);
|
||
|
|
||
|
res.render('backend/mailbox', {
|
||
|
mailbox: {
|
||
|
id: user.id,
|
||
|
name: await (await user.as(UserMailIdentityComponent).mainMailIdentity.get())?.toEmail() || 'Not created.',
|
||
|
},
|
||
|
domains: (await MailDomain.select().get()).map(d => ({
|
||
|
display: d.name,
|
||
|
value: d.id,
|
||
|
})),
|
||
|
identities: await Promise.all((await user.as(UserMailIdentityComponent).mailIdentities.get()).map(async i => ({
|
||
|
id: i.id,
|
||
|
email: await i.toEmail(),
|
||
|
}))),
|
||
|
});
|
||
|
}
|
||
|
|
||
|
protected async postAddDomain(req: Request, res: Response): Promise<void> {
|
||
|
const domain = MailDomain.create({
|
||
|
name: req.body.name,
|
||
|
user_id: req.body.user_id,
|
||
|
});
|
||
|
await domain.save();
|
||
|
req.flash('success', `Domain ${domain.name} successfully added with owner ${(await domain.owner.get())?.name}`);
|
||
|
res.redirectBack();
|
||
|
}
|
||
|
|
||
|
protected async postRemoveDomain(req: Request, res: Response): Promise<void> {
|
||
|
const domain = await MailDomain.select()
|
||
|
.where('id', req.body.id)
|
||
|
.with('identities')
|
||
|
.first();
|
||
|
if (!domain) throw new NotFoundHttpError('Domain', req.url);
|
||
|
|
||
|
// Don't delete that domain if it still has identities
|
||
|
if ((await domain.identities.get()).length > 0) {
|
||
|
req.flash('error', `This domain still has identities. Please remove all of these first (don't forget to rename mailboxes).`);
|
||
|
res.redirectBack();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
await domain.delete();
|
||
|
|
||
|
req.flash('success', `Domain ${domain.name} successfully deleted.`);
|
||
|
res.redirectBack();
|
||
|
}
|
||
|
|
||
|
protected async postCreateMailIdentity(req: Request, res: Response): Promise<void> {
|
||
|
const user = await User.select()
|
||
|
.where('id', req.params.id)
|
||
|
.first();
|
||
|
if (!user) throw new NotFoundHttpError('User', req.url);
|
||
|
|
||
|
const domain = await MailDomain.getById(req.body.mail_domain_id);
|
||
|
if (!domain) throw new NotFoundHttpError('domain', req.url);
|
||
|
|
||
|
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,
|
||
|
});
|
||
|
|
||
|
// 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', 'Mailbox created.');
|
||
|
}
|
||
|
|
||
|
req.flash('success', 'Mail identity ' + (await identity.toEmail()) + ' successfully created.')
|
||
|
res.redirectBack();
|
||
|
}
|
||
|
|
||
|
protected async postDeleteMailIdentity(req: Request, res: Response): Promise<void> {
|
||
|
const identity = await MailIdentity.select()
|
||
|
.where('id', req.body.id)
|
||
|
.with('user')
|
||
|
.first();
|
||
|
if (!identity) throw new NotFoundHttpError('Mail identity', req.url);
|
||
|
|
||
|
const user = await identity.user.get();
|
||
|
if (user?.as(UserMailIdentityComponent).main_mail_identity_id === identity.id) {
|
||
|
req.flash('error', `Cannot delete this user's mailbox identity.`);
|
||
|
res.redirectBack();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
await identity.delete();
|
||
|
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.');
|
||
|
res.redirectBack();
|
||
|
}
|
||
|
}
|