Fix lint issues
This commit is contained in:
parent
f53dc7c63c
commit
3ed93dbefb
@ -1,11 +1,11 @@
|
||||
{
|
||||
"bundles": {
|
||||
"app": "ts/app.ts",
|
||||
"register": "js/register.js",
|
||||
"register": "ts/register.ts",
|
||||
"layout": "sass/layout.scss",
|
||||
"error": "sass/error.scss",
|
||||
"logo": "img/logo.svg",
|
||||
"logo_png": "img/logox128.png",
|
||||
"logo_png_xxl": "img/logox1024.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
41
assets/ts/register.ts
Normal 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();
|
||||
});
|
@ -114,7 +114,7 @@ export default class App extends Application {
|
||||
this.use(new AuthComponent(new class extends AuthGuard<PasswordAuthProof | MagicLink> {
|
||||
public async getProofForSession(session: Express.Session): Promise<PasswordAuthProof | MagicLink | null> {
|
||||
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() {
|
||||
// Priority routes / interrupting middlewares
|
||||
this.use(new AccountController());
|
||||
this.use(new MagicLinkController(this.magicLinkWebSocketListener!));
|
||||
this.use(new MagicLinkController(this.as(MagicLinkWebSocketListener)));
|
||||
this.use(new BackendController());
|
||||
this.use(new MailboxBackendController());
|
||||
this.use(new AuthController());
|
||||
|
@ -1,5 +1,4 @@
|
||||
import ApplicationComponent from "wms-core/ApplicationComponent";
|
||||
import {Express} from "express";
|
||||
import ldap, {InvalidCredentialsError, Server} from "ldapjs";
|
||||
import {log} from "wms-core/Logger";
|
||||
import UserPasswordComponent from "./models/UserPasswordComponent";
|
||||
@ -9,13 +8,13 @@ import User from "wms-core/auth/models/User";
|
||||
export default class LDAPServerComponent extends ApplicationComponent {
|
||||
private server?: Server;
|
||||
|
||||
public async start(app: Express): Promise<void> {
|
||||
public async start(): Promise<void> {
|
||||
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('='));
|
||||
let username;
|
||||
let username: string = '';
|
||||
let email;
|
||||
for (const rdn of rdns) {
|
||||
if (rdn[0] === 'cn') {
|
||||
@ -50,12 +49,12 @@ export default class LDAPServerComponent extends ApplicationComponent {
|
||||
log.debug('Fail');
|
||||
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);
|
||||
next();
|
||||
});
|
||||
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', () => {
|
||||
log.info('LDAP server closed.');
|
||||
@ -66,7 +65,6 @@ export default class LDAPServerComponent extends ApplicationComponent {
|
||||
public async stop(): Promise<void> {
|
||||
await new Promise(resolve => {
|
||||
if (this.server) {
|
||||
// @ts-ignore
|
||||
this.server.close(() => {
|
||||
resolve();
|
||||
});
|
||||
|
@ -3,4 +3,4 @@ import {MailTemplate} from "wms-core/Mail";
|
||||
export const ADD_RECOVERY_EMAIL_MAIL_TEMPLATE: MailTemplate = new MailTemplate(
|
||||
'add_recovery_email',
|
||||
(data) => 'Add ' + data.email + ' as you recovery email.',
|
||||
);
|
||||
);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import Controller from "wms-core/Controller";
|
||||
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 Validator, {EMAIL_REGEX, InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator";
|
||||
import MagicLinkController from "./MagicLinkController";
|
||||
import {MagicLinkActionType} from "./MagicLinkActionType";
|
||||
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 UserMailIdentityComponent from "../models/UserMailIdentityComponent";
|
||||
import MailIdentity from "../models/MailIdentity";
|
||||
@ -18,7 +18,7 @@ export default class AccountController extends Controller {
|
||||
return '/account';
|
||||
}
|
||||
|
||||
routes(): void {
|
||||
public routes(): void {
|
||||
this.get('/', this.getAccount, 'account', RequireAuthMiddleware);
|
||||
this.post('/add-recovery-email', this.addRecoveryEmail, 'add-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);
|
||||
}
|
||||
|
||||
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 userMailIdentity = user.as(UserMailIdentityComponent);
|
||||
|
||||
@ -40,7 +40,7 @@ export default class AccountController extends Controller {
|
||||
email: await identity.toEmail(),
|
||||
}))),
|
||||
domains: (await MailDomain.select()
|
||||
.where('user_id', user.id!)
|
||||
.where('user_id', user.id)
|
||||
.where('user_id', null, WhereTest.EQ, WhereOperator.OR)
|
||||
.sortBy('user_id', 'DESC')
|
||||
.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({
|
||||
email: new Validator().defined().regexp(EMAIL_REGEX),
|
||||
}, req.body);
|
||||
@ -67,13 +67,15 @@ export default class AccountController extends Controller {
|
||||
throw bag;
|
||||
}
|
||||
|
||||
if (!req.sessionID) throw new ServerError('Session not initialized.');
|
||||
|
||||
await MagicLinkController.sendMagicLink(
|
||||
req.sessionID!,
|
||||
req.sessionID,
|
||||
MagicLinkActionType.ADD_RECOVERY_EMAIL,
|
||||
Controller.route('account'),
|
||||
email,
|
||||
ADD_RECOVERY_EMAIL_MAIL_TEMPLATE,
|
||||
{}
|
||||
{},
|
||||
);
|
||||
|
||||
res.redirect(Controller.route('magic_link_lobby', undefined, {
|
||||
@ -140,7 +142,9 @@ export default class AccountController extends Controller {
|
||||
await this.validate({
|
||||
name: new Validator<string>().defined().equals(user.as(UserNameComponent).name),
|
||||
}, 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.');
|
||||
res.redirectBack();
|
||||
return;
|
||||
@ -161,7 +165,7 @@ export default class AccountController extends Controller {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -178,7 +182,7 @@ export default class AccountController extends Controller {
|
||||
}
|
||||
|
||||
await identity.delete();
|
||||
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.');
|
||||
req.flash('success', 'Identity ' + await identity.toEmail() + ' successfully deleted.');
|
||||
res.redirectBack();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Controller from "wms-core/Controller";
|
||||
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 UserPasswordComponent, {PasswordAuthProof} from "../models/UserPasswordComponent";
|
||||
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";
|
||||
|
||||
export default class AuthController extends _AuthController {
|
||||
routes(): void {
|
||||
public routes(): void {
|
||||
this.get('/login', this.getLogin, 'auth', RequireGuestMiddleware);
|
||||
this.post('/login', this.postLogin, 'auth', 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);
|
||||
|
||||
const passwordAuthProof = PasswordAuthProof.createProofForLogin(req.session!);
|
||||
if (!req.session) throw new ServerError('Session not initialized.');
|
||||
|
||||
const passwordAuthProof = PasswordAuthProof.createProofForLogin(req.session);
|
||||
passwordAuthProof.setResource(user);
|
||||
|
||||
await passwordAuthProof.authorize(req.body.password);
|
||||
try {
|
||||
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session!, passwordAuthProof);
|
||||
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session, passwordAuthProof);
|
||||
} catch (e) {
|
||||
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);
|
||||
|
||||
if (e instanceof PendingApprovalAuthError) {
|
||||
@ -54,7 +56,7 @@ export default class AuthController extends _AuthController {
|
||||
const bag = new ValidationBag();
|
||||
const err = new InvalidFormatValidationError('Invalid password.');
|
||||
err.thingName = 'password';
|
||||
bag.addMessage(err)
|
||||
bag.addMessage(err);
|
||||
throw bag;
|
||||
}
|
||||
} else {
|
||||
@ -80,21 +82,24 @@ export default class AuthController extends _AuthController {
|
||||
terms: new Validator().defined(),
|
||||
}, req.body);
|
||||
|
||||
const passwordAuthProof = PasswordAuthProof.createAuthorizedProofForRegistration(req.session!);
|
||||
if(!req.session) throw new ServerError('Session not initialized.');
|
||||
|
||||
const passwordAuthProof = PasswordAuthProof.createAuthorizedProofForRegistration(req.session);
|
||||
try {
|
||||
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session!, passwordAuthProof, undefined, async (connection, user) => {
|
||||
passwordAuthProof.setResource(user);
|
||||
await this.getApp().as(AuthComponent).getAuthGuard().authenticateOrRegister(req.session, passwordAuthProof,
|
||||
undefined, async (connection, user) => {
|
||||
passwordAuthProof.setResource(user);
|
||||
|
||||
const callbacks: RegisterCallback[] = [];
|
||||
const callbacks: RegisterCallback[] = [];
|
||||
|
||||
// Password
|
||||
await user.as(UserPasswordComponent).setPassword(req.body.password);
|
||||
// Password
|
||||
await user.as(UserPasswordComponent).setPassword(req.body.password);
|
||||
|
||||
// Username
|
||||
user.as(UserNameComponent).name = req.body.username;
|
||||
// Username
|
||||
user.as(UserNameComponent).name = req.body.username;
|
||||
|
||||
return callbacks;
|
||||
});
|
||||
return callbacks;
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof PendingApprovalAuthError) {
|
||||
req.flash('info', `Your account was successfully created and is pending review from an administrator.`);
|
||||
@ -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'));
|
||||
}
|
||||
|
||||
protected async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
protected async getCheckAuth(): Promise<void> {
|
||||
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.');
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
export enum MagicLinkActionType {
|
||||
ADD_RECOVERY_EMAIL = 'Add a recovery email',
|
||||
}
|
||||
}
|
||||
|
@ -10,45 +10,42 @@ import App from "../App";
|
||||
import AuthComponent from "wms-core/auth/AuthComponent";
|
||||
|
||||
export default class MagicLinkController extends _MagicLinkController<App> {
|
||||
constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) {
|
||||
public constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) {
|
||||
super(magicLinkWebSocketListener);
|
||||
}
|
||||
|
||||
protected async performAction(magicLink: MagicLink, req: Request, res: Response): Promise<void> {
|
||||
switch (magicLink.action_type) {
|
||||
case MagicLinkActionType.ADD_RECOVERY_EMAIL:
|
||||
if (magicLink.session_id !== req.sessionID!) throw new BadOwnerMagicLink();
|
||||
await magicLink.delete();
|
||||
if (magicLink.action_type === MagicLinkActionType.ADD_RECOVERY_EMAIL) {
|
||||
if (!req.session || !req.sessionID || magicLink.session_id !== req.sessionID) throw new BadOwnerMagicLink();
|
||||
|
||||
const authGuard = this.getApp().as(AuthComponent).getAuthGuard();
|
||||
const proof = await authGuard.isAuthenticated(req.session!);
|
||||
const user = await proof?.getResource();
|
||||
if (!user) break;
|
||||
await magicLink.delete();
|
||||
|
||||
const email = await magicLink.getOrFail('email');
|
||||
const authGuard = this.getApp().as(AuthComponent).getAuthGuard();
|
||||
const proof = await authGuard.isAuthenticated(req.session);
|
||||
const user = await proof?.getResource();
|
||||
if (!user) return;
|
||||
|
||||
// Existing email
|
||||
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.');
|
||||
res.redirect(Controller.route('account'));
|
||||
break;
|
||||
}
|
||||
|
||||
const userEmail = UserEmail.create({
|
||||
user_id: user.id,
|
||||
email: email,
|
||||
main: false,
|
||||
});
|
||||
await userEmail.save();
|
||||
|
||||
if (!user.main_email_id) {
|
||||
user.main_email_id = userEmail.id;
|
||||
await user.save();
|
||||
}
|
||||
|
||||
req.flash('success', `Recovery email ${userEmail.email} successfully added.`);
|
||||
const email = await magicLink.getOrFail('email');
|
||||
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.');
|
||||
res.redirect(Controller.route('account'));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
const userEmail = UserEmail.create({
|
||||
user_id: user.id,
|
||||
email: email,
|
||||
main: false,
|
||||
});
|
||||
await userEmail.save();
|
||||
|
||||
if (!user.main_email_id) {
|
||||
user.main_email_id = userEmail.id;
|
||||
await user.save();
|
||||
}
|
||||
|
||||
req.flash('success', `Recovery email ${userEmail.email} successfully added.`);
|
||||
res.redirect(Controller.route('account'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Controller from "wms-core/Controller";
|
||||
import {Request, Response} from "express";
|
||||
import config from "config";
|
||||
import MailDomain from "../models/MailDomain";
|
||||
|
||||
export default class MailAutoConfigController extends Controller {
|
||||
|
@ -80,16 +80,19 @@ export default class MailboxBackendController extends Controller {
|
||||
.first();
|
||||
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', {
|
||||
mailbox: {
|
||||
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,
|
||||
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,
|
||||
email: await i.toEmail(),
|
||||
}))),
|
||||
@ -182,7 +185,7 @@ export default class MailboxBackendController extends Controller {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -201,7 +204,7 @@ export default class MailboxBackendController extends Controller {
|
||||
}
|
||||
|
||||
await identity.delete();
|
||||
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.');
|
||||
req.flash('success', 'Identity ' + await identity.toEmail() + ' successfully deleted.');
|
||||
res.redirectBack();
|
||||
}
|
||||
}
|
||||
|
@ -18,4 +18,4 @@ export default class AddPasswordToUsers extends Migration {
|
||||
public registerModels(): void {
|
||||
ModelFactory.get(User).addComponent(UserPasswordComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,4 @@ export default class CreateMailTables extends Migration {
|
||||
ModelFactory.get(User).addComponent(UserMailIdentityComponent);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import Model from "wms-core/db/Model";
|
||||
import User from "wms-core/auth/models/User";
|
||||
import {ManyModelRelation, OneModelRelation} from "wms-core/db/ModelRelation";
|
||||
import ModelFactory from "wms-core/db/ModelFactory";
|
||||
import MailIdentity from "./MailIdentity";
|
||||
|
||||
export default class MailDomain extends Model {
|
||||
@ -14,13 +13,14 @@ export default class MailDomain extends Model {
|
||||
foreignKey: 'id',
|
||||
});
|
||||
|
||||
public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, MailIdentity, {
|
||||
localKey: 'id',
|
||||
foreignKey: 'mail_domain_id',
|
||||
});
|
||||
public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, MailIdentity,
|
||||
{
|
||||
localKey: 'id',
|
||||
foreignKey: 'mail_domain_id',
|
||||
});
|
||||
|
||||
|
||||
public updateWithData(data: any) {
|
||||
public updateWithData(data: Pick<this, keyof this> | Record<string, unknown>): void {
|
||||
super.updateWithData(data);
|
||||
if (typeof this.user_id !== 'undefined' && this.user_id <= 0) {
|
||||
this.user_id = undefined;
|
||||
|
@ -33,6 +33,6 @@ export default class MailIdentity extends Model {
|
||||
}
|
||||
|
||||
public async toEmail(): Promise<string> {
|
||||
return this.name + '@' + (await this.domain.get())!.name;
|
||||
return this.name + '@' + (await this.domain.getOrFail())?.name;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,24 @@ import MailDomain from "./MailDomain";
|
||||
export default class UserMailIdentityComponent extends ModelComponent<User> {
|
||||
public main_mail_identity_id?: number = undefined;
|
||||
|
||||
public readonly mailIdentities: ManyModelRelation<User, MailIdentity> = new ManyModelRelation(this._model, MailIdentity, {
|
||||
localKey: 'id',
|
||||
foreignKey: 'user_id',
|
||||
});
|
||||
public readonly mailIdentities: ManyModelRelation<User, MailIdentity> = new ManyModelRelation(this._model,
|
||||
MailIdentity, {
|
||||
localKey: 'id',
|
||||
foreignKey: 'user_id',
|
||||
});
|
||||
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, {
|
||||
localKey: 'id',
|
||||
foreignKey: 'user_id',
|
||||
});
|
||||
|
||||
public readonly mainMailIdentity: OneModelRelation<User, MailIdentity> = new OneModelRelation(this._model, MailIdentity, {
|
||||
foreignKey: 'id',
|
||||
localKey: 'main_mail_identity_id',
|
||||
});
|
||||
|
||||
protected init(): void {
|
||||
}
|
||||
public readonly mainMailIdentity: OneModelRelation<User, MailIdentity> = new OneModelRelation(this._model,
|
||||
MailIdentity, {
|
||||
foreignKey: 'id',
|
||||
localKey: 'main_mail_identity_id',
|
||||
});
|
||||
|
||||
public getMaxPublicAddressesCount(): number {
|
||||
return 1;
|
||||
|
@ -10,4 +10,4 @@ export default class UserNameComponent extends ModelComponent<User> {
|
||||
this.setValidation('name').defined().between(3, 64).regexp(USERNAME_REGEXP).unique(this._model);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,6 @@ import ModelComponent from "wms-core/db/ModelComponent";
|
||||
export default class UserPasswordComponent extends ModelComponent<User> {
|
||||
private password?: string = undefined;
|
||||
|
||||
public constructor(props: any) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
this.setValidation('password').acceptUndefined().maxLength(128);
|
||||
}
|
||||
@ -51,22 +47,22 @@ export class PasswordAuthProof implements AuthProof<User> {
|
||||
}
|
||||
|
||||
private readonly session: Express.Session;
|
||||
private userID: number | null;
|
||||
private userId: number | null;
|
||||
private authorized: boolean;
|
||||
private userPassword: UserPasswordComponent | null = null;
|
||||
|
||||
private constructor(session: Express.Session) {
|
||||
this.session = session;
|
||||
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> {
|
||||
return await User.getById(this.userID);
|
||||
return await User.getById(this.userId);
|
||||
}
|
||||
|
||||
public setResource(user: User) {
|
||||
this.userID = user.id!;
|
||||
public setResource(user: User): void {
|
||||
this.userId = user.getOrFail('id');
|
||||
this.save();
|
||||
}
|
||||
|
||||
@ -75,7 +71,7 @@ export class PasswordAuthProof implements AuthProof<User> {
|
||||
}
|
||||
|
||||
public async isValid(): Promise<boolean> {
|
||||
if (typeof this.userID === 'number') {
|
||||
if (typeof this.userId === 'number') {
|
||||
return Boolean(await this.getResource());
|
||||
} else {
|
||||
return await this.isAuthorized();
|
||||
@ -88,7 +84,7 @@ export class PasswordAuthProof implements AuthProof<User> {
|
||||
|
||||
private async getUserPassword(): Promise<UserPasswordComponent | null> {
|
||||
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;
|
||||
}
|
||||
@ -105,7 +101,7 @@ export class PasswordAuthProof implements AuthProof<User> {
|
||||
private save() {
|
||||
this.session.auth_password_proof = {
|
||||
authorized: this.authorized,
|
||||
userID: this.userID,
|
||||
userID: this.userId,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user