misc: reorganized cron structure and removed unnecessary checks

This commit is contained in:
Sheen Capadngan
2024-06-14 00:58:54 +08:00
parent 4de63b6140
commit 44956c6a37
8 changed files with 27 additions and 29 deletions

View File

@@ -67,5 +67,3 @@ CLIENT_SECRET_GITLAB_LOGIN=
CAPTCHA_SECRET=
NEXT_PUBLIC_CAPTCHA_SITE_KEY=
ALLOW_RATELIMIT_UPDATES=

View File

@@ -43,7 +43,7 @@ export default {
const smtp = mockSmtpServer();
const queue = mockQueue();
const keyStore = mockKeyStore();
const { server } = await main({ db, smtp, logger, queue, keyStore });
const server = await main({ db, smtp, logger, queue, keyStore });
// @ts-expect-error type
globalThis.testServer = server;
// @ts-expect-error type

View File

@@ -6,7 +6,7 @@ import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.RateLimit))) {
await knex.schema.createTable(TableName.RateLimit, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo("00000000-0000-0000-0000-000000000000");
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.integer("readRateLimit").defaultTo(600).notNullable();
t.integer("writeRateLimit").defaultTo(200).notNullable();
t.integer("secretsRateLimit").defaultTo(60).notNullable();

View File

@@ -123,8 +123,7 @@ const envSchema = z
.optional(),
INFISICAL_CLOUD: zodStrBool.default("false"),
MAINTENANCE_MODE: zodStrBool.default("false"),
CAPTCHA_SECRET: zpStr(z.string().optional()),
ALLOW_RATELIMIT_UPDATES: zodStrBool.default("false")
CAPTCHA_SECRET: zpStr(z.string().optional())
})
.transform((data) => ({
...data,

View File

@@ -22,13 +22,12 @@ const run = async () => {
const queue = queueServiceFactory(appCfg.REDIS_URL);
const keyStore = keyStoreFactory(appCfg.REDIS_URL);
const { server, jobs } = await main({ db, smtp, logger, queue, keyStore });
const server = await main({ db, smtp, logger, queue, keyStore });
const bootstrap = await bootstrapCheck({ db });
// eslint-disable-next-line
process.on("SIGINT", async () => {
await server.close();
await db.destroy();
jobs.forEach((job) => job.stop());
process.exit(0);
});
@@ -36,7 +35,6 @@ const run = async () => {
process.on("SIGTERM", async () => {
await server.close();
await db.destroy();
jobs.forEach((job) => job.stop());
process.exit(0);
});

View File

@@ -10,7 +10,6 @@ import fastifyFormBody from "@fastify/formbody";
import helmet from "@fastify/helmet";
import type { FastifyRateLimitOptions } from "@fastify/rate-limit";
import ratelimiter from "@fastify/rate-limit";
import { CronJob } from "cron";
import fasitfy from "fastify";
import { Knex } from "knex";
import { Logger } from "pino";
@@ -42,7 +41,6 @@ type TMain = {
// Run the server!
export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
const appCfg = getConfig();
const cronJobs: CronJob[] = [];
const server = fasitfy({
logger: appCfg.NODE_ENV === "test" ? false : logger,
trustProxy: true,
@@ -76,11 +74,6 @@ export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
const rateLimitDAL = rateLimitDALFactory(db);
const rateLimitService = rateLimitServiceFactory({ rateLimitDAL });
const rateLimits = await rateLimitService.getRateLimits();
if (rateLimits) {
cronJobs.push(rateLimitService.initializeBackgroundSync());
}
await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg(rateLimits));
}
@@ -100,7 +93,7 @@ export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
await server.ready();
server.swagger();
return { server, jobs: cronJobs };
return server;
} catch (err) {
server.log.error(err);
await queue.shutdown();

View File

@@ -1,3 +1,4 @@
import { CronJob } from "cron";
import { Knex } from "knex";
import { z } from "zod";
@@ -907,6 +908,11 @@ export const registerRoutes = async (
secretSharing: secretSharingService
});
const cronJobs: CronJob[] = [];
if (appCfg.isProductionMode) {
cronJobs.push(rateLimitService.initializeBackgroundSync());
}
server.decorate<FastifyZodProvider["store"]>("store", {
user: userDAL
});
@@ -961,6 +967,7 @@ export const registerRoutes = async (
await server.register(registerV3Routes, { prefix: "/api/v3" });
server.addHook("onClose", async () => {
cronJobs.forEach((job) => job.stop());
await telemetryService.flushAll();
});
};

View File

@@ -1,7 +1,5 @@
import { CronJob } from "cron";
import { getConfig } from "@app/lib/config/env";
import { ForbiddenRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { rateLimitMaxConfiguration } from "@app/server/config/rateLimiter";
@@ -15,23 +13,28 @@ type TRateLimitServiceFactoryDep = {
export type TRateLimitServiceFactory = ReturnType<typeof rateLimitServiceFactory>;
export const rateLimitServiceFactory = ({ rateLimitDAL }: TRateLimitServiceFactoryDep) => {
const DEFAULT_RATE_LIMIT_CONFIG_ID = "00000000-0000-0000-0000-000000000000";
const getRateLimits = async (): Promise<TRateLimit | undefined> => {
let rateLimit: TRateLimit;
try {
return await rateLimitDAL.findOne({ id: "00000000-0000-0000-0000-000000000000" });
} catch (error) {
rateLimit = await rateLimitDAL.findOne({ id: DEFAULT_RATE_LIMIT_CONFIG_ID });
if (!rateLimit) {
// rate limit might not exist
rateLimit = await rateLimitDAL.create({
// @ts-expect-error id is kept as fixed because there should only be one rate limit config per instance
id: DEFAULT_RATE_LIMIT_CONFIG_ID
});
}
return rateLimit;
} catch (err) {
return undefined;
}
};
const updateRateLimit = async (updates: TRateLimitUpdateDTO): Promise<TRateLimit> => {
const appCfg = getConfig();
if (!appCfg.ALLOW_RATELIMIT_UPDATES) {
throw new ForbiddenRequestError({
name: "Rate limit Updates Disabled",
message: "Changes to rate limits are disabled"
});
}
return rateLimitDAL.updateById("00000000-0000-0000-0000-000000000000", updates);
return rateLimitDAL.updateById(DEFAULT_RATE_LIMIT_CONFIG_ID, updates);
};
const initializeBackgroundSync = () => {