import express from "express"; import type { Express, NextFunction, Request, RequestHandler, Response } from "express"; import cors from "cors"; import helmet from "helmet"; import morgan from "morgan"; import rateLimit from "express-rate-limit"; import allowSetup from "../middleware/allowSetup"; import authenticate from "../middleware/authenticate"; import errorHandler from "../middleware/errorHandler"; import publicAvailable from "./public"; import setup from "./setup"; import invite from "./invite"; import reset from "./reset"; import auth from "./auth"; import admin from "./admin/index"; import user from "./user"; import detectPWA from "../middleware/detectPWA"; import webapi from "./webapi"; import authenticateAPI from "../middleware/authenticateAPI"; import server from "./server"; import PermissionHelper from "../helpers/permissionHelper"; import preventWebapiAccess from "../middleware/preventWebApiAccess"; import ms from "ms"; import { SECURITY_LIMIT_REQUEST_COUNT, SECURITY_LIMIT_WINDOW, SECURITY_STRICT_LIMIT_REQUEST_COUNT, SECURITY_STRICT_LIMIT_WINDOW, TRUST_PROXY, USE_SECURITY_LIMIT, USE_SECURITY_STRICT_LIMIT, } from "../env.defaults"; const strictLimiter = rateLimit({ windowMs: ms(SECURITY_STRICT_LIMIT_WINDOW), max: SECURITY_STRICT_LIMIT_REQUEST_COUNT, message: `Zu viele Anmeldeversuche innerhalb von ${SECURITY_STRICT_LIMIT_WINDOW}. Bitte warten.`, skipSuccessfulRequests: true, skip: () => { return USE_SECURITY_STRICT_LIMIT == "false"; }, }); const generalLimiter = rateLimit({ windowMs: ms(SECURITY_LIMIT_WINDOW), max: SECURITY_LIMIT_REQUEST_COUNT, message: `Zu viele Anfragen innerhalb von ${SECURITY_LIMIT_WINDOW}. Bitte warten.`, skipSuccessfulRequests: true, skip: () => { return USE_SECURITY_LIMIT == "false"; }, }); function excludePaths(middleware: RequestHandler, excludedPaths: Array) { return (req: Request, res: Response, next: NextFunction) => { if (excludedPaths.includes(req.path)) { return next(); } return middleware(req, res, next); }; } export default (app: Express) => { if (TRUST_PROXY) { app.set("trust proxy", TRUST_PROXY); } app.set("query parser", "extended"); app.use(cors()); app.options("*", cors()); app.use(helmet()); app.use(morgan("short")); app.use(express.json()); app.use( express.urlencoded({ extended: true, }) ); app.use(detectPWA); app.use("/api/public", publicAvailable); app.use("/api/setup", strictLimiter, preventWebapiAccess, allowSetup, setup); app.use("/api/reset", strictLimiter, preventWebapiAccess, reset); app.use("/api/invite", strictLimiter, preventWebapiAccess, invite); app.use("/api/auth", strictLimiter, preventWebapiAccess, auth); app.use("/api/webapi", authenticateAPI, webapi); app.use(authenticate); app.use(excludePaths(generalLimiter, ["/synchronize"])); app.use("/api/admin", admin); app.use("/api/user", preventWebapiAccess, user); app.use("/api/server", preventWebapiAccess, PermissionHelper.isAdminMiddleware(), server); app.use(errorHandler); };