ff-admin-server/src/routes/index.ts

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);
};