Fix lint issues

This commit is contained in:
Alice Gaudon 2020-11-02 19:27:18 +01:00
parent f53dc7c63c
commit 3ed93dbefb
19 changed files with 159 additions and 144 deletions

View File

@ -1,7 +1,7 @@
{ {
"bundles": { "bundles": {
"app": "ts/app.ts", "app": "ts/app.ts",
"register": "js/register.js", "register": "ts/register.ts",
"layout": "sass/layout.scss", "layout": "sass/layout.scss",
"error": "sass/error.scss", "error": "sass/error.scss",
"logo": "img/logo.svg", "logo": "img/logo.svg",

View File

@ -1,27 +0,0 @@
document.addEventListener('DOMContentLoaded', () => {
const createEmailAddress = document.getElementById('field-create_email');
const username = document.getElementById('field-username');
const email_username = document.getElementById('email_username');
const domain = document.getElementById('field-domain');
const recovery_email = document.getElementById('field-recovery_email');
const recovery_email_label = recovery_email.parentElement.querySelector('.hint');
function updateForm() {
if (createEmailAddress.checked) {
recovery_email.removeAttribute('required');
recovery_email_label.style.display = 'block';
domain.disabled = false;
} else {
recovery_email.setAttribute('required', 'required');
recovery_email_label.style.display = 'none';
domain.disabled = true;
}
username.value = username.value.toLowerCase();
email_username.innerText = username.value + '@';
}
createEmailAddress.addEventListener('change', updateForm);
username.addEventListener('change', updateForm);
username.addEventListener('keyup', updateForm);
updateForm();
});

41
assets/ts/register.ts Normal file
View File

@ -0,0 +1,41 @@
document.addEventListener('DOMContentLoaded', () => {
const createEmailAddress = document.querySelector<HTMLInputElement>('#field-create_email');
const username = document.querySelector<HTMLInputElement>('#field-username');
const email_username = document.querySelector<HTMLElement>('#email_username');
const domain = document.querySelector<HTMLInputElement>('#field-domain');
const recovery_email = document.querySelector('#field-recovery_email');
const recovery_email_label = recovery_email?.parentElement?.querySelector<HTMLElement>('.hint');
if (
!createEmailAddress ||
!recovery_email ||
!recovery_email_label ||
!domain ||
!username ||
!email_username
) {
console.warn('Some elements wern\'t found.');
return;
}
const updateForm = () => {
if (createEmailAddress.checked) {
recovery_email.removeAttribute('required');
recovery_email_label.style.display = 'block';
domain.disabled = false;
} else {
recovery_email.setAttribute('required', 'required');
recovery_email_label.style.display = 'none';
domain.disabled = true;
}
username.value = username.value.toLowerCase();
email_username.innerText = username.value + '@';
};
createEmailAddress.addEventListener('change', updateForm);
username.addEventListener('change', updateForm);
username.addEventListener('keyup', updateForm);
updateForm();
});

View File

@ -114,7 +114,7 @@ export default class App extends Application {
this.use(new AuthComponent(new class extends AuthGuard<PasswordAuthProof | MagicLink> { this.use(new AuthComponent(new class extends AuthGuard<PasswordAuthProof | MagicLink> {
public async getProofForSession(session: Express.Session): Promise<PasswordAuthProof | MagicLink | null> { public async getProofForSession(session: Express.Session): Promise<PasswordAuthProof | MagicLink | null> {
return PasswordAuthProof.getProofForSession(session) || return PasswordAuthProof.getProofForSession(session) ||
MagicLink.bySessionId(session.id); await MagicLink.bySessionId(session.id);
} }
})); }));
@ -133,7 +133,7 @@ export default class App extends Application {
private registerControllers() { private registerControllers() {
// Priority routes / interrupting middlewares // Priority routes / interrupting middlewares
this.use(new AccountController()); this.use(new AccountController());
this.use(new MagicLinkController(this.magicLinkWebSocketListener!)); this.use(new MagicLinkController(this.as(MagicLinkWebSocketListener)));
this.use(new BackendController()); this.use(new BackendController());
this.use(new MailboxBackendController()); this.use(new MailboxBackendController());
this.use(new AuthController()); this.use(new AuthController());

View File

@ -1,5 +1,4 @@
import ApplicationComponent from "wms-core/ApplicationComponent"; import ApplicationComponent from "wms-core/ApplicationComponent";
import {Express} from "express";
import ldap, {InvalidCredentialsError, Server} from "ldapjs"; import ldap, {InvalidCredentialsError, Server} from "ldapjs";
import {log} from "wms-core/Logger"; import {log} from "wms-core/Logger";
import UserPasswordComponent from "./models/UserPasswordComponent"; import UserPasswordComponent from "./models/UserPasswordComponent";
@ -9,13 +8,13 @@ import User from "wms-core/auth/models/User";
export default class LDAPServerComponent extends ApplicationComponent { export default class LDAPServerComponent extends ApplicationComponent {
private server?: Server; private server?: Server;
public async start(app: Express): Promise<void> { public async start(): Promise<void> {
this.server = ldap.createServer({ this.server = ldap.createServer({
log: console log: console,
}); });
this.server.bind('ou=users,dc=toot,dc=party', async (req: any, res: any, next: any) => { this.server.bind('ou=users,dc=toot,dc=party', async (req: Record<string, string>, res: Record<string, () => void>, next: (err: unknown) => void) => {
const rdns = req.dn.toString().split(', ').map((rdn: string) => rdn.split('=')); const rdns = req.dn.toString().split(', ').map((rdn: string) => rdn.split('='));
let username; let username: string = '';
let email; let email;
for (const rdn of rdns) { for (const rdn of rdns) {
if (rdn[0] === 'cn') { if (rdn[0] === 'cn') {
@ -50,12 +49,12 @@ export default class LDAPServerComponent extends ApplicationComponent {
log.debug('Fail'); log.debug('Fail');
next(new InvalidCredentialsError()); next(new InvalidCredentialsError());
}); });
this.server.unbind((req: any, res: any, next: any) => { this.server.unbind((req: unknown, res: unknown, next: () => void) => {
log.debug('Unbind', req); log.debug('Unbind', req);
next(); next();
}); });
this.server.listen(8389, '127.0.0.1', () => { this.server.listen(8389, '127.0.0.1', () => {
log.info(`LDAP server listening on ${this.server!.url}`); log.info(`LDAP server listening on ${this.server?.url}`);
}); });
this.server.on('close', () => { this.server.on('close', () => {
log.info('LDAP server closed.'); log.info('LDAP server closed.');
@ -66,7 +65,6 @@ export default class LDAPServerComponent extends ApplicationComponent {
public async stop(): Promise<void> { public async stop(): Promise<void> {
await new Promise(resolve => { await new Promise(resolve => {
if (this.server) { if (this.server) {
// @ts-ignore
this.server.close(() => { this.server.close(() => {
resolve(); resolve();
}); });

View File

@ -1,12 +1,12 @@
import Controller from "wms-core/Controller"; import Controller from "wms-core/Controller";
import {RequireAuthMiddleware} from "wms-core/auth/AuthComponent"; import {RequireAuthMiddleware} from "wms-core/auth/AuthComponent";
import {NextFunction, Request, Response} from "express"; import {Request, Response} from "express";
import {ADD_RECOVERY_EMAIL_MAIL_TEMPLATE} from "../Mails"; import {ADD_RECOVERY_EMAIL_MAIL_TEMPLATE} from "../Mails";
import Validator, {EMAIL_REGEX, InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator"; import Validator, {EMAIL_REGEX, InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator";
import MagicLinkController from "./MagicLinkController"; import MagicLinkController from "./MagicLinkController";
import {MagicLinkActionType} from "./MagicLinkActionType"; import {MagicLinkActionType} from "./MagicLinkActionType";
import UserEmail from "wms-core/auth/models/UserEmail"; import UserEmail from "wms-core/auth/models/UserEmail";
import {BadRequestError, ForbiddenHttpError, NotFoundHttpError} from "wms-core/HttpError"; import {BadRequestError, ForbiddenHttpError, NotFoundHttpError, ServerError} from "wms-core/HttpError";
import MailDomain from "../models/MailDomain"; import MailDomain from "../models/MailDomain";
import UserMailIdentityComponent from "../models/UserMailIdentityComponent"; import UserMailIdentityComponent from "../models/UserMailIdentityComponent";
import MailIdentity from "../models/MailIdentity"; import MailIdentity from "../models/MailIdentity";
@ -18,7 +18,7 @@ export default class AccountController extends Controller {
return '/account'; return '/account';
} }
routes(): void { public routes(): void {
this.get('/', this.getAccount, 'account', RequireAuthMiddleware); this.get('/', this.getAccount, 'account', RequireAuthMiddleware);
this.post('/add-recovery-email', this.addRecoveryEmail, 'add-recovery-email', RequireAuthMiddleware); this.post('/add-recovery-email', this.addRecoveryEmail, 'add-recovery-email', RequireAuthMiddleware);
this.post('/set-main-email', this.postSetMainRecoveryEmail, 'set-main-recovery-email', RequireAuthMiddleware); this.post('/set-main-email', this.postSetMainRecoveryEmail, 'set-main-recovery-email', RequireAuthMiddleware);
@ -28,7 +28,7 @@ export default class AccountController extends Controller {
this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'delete-mail-identity', RequireAuthMiddleware); this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'delete-mail-identity', RequireAuthMiddleware);
} }
protected async getAccount(req: Request, res: Response, next: NextFunction): Promise<void> { protected async getAccount(req: Request, res: Response): Promise<void> {
const user = req.as(RequireAuthMiddleware).getUser(); const user = req.as(RequireAuthMiddleware).getUser();
const userMailIdentity = user.as(UserMailIdentityComponent); const userMailIdentity = user.as(UserMailIdentityComponent);
@ -40,7 +40,7 @@ export default class AccountController extends Controller {
email: await identity.toEmail(), email: await identity.toEmail(),
}))), }))),
domains: (await MailDomain.select() domains: (await MailDomain.select()
.where('user_id', user.id!) .where('user_id', user.id)
.where('user_id', null, WhereTest.EQ, WhereOperator.OR) .where('user_id', null, WhereTest.EQ, WhereOperator.OR)
.sortBy('user_id', 'DESC') .sortBy('user_id', 'DESC')
.get()) .get())
@ -51,7 +51,7 @@ export default class AccountController extends Controller {
}); });
} }
protected async addRecoveryEmail(req: Request, res: Response, next: NextFunction): Promise<void> { protected async addRecoveryEmail(req: Request, res: Response): Promise<void> {
await this.validate({ await this.validate({
email: new Validator().defined().regexp(EMAIL_REGEX), email: new Validator().defined().regexp(EMAIL_REGEX),
}, req.body); }, req.body);
@ -67,13 +67,15 @@ export default class AccountController extends Controller {
throw bag; throw bag;
} }
if (!req.sessionID) throw new ServerError('Session not initialized.');
await MagicLinkController.sendMagicLink( await MagicLinkController.sendMagicLink(
req.sessionID!, req.sessionID,
MagicLinkActionType.ADD_RECOVERY_EMAIL, MagicLinkActionType.ADD_RECOVERY_EMAIL,
Controller.route('account'), Controller.route('account'),
email, email,
ADD_RECOVERY_EMAIL_MAIL_TEMPLATE, ADD_RECOVERY_EMAIL_MAIL_TEMPLATE,
{} {},
); );
res.redirect(Controller.route('magic_link_lobby', undefined, { res.redirect(Controller.route('magic_link_lobby', undefined, {
@ -140,7 +142,9 @@ export default class AccountController extends Controller {
await this.validate({ await this.validate({
name: new Validator<string>().defined().equals(user.as(UserNameComponent).name), name: new Validator<string>().defined().equals(user.as(UserNameComponent).name),
}, req.body); }, req.body);
if ((await mailIdentityComponent.getPublicAddressesCount()) >= mailIdentityComponent.getMaxPublicAddressesCount()) { const actualPublicAddressesCount = await mailIdentityComponent.getPublicAddressesCount();
const maxPublicAddressesCount = mailIdentityComponent.getMaxPublicAddressesCount();
if (actualPublicAddressesCount >= maxPublicAddressesCount) {
req.flash('error', 'You have reached maximum public email addresses.'); req.flash('error', 'You have reached maximum public email addresses.');
res.redirectBack(); res.redirectBack();
return; return;
@ -161,7 +165,7 @@ export default class AccountController extends Controller {
req.flash('info', 'Congratulations! You just created your mailbox.'); req.flash('info', 'Congratulations! You just created your mailbox.');
} }
req.flash('success', 'Mail identity ' + (await identity.toEmail()) + ' successfully created.') req.flash('success', 'Mail identity ' + await identity.toEmail() + ' successfully created.');
res.redirectBack(); res.redirectBack();
} }
@ -178,7 +182,7 @@ export default class AccountController extends Controller {
} }
await identity.delete(); await identity.delete();
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.'); req.flash('success', 'Identity ' + await identity.toEmail() + ' successfully deleted.');
res.redirectBack(); res.redirectBack();
} }
} }

View File

@ -1,6 +1,6 @@
import Controller from "wms-core/Controller"; import Controller from "wms-core/Controller";
import AuthComponent, {RequireAuthMiddleware, RequireGuestMiddleware} from "wms-core/auth/AuthComponent"; import AuthComponent, {RequireAuthMiddleware, RequireGuestMiddleware} from "wms-core/auth/AuthComponent";
import {NextFunction, Request, Response} from "express"; import {Request, Response} from "express";
import Validator, {InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator"; import Validator, {InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator";
import UserPasswordComponent, {PasswordAuthProof} from "../models/UserPasswordComponent"; import UserPasswordComponent, {PasswordAuthProof} from "../models/UserPasswordComponent";
import UserNameComponent, {USERNAME_REGEXP} from "../models/UserNameComponent"; import UserNameComponent, {USERNAME_REGEXP} from "../models/UserNameComponent";
@ -11,7 +11,7 @@ import User from "wms-core/auth/models/User";
import Throttler from "wms-core/Throttler"; import Throttler from "wms-core/Throttler";
export default class AuthController extends _AuthController { export default class AuthController extends _AuthController {
routes(): void { public routes(): void {
this.get('/login', this.getLogin, 'auth', RequireGuestMiddleware); this.get('/login', this.getLogin, 'auth', RequireGuestMiddleware);
this.post('/login', this.postLogin, 'auth', RequireGuestMiddleware); this.post('/login', this.postLogin, 'auth', RequireGuestMiddleware);
this.get('/register', this.getRegister, 'register', RequireGuestMiddleware); this.get('/register', this.getRegister, 'register', RequireGuestMiddleware);
@ -35,15 +35,17 @@ export default class AuthController extends _AuthController {
if (!user) throw new NotFoundHttpError(`Couldn't find a user with name ${req.body.username}`, req.url); if (!user) throw new NotFoundHttpError(`Couldn't find a user with name ${req.body.username}`, req.url);
const passwordAuthProof = PasswordAuthProof.createProofForLogin(req.session!); if (!req.session) throw new ServerError('Session not initialized.');
const passwordAuthProof = PasswordAuthProof.createProofForLogin(req.session);
passwordAuthProof.setResource(user); passwordAuthProof.setResource(user);
await passwordAuthProof.authorize(req.body.password); await passwordAuthProof.authorize(req.body.password);
try { try {
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session!, passwordAuthProof); await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session, passwordAuthProof);
} catch (e) { } catch (e) {
if (e instanceof AuthError) { if (e instanceof AuthError) {
Throttler.throttle('login_failed_attempts_user', 3, 180000, user.as(UserNameComponent).name!, 1000, 60000); Throttler.throttle('login_failed_attempts_user', 3, 180000, <string>user.getOrFail('name'), 1000, 60000);
Throttler.throttle('login_failed_attempts_ip', 5, 60000, req.ip, 1000, 60000); Throttler.throttle('login_failed_attempts_ip', 5, 60000, req.ip, 1000, 60000);
if (e instanceof PendingApprovalAuthError) { if (e instanceof PendingApprovalAuthError) {
@ -54,7 +56,7 @@ export default class AuthController extends _AuthController {
const bag = new ValidationBag(); const bag = new ValidationBag();
const err = new InvalidFormatValidationError('Invalid password.'); const err = new InvalidFormatValidationError('Invalid password.');
err.thingName = 'password'; err.thingName = 'password';
bag.addMessage(err) bag.addMessage(err);
throw bag; throw bag;
} }
} else { } else {
@ -80,9 +82,12 @@ export default class AuthController extends _AuthController {
terms: new Validator().defined(), terms: new Validator().defined(),
}, req.body); }, req.body);
const passwordAuthProof = PasswordAuthProof.createAuthorizedProofForRegistration(req.session!); if(!req.session) throw new ServerError('Session not initialized.');
const passwordAuthProof = PasswordAuthProof.createAuthorizedProofForRegistration(req.session);
try { try {
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session!, passwordAuthProof, undefined, async (connection, user) => { await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session, passwordAuthProof,
undefined, async (connection, user) => {
passwordAuthProof.setResource(user); passwordAuthProof.setResource(user);
const callbacks: RegisterCallback[] = []; const callbacks: RegisterCallback[] = [];
@ -105,17 +110,17 @@ export default class AuthController extends _AuthController {
} }
} }
const user = (await passwordAuthProof.getResource())!; const user = await passwordAuthProof.getResource();
req.flash('success', `Your account was successfully created! Welcome, ${user.as(UserNameComponent).name}.`); req.flash('success', `Your account was successfully created! Welcome, ${user?.as(UserNameComponent).name}.`);
res.redirect(Controller.route('home')); res.redirect(Controller.route('home'));
} }
protected async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise<void> { protected async getCheckAuth(): Promise<void> {
throw new ServerError('Not implemented.'); throw new ServerError('Not implemented.');
} }
protected async postAuth(req: Request, res: Response, next: NextFunction): Promise<void> { protected async postAuth(): Promise<void> {
throw new ServerError('Not implemented.'); throw new ServerError('Not implemented.');
} }
} }

View File

@ -10,28 +10,26 @@ import App from "../App";
import AuthComponent from "wms-core/auth/AuthComponent"; import AuthComponent from "wms-core/auth/AuthComponent";
export default class MagicLinkController extends _MagicLinkController<App> { export default class MagicLinkController extends _MagicLinkController<App> {
constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) { public constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) {
super(magicLinkWebSocketListener); super(magicLinkWebSocketListener);
} }
protected async performAction(magicLink: MagicLink, req: Request, res: Response): Promise<void> { protected async performAction(magicLink: MagicLink, req: Request, res: Response): Promise<void> {
switch (magicLink.action_type) { if (magicLink.action_type === MagicLinkActionType.ADD_RECOVERY_EMAIL) {
case MagicLinkActionType.ADD_RECOVERY_EMAIL: if (!req.session || !req.sessionID || magicLink.session_id !== req.sessionID) throw new BadOwnerMagicLink();
if (magicLink.session_id !== req.sessionID!) throw new BadOwnerMagicLink();
await magicLink.delete(); await magicLink.delete();
const authGuard = this.getApp().as(AuthComponent).getAuthGuard(); const authGuard = this.getApp().as(AuthComponent).getAuthGuard();
const proof = await authGuard.isAuthenticated(req.session!); const proof = await authGuard.isAuthenticated(req.session);
const user = await proof?.getResource(); const user = await proof?.getResource();
if (!user) break; if (!user) return;
const email = await magicLink.getOrFail('email'); const email = await magicLink.getOrFail('email');
// Existing email
if (await UserEmail.select().with('user').where('email', email).first()) { if (await UserEmail.select().with('user').where('email', email).first()) {
req.flash('error', 'An account already exists with this email address. Please first remove it there before adding it here.'); req.flash('error', 'An account already exists with this email address. Please first remove it there before adding it here.');
res.redirect(Controller.route('account')); res.redirect(Controller.route('account'));
break; return;
} }
const userEmail = UserEmail.create({ const userEmail = UserEmail.create({
@ -48,7 +46,6 @@ export default class MagicLinkController extends _MagicLinkController<App> {
req.flash('success', `Recovery email ${userEmail.email} successfully added.`); req.flash('success', `Recovery email ${userEmail.email} successfully added.`);
res.redirect(Controller.route('account')); res.redirect(Controller.route('account'));
break;
} }
} }
} }

View File

@ -1,6 +1,5 @@
import Controller from "wms-core/Controller"; import Controller from "wms-core/Controller";
import {Request, Response} from "express"; import {Request, Response} from "express";
import config from "config";
import MailDomain from "../models/MailDomain"; import MailDomain from "../models/MailDomain";
export default class MailAutoConfigController extends Controller { export default class MailAutoConfigController extends Controller {

View File

@ -80,16 +80,19 @@ export default class MailboxBackendController extends Controller {
.first(); .first();
if (!user) throw new NotFoundHttpError('User', req.url); if (!user) throw new NotFoundHttpError('User', req.url);
const mainMailIdentity = await user.as(UserMailIdentityComponent).mainMailIdentity.get();
const mailDomains = await MailDomain.select().get();
const mailIdentities = await user.as(UserMailIdentityComponent).mailIdentities.get();
res.render('backend/mailbox', { res.render('backend/mailbox', {
mailbox: { mailbox: {
id: user.id, id: user.id,
name: await (await user.as(UserMailIdentityComponent).mainMailIdentity.get())?.toEmail() || 'Not created.', name: await mainMailIdentity?.toEmail() || 'Not created.',
}, },
domains: (await MailDomain.select().get()).map(d => ({ domains: mailDomains.map(d => ({
display: d.name, display: d.name,
value: d.id, value: d.id,
})), })),
identities: await Promise.all((await user.as(UserMailIdentityComponent).mailIdentities.get()).map(async i => ({ identities: await Promise.all(mailIdentities.map(async i => ({
id: i.id, id: i.id,
email: await i.toEmail(), email: await i.toEmail(),
}))), }))),
@ -182,7 +185,7 @@ export default class MailboxBackendController extends Controller {
req.flash('info', 'Mailbox created.'); req.flash('info', 'Mailbox created.');
} }
req.flash('success', 'Mail identity ' + (await identity.toEmail()) + ' successfully created.') req.flash('success', 'Mail identity ' + await identity.toEmail() + ' successfully created.');
res.redirectBack(); res.redirectBack();
} }
@ -201,7 +204,7 @@ export default class MailboxBackendController extends Controller {
} }
await identity.delete(); await identity.delete();
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.'); req.flash('success', 'Identity ' + await identity.toEmail() + ' successfully deleted.');
res.redirectBack(); res.redirectBack();
} }
} }

View File

@ -1,7 +1,6 @@
import Model from "wms-core/db/Model"; import Model from "wms-core/db/Model";
import User from "wms-core/auth/models/User"; import User from "wms-core/auth/models/User";
import {ManyModelRelation, OneModelRelation} from "wms-core/db/ModelRelation"; import {ManyModelRelation, OneModelRelation} from "wms-core/db/ModelRelation";
import ModelFactory from "wms-core/db/ModelFactory";
import MailIdentity from "./MailIdentity"; import MailIdentity from "./MailIdentity";
export default class MailDomain extends Model { export default class MailDomain extends Model {
@ -14,13 +13,14 @@ export default class MailDomain extends Model {
foreignKey: 'id', foreignKey: 'id',
}); });
public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, MailIdentity, { public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, MailIdentity,
{
localKey: 'id', localKey: 'id',
foreignKey: 'mail_domain_id', foreignKey: 'mail_domain_id',
}); });
public updateWithData(data: any) { public updateWithData(data: Pick<this, keyof this> | Record<string, unknown>): void {
super.updateWithData(data); super.updateWithData(data);
if (typeof this.user_id !== 'undefined' && this.user_id <= 0) { if (typeof this.user_id !== 'undefined' && this.user_id <= 0) {
this.user_id = undefined; this.user_id = undefined;

View File

@ -33,6 +33,6 @@ export default class MailIdentity extends Model {
} }
public async toEmail(): Promise<string> { public async toEmail(): Promise<string> {
return this.name + '@' + (await this.domain.get())!.name; return this.name + '@' + (await this.domain.getOrFail())?.name;
} }
} }

View File

@ -7,26 +7,25 @@ import MailDomain from "./MailDomain";
export default class UserMailIdentityComponent extends ModelComponent<User> { export default class UserMailIdentityComponent extends ModelComponent<User> {
public main_mail_identity_id?: number = undefined; public main_mail_identity_id?: number = undefined;
public readonly mailIdentities: ManyModelRelation<User, MailIdentity> = new ManyModelRelation(this._model, MailIdentity, { public readonly mailIdentities: ManyModelRelation<User, MailIdentity> = new ManyModelRelation(this._model,
MailIdentity, {
localKey: 'id', localKey: 'id',
foreignKey: 'user_id', foreignKey: 'user_id',
}); });
public readonly publicMailIdentities: ManyModelRelation<User, MailIdentity> = this.mailIdentities.clone() public readonly publicMailIdentities: ManyModelRelation<User, MailIdentity> = this.mailIdentities.clone()
.filter(async model => (await model.domain.get())!.isPublic()); .filter(async model => !!(await model.domain.getOrFail())?.isPublic());
public readonly mailDomains: ManyModelRelation<User, MailDomain> = new ManyModelRelation(this._model, MailDomain, { public readonly mailDomains: ManyModelRelation<User, MailDomain> = new ManyModelRelation(this._model, MailDomain, {
localKey: 'id', localKey: 'id',
foreignKey: 'user_id', foreignKey: 'user_id',
}); });
public readonly mainMailIdentity: OneModelRelation<User, MailIdentity> = new OneModelRelation(this._model, MailIdentity, { public readonly mainMailIdentity: OneModelRelation<User, MailIdentity> = new OneModelRelation(this._model,
MailIdentity, {
foreignKey: 'id', foreignKey: 'id',
localKey: 'main_mail_identity_id', localKey: 'main_mail_identity_id',
}); });
protected init(): void {
}
public getMaxPublicAddressesCount(): number { public getMaxPublicAddressesCount(): number {
return 1; return 1;
} }

View File

@ -7,10 +7,6 @@ import ModelComponent from "wms-core/db/ModelComponent";
export default class UserPasswordComponent extends ModelComponent<User> { export default class UserPasswordComponent extends ModelComponent<User> {
private password?: string = undefined; private password?: string = undefined;
public constructor(props: any) {
super(props);
}
public init(): void { public init(): void {
this.setValidation('password').acceptUndefined().maxLength(128); this.setValidation('password').acceptUndefined().maxLength(128);
} }
@ -51,22 +47,22 @@ export class PasswordAuthProof implements AuthProof<User> {
} }
private readonly session: Express.Session; private readonly session: Express.Session;
private userID: number | null; private userId: number | null;
private authorized: boolean; private authorized: boolean;
private userPassword: UserPasswordComponent | null = null; private userPassword: UserPasswordComponent | null = null;
private constructor(session: Express.Session) { private constructor(session: Express.Session) {
this.session = session; this.session = session;
this.authorized = session.auth_password_proof?.authorized || false; this.authorized = session.auth_password_proof?.authorized || false;
this.userID = session.auth_password_proof?.userID || null; this.userId = session.auth_password_proof?.userId || null;
} }
public async getResource(): Promise<User | null> { public async getResource(): Promise<User | null> {
return await User.getById(this.userID); return await User.getById(this.userId);
} }
public setResource(user: User) { public setResource(user: User): void {
this.userID = user.id!; this.userId = user.getOrFail('id');
this.save(); this.save();
} }
@ -75,7 +71,7 @@ export class PasswordAuthProof implements AuthProof<User> {
} }
public async isValid(): Promise<boolean> { public async isValid(): Promise<boolean> {
if (typeof this.userID === 'number') { if (typeof this.userId === 'number') {
return Boolean(await this.getResource()); return Boolean(await this.getResource());
} else { } else {
return await this.isAuthorized(); return await this.isAuthorized();
@ -88,7 +84,7 @@ export class PasswordAuthProof implements AuthProof<User> {
private async getUserPassword(): Promise<UserPasswordComponent | null> { private async getUserPassword(): Promise<UserPasswordComponent | null> {
if (!this.userPassword) { if (!this.userPassword) {
this.userPassword = (await User.getById(this.userID))?.as(UserPasswordComponent) || null; this.userPassword = (await User.getById(this.userId))?.as(UserPasswordComponent) || null;
} }
return this.userPassword; return this.userPassword;
} }
@ -105,7 +101,7 @@ export class PasswordAuthProof implements AuthProof<User> {
private save() { private save() {
this.session.auth_password_proof = { this.session.auth_password_proof = {
authorized: this.authorized, authorized: this.authorized,
userID: this.userID, userID: this.userId,
}; };
} }
} }