94 lines
3 KiB
TypeScript
94 lines
3 KiB
TypeScript
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<string>) {
|
|
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);
|
|
};
|