Fix compiling errors following wms-core upgrade

This commit is contained in:
Alice Gaudon 2020-11-02 18:59:35 +01:00
parent f418008d78
commit f53dc7c63c
9 changed files with 79 additions and 75 deletions

View File

@ -24,7 +24,6 @@ import DummyMigration from "wms-core/migrations/DummyMigration";
import DropLegacyLogsTable from "wms-core/migrations/DropLegacyLogsTable";
import AccountController from "./controllers/AccountController";
import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable";
import CreateLogsTable from "wms-core/migrations/CreateLogsTable";
import CreateUsersAndUserEmailsTable from "wms-core/auth/migrations/CreateUsersAndUserEmailsTable";
import AddPasswordToUsers from "./migrations/AddPasswordToUsers";
import CreateMagicLinksTable from "wms-core/auth/migrations/CreateMagicLinksTable";
@ -43,7 +42,7 @@ import RedirectBackComponent from "wms-core/components/RedirectBackComponent";
import MailAutoConfigController from "./controllers/MailAutoConfigController";
export default class App extends Application {
private magicLinkWebSocketListener?: MagicLinkWebSocketListener;
private magicLinkWebSocketListener?: MagicLinkWebSocketListener<this>;
public constructor(
private readonly addr: string,
@ -56,7 +55,6 @@ export default class App extends Application {
return [
CreateMigrationsTable,
DummyMigration,
CreateLogsTable,
CreateUsersAndUserEmailsTable,
AddPasswordToUsers,
CreateMagicLinksTable,
@ -76,7 +74,6 @@ export default class App extends Application {
}
private registerComponents() {
const expressAppComponent = new ExpressAppComponent(this.port);
const redisComponent = new RedisComponent();
const mysqlComponent = new MysqlComponent();
@ -117,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);
MagicLink.bySessionId(session.id);
}
}));
@ -136,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.magicLinkWebSocketListener!));
this.use(new BackendController());
this.use(new MailboxBackendController());
this.use(new AuthController());

View File

@ -1,12 +1,12 @@
import ApplicationComponent from "wms-core/ApplicationComponent";
import {Express} from "express";
import ldap, {InvalidCredentialsError, Server} from "ldapjs";
import Logger from "wms-core/Logger";
import {log} from "wms-core/Logger";
import UserPasswordComponent from "./models/UserPasswordComponent";
import Throttler from "wms-core/Throttler";
import User from "wms-core/auth/models/User";
export default class LDAPServerComponent extends ApplicationComponent<void> {
export default class LDAPServerComponent extends ApplicationComponent {
private server?: Server;
public async start(app: Express): Promise<void> {
@ -25,12 +25,12 @@ export default class LDAPServerComponent extends ApplicationComponent<void> {
}
}
Logger.debug('Matrix authentication attempt:', username, email);
log.debug('Matrix authentication attempt:', username, email);
try {
Throttler.throttle('ldap_auth', 3, 30 * 1000, username);
} catch (e) {
Logger.debug('Too many auth requests');
log.debug('Too many auth requests');
next(new InvalidCredentialsError());
return;
}
@ -40,25 +40,25 @@ export default class LDAPServerComponent extends ApplicationComponent<void> {
const email = await user.mainEmail.get();
if (email) {
if (await user.as(UserPasswordComponent).verifyPassword(req.credentials)) {
Logger.debug('Success');
log.debug('Success');
res.end();
return;
}
}
}
Logger.debug('Fail');
log.debug('Fail');
next(new InvalidCredentialsError());
});
this.server.unbind((req: any, res: any, next: any) => {
Logger.debug('Unbind', req);
log.debug('Unbind', req);
next();
});
this.server.listen(8389, '127.0.0.1', () => {
Logger.info(`LDAP server listening on ${this.server!.url}`);
log.info(`LDAP server listening on ${this.server!.url}`);
});
this.server.on('close', () => {
Logger.info('LDAP server closed.');
log.info('LDAP server closed.');
});
}
@ -75,4 +75,4 @@ export default class LDAPServerComponent extends ApplicationComponent<void> {
}
});
}
}
}

View File

@ -1,9 +1,8 @@
import Controller from "wms-core/Controller";
import {REQUIRE_AUTH_MIDDLEWARE} from "wms-core/auth/AuthComponent";
import {RequireAuthMiddleware} from "wms-core/auth/AuthComponent";
import {NextFunction, Request, Response} from "express";
import {ADD_RECOVERY_EMAIL_MAIL_TEMPLATE} from "../Mails";
import Validator, {InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator";
import {EMAIL_REGEX} from "wms-core/db/Model";
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";
@ -20,17 +19,17 @@ export default class AccountController extends Controller {
}
routes(): void {
this.get('/', this.getAccount, 'account', REQUIRE_AUTH_MIDDLEWARE);
this.post('/add-recovery-email', this.addRecoveryEmail, 'add-recovery-email', REQUIRE_AUTH_MIDDLEWARE);
this.post('/set-main-email', this.postSetMainRecoveryEmail, 'set-main-recovery-email', REQUIRE_AUTH_MIDDLEWARE);
this.post('/remove-email', this.postRemoveRecoveryEmail, 'remove-recovery-email', REQUIRE_AUTH_MIDDLEWARE);
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);
this.post('/remove-email', this.postRemoveRecoveryEmail, 'remove-recovery-email', RequireAuthMiddleware);
this.post('/create-mail-identity', this.postCreateMailIdentity, 'create-mail-identity', REQUIRE_AUTH_MIDDLEWARE);
this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'delete-mail-identity', REQUIRE_AUTH_MIDDLEWARE);
this.post('/create-mail-identity', this.postCreateMailIdentity, 'create-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> {
const user = req.models.user!;
const user = req.as(RequireAuthMiddleware).getUser();
const userMailIdentity = user.as(UserMailIdentityComponent);
res.render('account', {
@ -86,16 +85,18 @@ export default class AccountController extends Controller {
if (!req.body.id)
throw new BadRequestError('Missing id field', 'Check form parameters.', req.url);
const user = req.as(RequireAuthMiddleware).getUser();
const userEmail = await UserEmail.getById(req.body.id);
if (!userEmail)
throw new NotFoundHttpError('email', req.url);
if (userEmail.user_id !== req.models.user!.id)
if (userEmail.user_id !== user.id)
throw new ForbiddenHttpError('email', req.url);
if (userEmail.id === req.models.user!.main_email_id)
if (userEmail.id === user.main_email_id)
throw new BadRequestError('This address is already your main address', 'Try refreshing the account page.', req.url);
req.models.user!.main_email_id = userEmail.id;
await req.models.user!.save();
user.main_email_id = userEmail.id;
await user.save();
req.flash('success', 'This email was successfully set as your main address.');
res.redirectBack();
@ -105,12 +106,14 @@ export default class AccountController extends Controller {
if (!req.body.id)
throw new BadRequestError('Missing id field', 'Check form parameters.', req.url);
const user = req.as(RequireAuthMiddleware).getUser();
const userEmail = await UserEmail.getById(req.body.id);
if (!userEmail)
throw new NotFoundHttpError('email', req.url);
if (userEmail.user_id !== req.models.user!.id)
if (userEmail.user_id !== user.id)
throw new ForbiddenHttpError('email', req.url);
if (userEmail.id === req.models.user!.main_email_id)
if (userEmail.id === user.main_email_id)
throw new BadRequestError('Cannot remove main email address', 'Try refreshing the account page.', req.url);
await userEmail.delete();
@ -123,7 +126,7 @@ export default class AccountController extends Controller {
const domain = await MailDomain.getById(req.body.mail_domain_id);
if (!domain) throw new NotFoundHttpError('domain', req.url);
const user = req.models.user!;
const user = req.as(RequireAuthMiddleware).getUser();
const mailIdentityComponent = user.as(UserMailIdentityComponent);
const identity = MailIdentity.create({
@ -163,10 +166,12 @@ export default class AccountController extends Controller {
}
protected async postDeleteMailIdentity(req: Request, res: Response): Promise<void> {
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 !== req.models.user!.id) throw new ForbiddenHttpError('mail identity', req.url);
if (req.models.user!.as(UserMailIdentityComponent).main_mail_identity_id === identity.id) {
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.redirectBack();
return;
@ -176,4 +181,4 @@ export default class AccountController extends Controller {
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.');
res.redirectBack();
}
}
}

View File

@ -1,5 +1,5 @@
import Controller from "wms-core/Controller";
import {REQUIRE_AUTH_MIDDLEWARE, REQUIRE_GUEST_MIDDLEWARE} from "wms-core/auth/AuthComponent";
import AuthComponent, {RequireAuthMiddleware, RequireGuestMiddleware} from "wms-core/auth/AuthComponent";
import {NextFunction, Request, Response} from "express";
import Validator, {InvalidFormatValidationError, ValidationBag} from "wms-core/db/Validator";
import UserPasswordComponent, {PasswordAuthProof} from "../models/UserPasswordComponent";
@ -12,11 +12,11 @@ import Throttler from "wms-core/Throttler";
export default class AuthController extends _AuthController {
routes(): void {
this.get('/login', this.getLogin, 'auth', REQUIRE_GUEST_MIDDLEWARE);
this.post('/login', this.postLogin, 'auth', REQUIRE_GUEST_MIDDLEWARE);
this.get('/register', this.getRegister, 'register', REQUIRE_GUEST_MIDDLEWARE);
this.post('/register', this.postRegister, 'register', REQUIRE_GUEST_MIDDLEWARE);
this.post('/logout', this.postLogout, 'logout', REQUIRE_AUTH_MIDDLEWARE);
this.get('/login', this.getLogin, 'auth', RequireGuestMiddleware);
this.post('/login', this.postLogin, 'auth', RequireGuestMiddleware);
this.get('/register', this.getRegister, 'register', RequireGuestMiddleware);
this.post('/register', this.postRegister, 'register', RequireGuestMiddleware);
this.post('/logout', this.postLogout, 'logout', RequireAuthMiddleware);
}
protected async getLogin(req: Request, res: Response): Promise<void> {
@ -40,7 +40,7 @@ export default class AuthController extends _AuthController {
await passwordAuthProof.authorize(req.body.password);
try {
await req.authGuard.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);
@ -82,7 +82,7 @@ export default class AuthController extends _AuthController {
const passwordAuthProof = PasswordAuthProof.createAuthorizedProofForRegistration(req.session!);
try {
await req.authGuard.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);
const callbacks: RegisterCallback[] = [];
@ -118,4 +118,4 @@ export default class AuthController extends _AuthController {
protected async postAuth(req: Request, res: Response, next: NextFunction): Promise<void> {
throw new ServerError('Not implemented.');
}
}
}

View File

@ -6,23 +6,26 @@ import {MagicLinkActionType} from "./MagicLinkActionType";
import Controller from "wms-core/Controller";
import {BadOwnerMagicLink} from "wms-core/auth/magic_link/MagicLinkAuthController";
import UserEmail from "wms-core/auth/models/UserEmail";
import App from "../App";
import AuthComponent from "wms-core/auth/AuthComponent";
export default class MagicLinkController extends _MagicLinkController {
constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener) {
export default class MagicLinkController extends _MagicLinkController<App> {
constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) {
super(magicLinkWebSocketListener);
}
protected async performAction(magicLink: MagicLink, req: Request, res: Response): Promise<void> {
switch (magicLink.getActionType()) {
switch (magicLink.action_type) {
case MagicLinkActionType.ADD_RECOVERY_EMAIL:
if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink();
if (magicLink.session_id !== req.sessionID!) throw new BadOwnerMagicLink();
await magicLink.delete();
const proof = await req.authGuard.isAuthenticated(req.session!);
const authGuard = this.getApp().as(AuthComponent).getAuthGuard();
const proof = await authGuard.isAuthenticated(req.session!);
const user = await proof?.getResource();
if (!user) break;
const email = await magicLink.getEmail();
const email = await magicLink.getOrFail('email');
// Existing email
if (await UserEmail.select().with('user').where('email', email).first()) {
@ -48,4 +51,4 @@ export default class MagicLinkController extends _MagicLinkController {
break;
}
}
}
}

View File

@ -1,5 +1,4 @@
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";
@ -9,6 +8,7 @@ import {NotFoundHttpError} from "wms-core/HttpError";
import MailDomain from "../models/MailDomain";
import BackendController from "wms-core/helpers/BackendController";
import MailIdentity from "../models/MailIdentity";
import {RequireAdminMiddleware, RequireAuthMiddleware} from "wms-core/auth/AuthComponent";
export default class MailboxBackendController extends Controller {
public constructor() {
@ -25,16 +25,16 @@ export default class MailboxBackendController extends Controller {
}
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.get('/', this.getMailboxesBackend, 'backend-mailboxes', RequireAuthMiddleware, RequireAdminMiddleware);
this.get('/:id', this.getMailboxBackend, 'backend-mailbox', RequireAuthMiddleware, RequireAdminMiddleware);
this.post('/add-domain', this.postAddDomain, 'backend-add-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
this.get('/edit-domain/:id', this.getEditDomain, 'backend-edit-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
this.post('/edit-domain/:id', this.postEditDomain, 'backend-edit-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
this.post('/remove-domain', this.postRemoveDomain, 'backend-remove-domain', REQUIRE_AUTH_MIDDLEWARE, REQUIRE_ADMIN_MIDDLEWARE);
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);
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);
this.post('/:id/create-mail-identity', this.postCreateMailIdentity, 'backend-create-mail-identity', RequireAuthMiddleware, RequireAdminMiddleware);
this.post('/delete-mail-identity', this.postDeleteMailIdentity, 'backend-delete-mail-identity', RequireAuthMiddleware, RequireAdminMiddleware);
}
protected async getMailboxesBackend(req: Request, res: Response): Promise<void> {
@ -204,4 +204,4 @@ export default class MailboxBackendController extends Controller {
req.flash('success', 'Identity ' + (await identity.toEmail()) + ' successfully deleted.');
res.redirectBack();
}
}
}

View File

@ -9,12 +9,12 @@ export default class MailDomain extends Model {
public name?: string = undefined;
public user_id?: number = undefined;
public readonly owner: OneModelRelation<MailDomain, User> = new OneModelRelation(this, ModelFactory.get(User), {
public readonly owner: OneModelRelation<MailDomain, User> = new OneModelRelation(this, User, {
localKey: 'user_id',
foreignKey: 'id',
});
public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, ModelFactory.get(MailIdentity), {
public readonly identities: ManyModelRelation<MailDomain, MailIdentity> = new ManyModelRelation(this, MailIdentity, {
localKey: 'id',
foreignKey: 'mail_domain_id',
});
@ -42,4 +42,4 @@ export default class MailDomain extends Model {
public canCreateAddresses(user: User): boolean {
return this.user_id === user.id || this.isPublic();
}
}
}

View File

@ -1,8 +1,8 @@
import Model, {EMAIL_REGEX} from "wms-core/db/Model";
import Model from "wms-core/db/Model";
import User from "wms-core/auth/models/User";
import MailDomain from "./MailDomain";
import {OneModelRelation} from "wms-core/db/ModelRelation";
import ModelFactory from "wms-core/db/ModelFactory";
import {EMAIL_REGEX} from "wms-core/db/Validator";
export default class MailIdentity extends Model {
public static get table(): string {
@ -15,11 +15,11 @@ export default class MailIdentity extends Model {
public name?: string = undefined;
public redirects_to?: string = undefined;
public readonly user: OneModelRelation<MailIdentity, User> = new OneModelRelation(this, ModelFactory.get(User), {
public readonly user: OneModelRelation<MailIdentity, User> = new OneModelRelation(this, User, {
foreignKey: 'id',
localKey: 'user_id',
});
public readonly domain: OneModelRelation<MailIdentity, MailDomain> = new OneModelRelation(this, ModelFactory.get(MailDomain), {
public readonly domain: OneModelRelation<MailIdentity, MailDomain> = new OneModelRelation(this, MailDomain, {
foreignKey: 'id',
localKey: 'mail_domain_id',
});
@ -35,4 +35,4 @@ export default class MailIdentity extends Model {
public async toEmail(): Promise<string> {
return this.name + '@' + (await this.domain.get())!.name;
}
}
}

View File

@ -2,25 +2,24 @@ import ModelComponent from "wms-core/db/ModelComponent";
import User from "wms-core/auth/models/User";
import {ManyModelRelation, OneModelRelation} from "wms-core/db/ModelRelation";
import MailIdentity from "./MailIdentity";
import ModelFactory from "wms-core/db/ModelFactory";
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, ModelFactory.get(MailIdentity), {
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());
public readonly mailDomains: ManyModelRelation<User, MailDomain> = new ManyModelRelation(this._model, ModelFactory.get(MailDomain), {
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, ModelFactory.get(MailIdentity), {
public readonly mainMailIdentity: OneModelRelation<User, MailIdentity> = new OneModelRelation(this._model, MailIdentity, {
foreignKey: 'id',
localKey: 'main_mail_identity_id',
});
@ -35,4 +34,4 @@ export default class UserMailIdentityComponent extends ModelComponent<User> {
public async getPublicAddressesCount(): Promise<number> {
return (await this.publicMailIdentities.get()).length;
}
}
}