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
-2
View File
@@ -67,5 +67,3 @@ CLIENT_SECRET_GITLAB_LOGIN=
CAPTCHA_SECRET= CAPTCHA_SECRET=
NEXT_PUBLIC_CAPTCHA_SITE_KEY= NEXT_PUBLIC_CAPTCHA_SITE_KEY=
ALLOW_RATELIMIT_UPDATES=
+1 -1
View File
@@ -43,7 +43,7 @@ export default {
const smtp = mockSmtpServer(); const smtp = mockSmtpServer();
const queue = mockQueue(); const queue = mockQueue();
const keyStore = mockKeyStore(); 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 // @ts-expect-error type
globalThis.testServer = server; globalThis.testServer = server;
// @ts-expect-error type // @ts-expect-error type
@@ -6,7 +6,7 @@ import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> { export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.RateLimit))) { if (!(await knex.schema.hasTable(TableName.RateLimit))) {
await knex.schema.createTable(TableName.RateLimit, (t) => { 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("readRateLimit").defaultTo(600).notNullable();
t.integer("writeRateLimit").defaultTo(200).notNullable(); t.integer("writeRateLimit").defaultTo(200).notNullable();
t.integer("secretsRateLimit").defaultTo(60).notNullable(); t.integer("secretsRateLimit").defaultTo(60).notNullable();
+1 -2
View File
@@ -123,8 +123,7 @@ const envSchema = z
.optional(), .optional(),
INFISICAL_CLOUD: zodStrBool.default("false"), INFISICAL_CLOUD: zodStrBool.default("false"),
MAINTENANCE_MODE: zodStrBool.default("false"), MAINTENANCE_MODE: zodStrBool.default("false"),
CAPTCHA_SECRET: zpStr(z.string().optional()), CAPTCHA_SECRET: zpStr(z.string().optional())
ALLOW_RATELIMIT_UPDATES: zodStrBool.default("false")
}) })
.transform((data) => ({ .transform((data) => ({
...data, ...data,
+1 -3
View File
@@ -22,13 +22,12 @@ const run = async () => {
const queue = queueServiceFactory(appCfg.REDIS_URL); const queue = queueServiceFactory(appCfg.REDIS_URL);
const keyStore = keyStoreFactory(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 }); const bootstrap = await bootstrapCheck({ db });
// eslint-disable-next-line // eslint-disable-next-line
process.on("SIGINT", async () => { process.on("SIGINT", async () => {
await server.close(); await server.close();
await db.destroy(); await db.destroy();
jobs.forEach((job) => job.stop());
process.exit(0); process.exit(0);
}); });
@@ -36,7 +35,6 @@ const run = async () => {
process.on("SIGTERM", async () => { process.on("SIGTERM", async () => {
await server.close(); await server.close();
await db.destroy(); await db.destroy();
jobs.forEach((job) => job.stop());
process.exit(0); process.exit(0);
}); });
+1 -8
View File
@@ -10,7 +10,6 @@ import fastifyFormBody from "@fastify/formbody";
import helmet from "@fastify/helmet"; import helmet from "@fastify/helmet";
import type { FastifyRateLimitOptions } from "@fastify/rate-limit"; import type { FastifyRateLimitOptions } from "@fastify/rate-limit";
import ratelimiter from "@fastify/rate-limit"; import ratelimiter from "@fastify/rate-limit";
import { CronJob } from "cron";
import fasitfy from "fastify"; import fasitfy from "fastify";
import { Knex } from "knex"; import { Knex } from "knex";
import { Logger } from "pino"; import { Logger } from "pino";
@@ -42,7 +41,6 @@ type TMain = {
// Run the server! // Run the server!
export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => { export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
const appCfg = getConfig(); const appCfg = getConfig();
const cronJobs: CronJob[] = [];
const server = fasitfy({ const server = fasitfy({
logger: appCfg.NODE_ENV === "test" ? false : logger, logger: appCfg.NODE_ENV === "test" ? false : logger,
trustProxy: true, trustProxy: true,
@@ -76,11 +74,6 @@ export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
const rateLimitDAL = rateLimitDALFactory(db); const rateLimitDAL = rateLimitDALFactory(db);
const rateLimitService = rateLimitServiceFactory({ rateLimitDAL }); const rateLimitService = rateLimitServiceFactory({ rateLimitDAL });
const rateLimits = await rateLimitService.getRateLimits(); const rateLimits = await rateLimitService.getRateLimits();
if (rateLimits) {
cronJobs.push(rateLimitService.initializeBackgroundSync());
}
await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg(rateLimits)); await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg(rateLimits));
} }
@@ -100,7 +93,7 @@ export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
await server.ready(); await server.ready();
server.swagger(); server.swagger();
return { server, jobs: cronJobs }; return server;
} catch (err) { } catch (err) {
server.log.error(err); server.log.error(err);
await queue.shutdown(); await queue.shutdown();
+7
View File
@@ -1,3 +1,4 @@
import { CronJob } from "cron";
import { Knex } from "knex"; import { Knex } from "knex";
import { z } from "zod"; import { z } from "zod";
@@ -907,6 +908,11 @@ export const registerRoutes = async (
secretSharing: secretSharingService secretSharing: secretSharingService
}); });
const cronJobs: CronJob[] = [];
if (appCfg.isProductionMode) {
cronJobs.push(rateLimitService.initializeBackgroundSync());
}
server.decorate<FastifyZodProvider["store"]>("store", { server.decorate<FastifyZodProvider["store"]>("store", {
user: userDAL user: userDAL
}); });
@@ -961,6 +967,7 @@ export const registerRoutes = async (
await server.register(registerV3Routes, { prefix: "/api/v3" }); await server.register(registerV3Routes, { prefix: "/api/v3" });
server.addHook("onClose", async () => { server.addHook("onClose", async () => {
cronJobs.forEach((job) => job.stop());
await telemetryService.flushAll(); await telemetryService.flushAll();
}); });
}; };
@@ -1,7 +1,5 @@
import { CronJob } from "cron"; import { CronJob } from "cron";
import { getConfig } from "@app/lib/config/env";
import { ForbiddenRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { rateLimitMaxConfiguration } from "@app/server/config/rateLimiter"; import { rateLimitMaxConfiguration } from "@app/server/config/rateLimiter";
@@ -15,23 +13,28 @@ type TRateLimitServiceFactoryDep = {
export type TRateLimitServiceFactory = ReturnType<typeof rateLimitServiceFactory>; export type TRateLimitServiceFactory = ReturnType<typeof rateLimitServiceFactory>;
export const rateLimitServiceFactory = ({ rateLimitDAL }: TRateLimitServiceFactoryDep) => { export const rateLimitServiceFactory = ({ rateLimitDAL }: TRateLimitServiceFactoryDep) => {
const DEFAULT_RATE_LIMIT_CONFIG_ID = "00000000-0000-0000-0000-000000000000";
const getRateLimits = async (): Promise<TRateLimit | undefined> => { const getRateLimits = async (): Promise<TRateLimit | undefined> => {
let rateLimit: TRateLimit;
try { try {
return await rateLimitDAL.findOne({ id: "00000000-0000-0000-0000-000000000000" }); rateLimit = await rateLimitDAL.findOne({ id: DEFAULT_RATE_LIMIT_CONFIG_ID });
} catch (error) { 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; return undefined;
} }
}; };
const updateRateLimit = async (updates: TRateLimitUpdateDTO): Promise<TRateLimit> => { const updateRateLimit = async (updates: TRateLimitUpdateDTO): Promise<TRateLimit> => {
const appCfg = getConfig(); return rateLimitDAL.updateById(DEFAULT_RATE_LIMIT_CONFIG_ID, updates);
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);
}; };
const initializeBackgroundSync = () => { const initializeBackgroundSync = () => {