import { AConfigChecker } from './src/AConfigChecker'; import * as express from 'express'; import { AddressInfo } from "net"; import * as path from 'path'; import * as bodyParser from 'body-parser'; import route_index from './routes/index'; import route_login from './routes/login'; import Security from './src/Security'; import { Session, SessionManager } from './src/Session'; import UserConnectorFactory from './src/UserConnector/UserConnectorFactory'; const debug = require('debug')('my express app'); const app = express(); declare global { namespace Express { interface Request { mSession: Session mCookies: Map } } } // Check config (_ => { let cc: AConfigChecker[] = [ UserConnectorFactory ]; for (let i of cc) { let err = i.CheckConfig(); if (err) { err = i.constructor.name + ": " + err; console.error("Configuration error: " + err); throw "Configuration error"; } } })(); // view engine setup app.set('views', [path.join(__dirname, 'views'), path.join(__dirname, 'views/template')]); app.set('view engine', 'pug'); app.use(express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // Security and session setup app.use((req, _, next) => { req.mCookies = new Map(); (req.headers?.cookie || "").split(";").forEach(i => { let keyValue = i.split("=", 2); req.mCookies.set(keyValue[0].trim(), keyValue[1].trim()); }); req.mSession = SessionManager.GetSession(req); if (req.mSession.IsValid()) req.mSession.Ping(); if (req.query["API_KEY"]) if (!Security.TryLoginApiKey(req.query["API_KEY"].toString())) { let err: any = new Error("Access denied"); err['status'] = 403; next(err); return; } next(); }); // Annonymous pages app.use('/', route_index); app.use('/login', route_login); // Login check app.use((req, res, next) => { if (!req.mSession.IsValid()) { const URL = '/login?redirect=' + encodeURIComponent(req.url); res.status(302); res.setHeader("Location", URL); res.send("" + URL + ""); } else { next(); } }); // Any following routes need login app.use('/logged', route_index); // catch 404 and forward to error handler app.use((_, __, next) => { const err: any = new Error('Not Found'); err['status'] = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use((err: any, req: Express.Request, res: any, next: any) => { // eslint-disable-line @typescript-eslint/no-unused-vars res.status(err['status'] || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use((err: any, _: any, res: any, __: any) => { // eslint-disable-line @typescript-eslint/no-unused-vars res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); app.set('port', process.env.port || 1337); const server = app.listen(app.get('port'), function () { debug(`Express server listening on port ${(server.address() as AddressInfo).port}`); });