2021-01-25 18:04:11 +01:00
import Controller from "swaf/Controller" ;
2020-07-27 16:02:09 +02:00
import { Request , Response } from "express" ;
2021-01-25 18:04:11 +01:00
import User from "swaf/auth/models/User" ;
import { WhereTest } from "swaf/db/ModelQuery" ;
2020-11-10 14:53:58 +01:00
import UserMailIdentityComponent from "../../models/UserMailIdentityComponent" ;
2021-03-01 13:43:29 +01:00
import { NotFoundHttpError , ServerError } from "swaf/HttpError" ;
2020-11-10 14:53:58 +01:00
import MailDomain from "../../models/MailDomain" ;
2021-01-25 18:04:11 +01:00
import BackendController from "swaf/helpers/BackendController" ;
2020-11-10 14:53:58 +01:00
import MailIdentity from "../../models/MailIdentity" ;
2021-01-25 18:04:11 +01:00
import { RequireAdminMiddleware , RequireAuthMiddleware } from "swaf/auth/AuthComponent" ;
import UserNameComponent from "swaf/auth/models/UserNameComponent" ;
2020-07-27 16:02:09 +02:00
export default class MailboxBackendController extends Controller {
public constructor ( ) {
super ( ) ;
2021-03-01 14:01:02 +01:00
BackendController . registerMenuElement ( {
getLink : async ( ) = > Controller . route ( 'backend-mail-domains' ) ,
getDisplayString : async ( ) = > 'Mail domains' ,
getDisplayIcon : async ( ) = > 'globe' ,
} ) ;
2020-07-27 16:02:09 +02:00
BackendController . registerMenuElement ( {
getLink : async ( ) = > Controller . route ( 'backend-mailboxes' ) ,
getDisplayString : async ( ) = > 'Mailboxes' ,
getDisplayIcon : async ( ) = > 'mail' ,
} ) ;
}
public getRoutesPrefix ( ) : string {
return '/backend/mailboxes' ;
}
public routes ( ) : void {
2020-11-02 18:59:35 +01:00
this . get ( '/' , this . getMailboxesBackend , 'backend-mailboxes' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2021-03-01 14:01:02 +01:00
this . get ( '/mailbox/:id' , this . getMailboxBackend , 'backend-mailbox' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2020-07-27 16:02:09 +02:00
2021-03-01 14:01:02 +01:00
this . get ( '/domains' , this . getDomainsBackend , 'backend-mail-domains' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2020-11-02 18:59:35 +01:00
this . post ( '/add-domain' , this . postAddDomain , 'backend-add-domain' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
this . get ( '/edit-domain/:id' , this . getEditDomain , 'backend-edit-domain' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
this . post ( '/edit-domain/:id' , this . postEditDomain , 'backend-edit-domain' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
this . post ( '/remove-domain' , this . postRemoveDomain , 'backend-remove-domain' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2020-07-27 16:02:09 +02:00
2020-11-02 18:59:35 +01:00
this . post ( '/:id/create-mail-identity' , this . postCreateMailIdentity , 'backend-create-mail-identity' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2021-03-01 13:43:29 +01:00
this . post ( '/set-main-mail-identity' , this . postSetMainMailIdentity , 'backend-set-main-mail-identity' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2020-11-02 18:59:35 +01:00
this . post ( '/delete-mail-identity' , this . postDeleteMailIdentity , 'backend-delete-mail-identity' , RequireAuthMiddleware , RequireAdminMiddleware ) ;
2020-07-27 16:02:09 +02:00
}
protected async getMailboxesBackend ( req : Request , res : Response ) : Promise < void > {
const users = await User . select ( )
. where ( 'main_mail_identity_id' , null , WhereTest . NE )
. with ( 'mainMailIdentity' )
. with ( 'mailIdentities' )
. get ( ) ;
res . render ( 'backend/mailboxes' , {
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 ) ;
2020-11-02 19:27:18 +01:00
const mainMailIdentity = await user . as ( UserMailIdentityComponent ) . mainMailIdentity . get ( ) ;
const mailDomains = await MailDomain . select ( ) . get ( ) ;
const mailIdentities = await user . as ( UserMailIdentityComponent ) . mailIdentities . get ( ) ;
2020-07-27 16:02:09 +02:00
res . render ( 'backend/mailbox' , {
mailbox : {
id : user.id ,
2020-11-10 15:22:06 +01:00
userName : user.as ( UserNameComponent ) . name ,
2020-11-02 19:27:18 +01:00
name : await mainMailIdentity ? . toEmail ( ) || 'Not created.' ,
2021-02-26 12:56:56 +01:00
exists : ! ! mainMailIdentity ,
2020-07-27 16:02:09 +02:00
} ,
2020-11-02 19:27:18 +01:00
domains : mailDomains.map ( d = > ( {
2020-07-27 16:02:09 +02:00
display : d.name ,
value : d.id ,
} ) ) ,
2020-11-02 19:27:18 +01:00
identities : await Promise . all ( mailIdentities . map ( async i = > ( {
2020-07-27 16:02:09 +02:00
id : i.id ,
email : await i . toEmail ( ) ,
} ) ) ) ,
} ) ;
}
2021-03-01 14:01:02 +01:00
protected async getDomainsBackend ( req : Request , res : Response ) : Promise < void > {
const mailDomains = await MailDomain . select ( )
. with ( 'owner' )
. with ( 'identities' )
. get ( ) ;
res . render ( 'backend/mail_domains' , {
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 ,
} ) ) ) ,
} ) ;
}
2020-07-27 16:02:09 +02:00
protected async postAddDomain ( req : Request , res : Response ) : Promise < void > {
2020-11-03 11:21:32 +01:00
const domain = MailDomain . create ( req . body ) ;
2020-07-27 16:02:09 +02:00
await domain . save ( ) ;
req . flash ( 'success' , ` Domain ${ domain . name } successfully added with owner ${ ( await domain . owner . get ( ) ) ? . name } ` ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-edit-domain' , domain . id ) ) ;
2020-07-27 16:02:09 +02:00
}
2020-07-30 10:58:51 +02:00
protected async getEditDomain ( req : Request , res : Response ) : Promise < void > {
const domain = await MailDomain . getById ( req . params . id ) ;
if ( ! domain ) throw new NotFoundHttpError ( 'Domain' , req . url ) ;
res . render ( 'backend/mail_domain' , {
domain : domain ,
users : [ {
value : 0 ,
display : 'Public' ,
} , . . . ( await User . select ( ) . get ( ) ) . map ( u = > ( {
value : u.id ,
display : u.name ,
} ) ) ] ,
} ) ;
}
protected async postEditDomain ( req : Request , res : Response ) : Promise < void > {
const domain = await MailDomain . select ( )
. where ( 'id' , req . params . id )
. first ( ) ;
if ( ! domain ) throw new NotFoundHttpError ( 'Domain' , req . url ) ;
2020-07-30 11:14:35 +02:00
domain . updateWithData ( req . body ) ;
2020-07-30 10:58:51 +02:00
await domain . save ( ) ;
req . flash ( 'success' , ` Domain ${ domain . name } updated successfully. ` ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-edit-domain' , domain . id ) ) ;
2020-07-30 10:58:51 +02:00
}
2020-07-27 16:02:09 +02:00
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). ` ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-edit-domain' , domain . id ) ) ;
2020-07-27 16:02:09 +02:00
return ;
}
await domain . delete ( ) ;
req . flash ( 'success' , ` Domain ${ domain . name } successfully deleted. ` ) ;
2021-01-25 18:04:11 +01:00
res . redirect ( Controller . route ( 'backend-mailboxes' ) ) ;
2020-07-27 16:02:09 +02:00
}
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.' ) ;
}
2020-11-02 19:27:18 +01:00
req . flash ( 'success' , 'Mail identity ' + await identity . toEmail ( ) + ' successfully created.' ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-mailbox' , user . id ) ) ;
2020-07-27 16:02:09 +02:00
}
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 ) ;
2021-03-01 13:29:30 +01:00
const user = identity . user . getOrFail ( ) ;
if ( ! user ) throw new NotFoundHttpError ( 'Mail identity owner' , req . url ) ;
if ( user . as ( UserMailIdentityComponent ) . main_mail_identity_id === identity . id ) {
2020-07-27 16:02:09 +02:00
req . flash ( 'error' , ` Cannot delete this user's mailbox identity. ` ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-mailbox' , user . id ) ) ;
2020-07-27 16:02:09 +02:00
return ;
}
await identity . delete ( ) ;
2020-11-02 19:27:18 +01:00
req . flash ( 'success' , 'Identity ' + await identity . toEmail ( ) + ' successfully deleted.' ) ;
2021-03-01 13:29:30 +01:00
res . redirect ( Controller . route ( 'backend-mailbox' , user . id ) ) ;
2020-07-27 16:02:09 +02:00
}
2021-03-01 13:43:29 +01:00
protected async postSetMainMailIdentity ( req : Request , res : Response ) : Promise < void > {
const identity = await MailIdentity . select ( )
. where ( 'id' , req . body . id )
. with ( 'user.mainMailIdentity' )
. first ( ) ;
if ( ! identity ) throw new NotFoundHttpError ( 'Mail identity' , req . url ) ;
const user = await identity . user . getOrFail ( ) ;
if ( ! user ) throw new NotFoundHttpError ( 'Mail identity owner' , req . url ) ;
const mailIdentityComponent = user . as ( UserMailIdentityComponent ) ;
const mainMailIdentity = mailIdentityComponent . mainMailIdentity . getOrFail ( ) ;
if ( ! mainMailIdentity ) throw new ServerError ( 'Could not find this users main mail identity.' ) ;
mailIdentityComponent . main_mail_identity_id = identity . id ;
await user . save ( ) ;
req . flash ( 'success' , 'User ' + user . id + ' main mail identity set to ' + await identity . toEmail ( ) ) ;
req . flash ( 'warning' , 'Please rename user\'s mailbox folder to correspond to changing from ' + await mainMailIdentity . toEmail ( ) + ' to ' + await identity . toEmail ( ) ) ;
res . redirect ( Controller . route ( 'backend-mailbox' , user . id ) ) ;
}
2020-11-02 18:59:35 +01:00
}