From a1b52e18dd7515314d0f40a8a5f0e0f12fc60459 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 9 Nov 2023 09:13:50 -0500 Subject: [PATCH] chore: Centralize environment detection --- server/env.ts | 21 +++++++++++++++++++++ server/logging/Logger.ts | 10 ++++------ server/middlewares/shareDomains.ts | 3 +-- server/routes/app.ts | 12 ++++-------- server/routes/index.ts | 3 +-- server/services/web.ts | 6 ++---- server/storage/database.ts | 6 ++---- server/utils/prefetchTags.tsx | 4 +--- server/utils/startup.ts | 3 +-- 9 files changed, 37 insertions(+), 31 deletions(-) diff --git a/server/env.ts b/server/env.ts index 3dd41b2c7..6eb8d19a0 100644 --- a/server/env.ts +++ b/server/env.ts @@ -711,6 +711,27 @@ export class Environment { ].includes(this.URL); } + /** + * Returns true if the current installation is running in production. + */ + public get isProduction() { + return this.ENVIRONMENT === "production"; + } + + /** + * Returns true if the current installation is running in the development environment. + */ + public get isDevelopment() { + return this.ENVIRONMENT === "development"; + } + + /** + * Returns true if the current installation is running in a test environment. + */ + public get isTest() { + return this.ENVIRONMENT === "test"; + } + private toOptionalString(value: string | undefined) { return value ? value : undefined; } diff --git a/server/logging/Logger.ts b/server/logging/Logger.ts index 43feb9cfd..f684f4de3 100644 --- a/server/logging/Logger.ts +++ b/server/logging/Logger.ts @@ -12,8 +12,6 @@ import Sentry from "@server/logging/sentry"; import ShutdownHelper from "@server/utils/ShutdownHelper"; import * as Tracing from "./tracer"; -const isProduction = env.ENVIRONMENT === "production"; - type LogCategory = | "lifecycle" | "authentication" @@ -53,7 +51,7 @@ class Logger { }); this.output.add( new winston.transports.Console({ - format: isProduction + format: env.isProduction ? winston.format.json() : winston.format.combine( winston.format.colorize(), @@ -109,7 +107,7 @@ class Logger { }); } - if (isProduction) { + if (env.isProduction) { this.output.warn(message, this.sanitize(extra)); } else if (extra) { console.warn(message, extra); @@ -155,7 +153,7 @@ class Logger { }); } - if (isProduction) { + if (env.isProduction) { this.output.error(message, { error: error.message, stack: error.stack, @@ -190,7 +188,7 @@ class Logger { */ private sanitize(input: T): T { // Short circuit if we're not in production to enable easier debugging - if (!isProduction) { + if (!env.isProduction) { return input; } diff --git a/server/middlewares/shareDomains.ts b/server/middlewares/shareDomains.ts index f846fcddd..ffaab1f96 100644 --- a/server/middlewares/shareDomains.ts +++ b/server/middlewares/shareDomains.ts @@ -7,9 +7,8 @@ import { Share } from "@server/models"; export default function shareDomains() { return async function shareDomainsMiddleware(ctx: Context, next: Next) { const isCustomDomain = parseDomain(ctx.host).custom; - const isDevelopment = env.ENVIRONMENT === "development"; - if (isDevelopment || (isCustomDomain && env.isCloudHosted)) { + if (env.isDevelopment || (isCustomDomain && env.isCloudHosted)) { const share = await Share.unscoped().findOne({ where: { domain: ctx.hostname, diff --git a/server/routes/app.ts b/server/routes/app.ts index 23effcb7e..6731dcc6d 100644 --- a/server/routes/app.ts +++ b/server/routes/app.ts @@ -14,10 +14,6 @@ import { getTeamFromContext } from "@server/utils/passport"; import prefetchTags from "@server/utils/prefetchTags"; import readManifestFile from "@server/utils/readManifestFile"; -const isProduction = env.ENVIRONMENT === "production"; -const isDevelopment = env.ENVIRONMENT === "development"; -const isTest = env.ENVIRONMENT === "test"; - const readFile = util.promisify(fs.readFile); const entry = "app/index.tsx"; const viteHost = env.URL.replace(`:${env.PORT}`, ":3001"); @@ -25,17 +21,17 @@ const viteHost = env.URL.replace(`:${env.PORT}`, ":3001"); let indexHtmlCache: Buffer | undefined; const readIndexFile = async (): Promise => { - if (isProduction || isTest) { + if (env.isProduction || env.isTest) { if (indexHtmlCache) { return indexHtmlCache; } } - if (isTest) { + if (env.isTest) { return await readFile(path.join(__dirname, "../static/index.html")); } - if (isDevelopment) { + if (env.isDevelopment) { return await readFile( path.join(__dirname, "../../../server/static/index.html") ); @@ -77,7 +73,7 @@ export const renderApp = async ( `; - const scriptTags = isProduction + const scriptTags = env.isProduction ? `` diff --git a/server/routes/index.ts b/server/routes/index.ts index 4d41088a2..9804cbaaa 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -19,7 +19,6 @@ import apexRedirect from "../middlewares/apexRedirect"; import { renderApp, renderShare } from "./app"; import errors from "./errors"; -const isProduction = env.ENVIRONMENT === "production"; const koa = new Koa(); const router = new Router(); @@ -59,7 +58,7 @@ router.use( } ); -if (isProduction) { +if (env.isProduction) { router.get("/static/*", async (ctx) => { try { const pathname = ctx.path.substring(8); diff --git a/server/services/web.ts b/server/services/web.ts index e2fdc1148..c54e14b0d 100644 --- a/server/services/web.ts +++ b/server/services/web.ts @@ -22,8 +22,6 @@ import routes from "../routes"; import api from "../routes/api"; import auth from "../routes/auth"; -const isProduction = env.ENVIRONMENT === "production"; - // Construct scripts CSP based on services in use by this installation const defaultSrc = ["'self'"]; const scriptSrc = ["'self'", "gist.github.com", "www.googletagmanager.com"]; @@ -36,7 +34,7 @@ if (env.isCloudHosted) { } // Allow to load assets from Vite -if (!isProduction) { +if (!env.isProduction) { scriptSrc.push(env.URL.replace(`:${env.PORT}`, ":3001")); scriptSrc.push("localhost:3001"); } @@ -54,7 +52,7 @@ if (env.CDN_URL) { export default function init(app: Koa = new Koa(), server?: Server) { void initI18n(); - if (isProduction) { + if (env.isProduction) { // Force redirect to HTTPS protocol unless explicitly disabled if (env.FORCE_HTTPS) { app.use( diff --git a/server/storage/database.ts b/server/storage/database.ts index 3e1e98f88..7980976a2 100644 --- a/server/storage/database.ts +++ b/server/storage/database.ts @@ -5,8 +5,6 @@ import env from "@server/env"; import Logger from "../logging/Logger"; import * as models from "../models"; -const isDevelopment = env.ENVIRONMENT === "development"; -const isProduction = env.ENVIRONMENT === "production"; const isSSLDisabled = env.PGSSLMODE === "disable"; const poolMax = env.DATABASE_CONNECTION_POOL_MAX ?? 5; const poolMin = env.DATABASE_CONNECTION_POOL_MIN ?? 0; @@ -19,10 +17,10 @@ export const sequelize = new Sequelize(url, { logging: (msg) => process.env.DEBUG?.includes("database") && Logger.debug("database", msg), typeValidation: true, - logQueryParameters: isDevelopment, + logQueryParameters: env.isDevelopment, dialectOptions: { ssl: - isProduction && !isSSLDisabled + env.isProduction && !isSSLDisabled ? { // Ref.: https://github.com/brianc/node-postgres/issues/2009 rejectUnauthorized: false, diff --git a/server/utils/prefetchTags.tsx b/server/utils/prefetchTags.tsx index 83410c4b0..4894834d3 100644 --- a/server/utils/prefetchTags.tsx +++ b/server/utils/prefetchTags.tsx @@ -3,8 +3,6 @@ import ReactDOMServer from "react-dom/server"; import env from "@server/env"; import readManifestFile, { ManifestStructure } from "./readManifestFile"; -const isProduction = env.ENVIRONMENT === "production"; - const prefetchTags = []; if (env.AWS_S3_ACCELERATE_URL) { @@ -30,7 +28,7 @@ if (env.CDN_URL) { ); } -if (isProduction) { +if (env.isProduction) { const manifest = readManifestFile(); const returnFileAndImportsFromManifest = ( diff --git a/server/utils/startup.ts b/server/utils/startup.ts index ee26eace5..2f760c655 100644 --- a/server/utils/startup.ts +++ b/server/utils/startup.ts @@ -33,11 +33,10 @@ export async function checkDataMigrations() { return; } - const isProduction = env.ENVIRONMENT === "production"; const teams = await Team.count(); const providers = await AuthenticationProvider.count(); - if (isProduction && teams && !providers) { + if (env.isProduction && teams && !providers) { Logger.warn(` This version of Outline cannot start until a data migration is complete. Backup your database, run the database migrations and the following script: