ily.li/src/App.ts

162 lines
6.6 KiB
TypeScript

import Application from "wms-core/Application";
import {Type} from "wms-core/Utils";
import Migration from "wms-core/db/Migration";
import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable";
import CreateLogsTable from "wms-core/migrations/CreateLogsTable";
import ExpressAppComponent from "wms-core/components/ExpressAppComponent";
import NunjucksComponent from "wms-core/components/NunjucksComponent";
import MysqlComponent from "wms-core/components/MysqlComponent";
import LogRequestsComponent from "wms-core/components/LogRequestsComponent";
import RedisComponent from "wms-core/components/RedisComponent";
import ServeStaticDirectoryComponent from "wms-core/components/ServeStaticDirectoryComponent";
import MaintenanceComponent from "wms-core/components/MaintenanceComponent";
import MailComponent from "wms-core/components/MailComponent";
import SessionComponent from "wms-core/components/SessionComponent";
import FormHelperComponent from "wms-core/components/FormHelperComponent";
import CsrfProtectionComponent from "wms-core/components/CsrfProtectionComponent";
import WebSocketServerComponent from "wms-core/components/WebSocketServerComponent";
import AboutController from "./controllers/AboutController";
import AutoUpdateComponent from "wms-core/components/AutoUpdateComponent";
import AuthController from "./controllers/AuthController";
import MagicLinkWebSocketListener from "wms-core/auth/magic_link/MagicLinkWebSocketListener";
import MagicLinkController from "./controllers/MagicLinkController";
import MailController from "wms-core/auth/MailController";
import FileController from "./controllers/FileController";
import CreateUsersAndUserEmailsTable from "wms-core/auth/migrations/CreateUsersAndUserEmailsTable";
import CreateMagicLinksTable from "wms-core/auth/migrations/CreateMagicLinksTable";
import CreateAuthTokensTable from "./migrations/CreateAuthTokensTable";
import AuthComponent from "wms-core/auth/AuthComponent";
import AuthGuard from "wms-core/auth/AuthGuard";
import MagicLink from "wms-core/auth/models/MagicLink";
import AuthToken from "./models/AuthToken";
import {MagicLinkActionType} from "./controllers/MagicLinkActionType";
import {Request} from "express";
import CreateFilesTable from "./migrations/CreateFilesTable";
import IncreaseFilesSizeField from "./migrations/IncreaseFilesSizeField";
import AddApprovedFieldToUsersTable from "wms-core/auth/migrations/AddApprovedFieldToUsersTable";
import CreateUrlRedirectsTable from "./migrations/CreateUrlRedirectsTable";
import AuthTokenController from "./controllers/AuthTokenController";
import URLRedirectController from "./controllers/URLRedirectController";
import LinkController from "./controllers/LinkController";
import BackendController from "wms-core/helpers/BackendController";
import RedirectBackComponent from "wms-core/components/RedirectBackComponent";
import packageJson = require('../package.json');
export default class App extends Application {
public constructor(
private readonly addr: string,
private readonly port: number,
) {
super(packageJson.version);
}
protected getMigrations(): MigrationType<Migration>[] {
return [
CreateMigrationsTable,
CreateLogsTable,
CreateUsersAndUserEmailsTable,
CreateMagicLinksTable,
CreateAuthTokensTable,
CreateFilesTable,
IncreaseFilesSizeField,
AddApprovedFieldToUsersTable,
CreateUrlRedirectsTable,
];
}
protected async init(): Promise<void> {
this.registerComponents();
this.registerWebSocketListeners();
this.registerControllers();
}
private registerComponents() {
const redisComponent = new RedisComponent();
const mysqlComponent = new MysqlComponent();
const expressAppComponent = new ExpressAppComponent(this.addr, this.port);
this.use(expressAppComponent);
// Base
this.use(new LogRequestsComponent());
// Static files
this.use(new ServeStaticDirectoryComponent('public'));
this.use(new ServeStaticDirectoryComponent('node_modules/feather-icons/dist', '/icons'));
// Dynamic views and routes
this.use(new NunjucksComponent());
this.use(new RedirectBackComponent());
// Maintenance
this.use(new MaintenanceComponent(this, () => {
return redisComponent.canServe() && mysqlComponent.canServe();
}));
this.use(new AutoUpdateComponent());
// Services
this.use(mysqlComponent);
this.use(new MailComponent());
// Session
this.use(redisComponent);
this.use(new SessionComponent(redisComponent));
this.use(new AuthComponent(new class extends AuthGuard<MagicLink | AuthToken> {
public async getProofForSession(session: Express.Session): Promise<any | null> {
return await MagicLink.bySessionID(session.id, [MagicLinkActionType.LOGIN, MagicLinkActionType.REGISTER]);
}
public async getProofForRequest(req: Request): Promise<MagicLink | AuthToken | null> {
const authorization = req.header('Authorization');
if (authorization) {
const token = await AuthToken.select().where('secret', authorization).first();
if (token) {
token.use();
await token.save();
}
return token;
}
return super.getProofForRequest(req);
}
}));
// Utils
this.use(new FormHelperComponent());
// Middlewares
this.use(new CsrfProtectionComponent());
// WebSocket server
this.use(new WebSocketServerComponent(this, expressAppComponent, redisComponent));
}
private registerWebSocketListeners() {
this.magicLinkWebSocketListener = new MagicLinkWebSocketListener();
this.use(this.magicLinkWebSocketListener);
}
private registerControllers() {
// Multi-domain + vhost
this.use(new LinkController());
// Priority
this.use(new AuthController());
this.use(new MagicLinkController(this.magicLinkWebSocketListener!));
this.use(new BackendController());
// Core functionality
this.use(new MailController());
// Other functionality
this.use(new AuthTokenController());
// Semi-static
this.use(new AboutController());
// Global slug
this.use(new FileController());
this.use(new URLRedirectController());
}
}