perf: cache jwt secret as key

This commit is contained in:
Samuel 2023-03-17 17:47:43 +01:00
parent 5b6b97e86c
commit 810f5dd84c
3 changed files with 21 additions and 7 deletions

View File

@ -32,7 +32,7 @@ import "missing-native-js-functions";
import morgan from "morgan"; import morgan from "morgan";
import path from "path"; import path from "path";
import { red } from "picocolors"; import { red } from "picocolors";
import { Authentication, CORS } from "./middlewares/"; import { CORS, initAuthentication } from "./middlewares/";
import { BodyParser } from "./middlewares/BodyParser"; import { BodyParser } from "./middlewares/BodyParser";
import { ErrorHandler } from "./middlewares/ErrorHandler"; import { ErrorHandler } from "./middlewares/ErrorHandler";
import { initRateLimits } from "./middlewares/RateLimit"; import { initRateLimits } from "./middlewares/RateLimit";
@ -97,7 +97,7 @@ export class FosscordServer extends Server {
// @ts-ignore // @ts-ignore
this.app = api; this.app = api;
api.use(Authentication); initAuthentication(api);
await initRateLimits(api); await initRateLimits(api);
await initTranslation(api); await initTranslation(api);
@ -126,6 +126,10 @@ export class FosscordServer extends Server {
app.use("/api/v9", api); app.use("/api/v9", api);
app.use("/api", api); // allow unversioned requests app.use("/api", api); // allow unversioned requests
try {
require("./middlewares/TestClient").default(this.app);
// eslint-disable-next-line no-empty
} catch (error) {}
this.app.use(ErrorHandler); this.app.use(ErrorHandler);
Sentry.errorHandler(this.app); Sentry.errorHandler(this.app);

View File

@ -18,8 +18,9 @@
import { checkToken, Config, Rights } from "@fosscord/util"; import { checkToken, Config, Rights } from "@fosscord/util";
import * as Sentry from "@sentry/node"; import * as Sentry from "@sentry/node";
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response, Router } from "express";
import { HTTPError } from "lambert-server"; import { HTTPError } from "lambert-server";
import { createSecretKey, KeyObject } from "crypto";
export const NO_AUTHORIZATION_ROUTES = [ export const NO_AUTHORIZATION_ROUTES = [
// Authentication routes // Authentication routes
@ -69,6 +70,16 @@ declare global {
} }
} }
let jwtPublicKey: KeyObject;
// Initialize the jwt secret as a key object so it does not need to be regenerated for each request.
export function initAuthentication(api: Router) {
jwtPublicKey = createSecretKey(
Buffer.from(Config.get().security.jwtSecret),
);
api.use(Authentication);
}
export async function Authentication( export async function Authentication(
req: Request, req: Request,
res: Response, res: Response,
@ -90,11 +101,9 @@ export async function Authentication(
Sentry.setUser({ id: req.user_id }); Sentry.setUser({ id: req.user_id });
try { try {
const { jwtSecret } = Config.get().security;
const { decoded, user } = await checkToken( const { decoded, user } = await checkToken(
req.headers.authorization, req.headers.authorization,
jwtSecret, jwtPublicKey,
); );
req.token = decoded; req.token = decoded;

View File

@ -19,6 +19,7 @@
import jwt, { VerifyOptions } from "jsonwebtoken"; import jwt, { VerifyOptions } from "jsonwebtoken";
import { Config } from "./Config"; import { Config } from "./Config";
import { User } from "../entities"; import { User } from "../entities";
import { KeyObject } from "crypto";
export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] };
@ -62,7 +63,7 @@ async function checkEmailToken(
export function checkToken( export function checkToken(
token: string, token: string,
jwtSecret: string, jwtSecret: string | KeyObject,
isEmailVerification = false, isEmailVerification = false,
): Promise<UserTokenData> { ): Promise<UserTokenData> {
return new Promise((res, rej) => { return new Promise((res, rej) => {