remove frontend env parsing

This commit is contained in:
miloschwartz
2025-11-14 12:25:32 -05:00
parent e6e80f6fc7
commit 5b31bbce8d
2 changed files with 83 additions and 152 deletions

View File

@@ -1,13 +1,6 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin"; import createNextIntlPlugin from "next-intl/plugin";
import { pullEnv } from "./src/lib/pullEnv";
// validate env variables on local dev
if (process.env.NODE_ENV === "development") {
pullEnv();
}
const withNextIntl = createNextIntlPlugin(); const withNextIntl = createNextIntlPlugin();
const nextConfig: NextConfig = { const nextConfig: NextConfig = {

View File

@@ -1,175 +1,113 @@
import z from "zod";
import { Env } from "./types/env"; import { Env } from "./types/env";
const envSchema = z.object({
// Server configuration
NEXT_PORT: z.string(),
SERVER_EXTERNAL_PORT: z.string(),
SESSION_COOKIE_NAME: z.string(),
RESOURCE_ACCESS_TOKEN_PARAM: z.string(),
RESOURCE_SESSION_REQUEST_PARAM: z.string(),
RESOURCE_ACCESS_TOKEN_HEADERS_ID: z.string(),
RESOURCE_ACCESS_TOKEN_HEADERS_TOKEN: z.string(),
REO_CLIENT_ID: z.string().optional(),
MAXMIND_DB_PATH: z.string().optional(),
// App configuration
ENVIRONMENT: z.string(),
SANDBOX_MODE: z
.string()
.default("false")
.transform((val) => val === "true"),
APP_VERSION: z.string(),
DASHBOARD_URL: z.string(),
PRODUCT_UPDATES_NOTIFICATION_ENABLED: z
.string()
.default("true")
.transform((val) => val === "true"),
NEW_RELEASES_NOTIFICATION_ENABLED: z
.string()
.default("true")
.transform((val) => val === "true"),
// Email configuration
EMAIL_ENABLED: z
.string()
.default("false")
.transform((val) => val === "true"),
// Feature flags
DISABLE_USER_CREATE_ORG: z
.string()
.default("false")
.transform((val) => val === "true"),
DISABLE_SIGNUP_WITHOUT_INVITE: z
.string()
.default("false")
.transform((val) => val === "true"),
FLAGS_EMAIL_VERIFICATION_REQUIRED: z
.string()
.default("false")
.transform((val) => val === "true"),
FLAGS_ALLOW_RAW_RESOURCES: z
.string()
.default("false")
.transform((val) => val === "true"),
FLAGS_DISABLE_LOCAL_SITES: z
.string()
.default("false")
.transform((val) => val === "true"),
FLAGS_DISABLE_BASIC_WIREGUARD_SITES: z
.string()
.default("false")
.transform((val) => val === "true"),
FLAGS_ENABLE_CLIENTS: z
.string()
.default("false")
.transform((val) => val === "true"),
HIDE_SUPPORTER_KEY: z
.string()
.default("false")
.transform((val) => val === "true"),
USE_PANGOLIN_DNS: z
.string()
.default("false")
.transform((val) => val === "true"),
// Branding configuration (all optional)
BRANDING_APP_NAME: z.string().optional(),
BACKGROUND_IMAGE_PATH: z.string().optional(),
BRANDING_LOGO_LIGHT_PATH: z.string().optional(),
BRANDING_LOGO_DARK_PATH: z.string().optional(),
BRANDING_LOGO_AUTH_WIDTH: z.coerce.number().optional(),
BRANDING_LOGO_AUTH_HEIGHT: z.coerce.number().optional(),
BRANDING_LOGO_NAVBAR_WIDTH: z.coerce.number().optional(),
BRANDING_LOGO_NAVBAR_HEIGHT: z.coerce.number().optional(),
LOGIN_PAGE_TITLE_TEXT: z.string().optional(),
LOGIN_PAGE_SUBTITLE_TEXT: z.string().optional(),
SIGNUP_PAGE_TITLE_TEXT: z.string().optional(),
SIGNUP_PAGE_SUBTITLE_TEXT: z.string().optional(),
RESOURCE_AUTH_PAGE_SHOW_LOGO: z
.string()
.transform((val) => val === "true")
.optional(),
RESOURCE_AUTH_PAGE_HIDE_POWERED_BY: z
.string()
.transform((val) => val === "true")
.optional(),
RESOURCE_AUTH_PAGE_TITLE_TEXT: z.string().optional(),
RESOURCE_AUTH_PAGE_SUBTITLE_TEXT: z.string().optional(),
BRANDING_FOOTER: z.string().optional()
});
export function pullEnv(): Env { export function pullEnv(): Env {
const env = envSchema.parse(process.env);
return { return {
server: { server: {
nextPort: env.NEXT_PORT, nextPort: process.env.NEXT_PORT as string,
externalPort: env.SERVER_EXTERNAL_PORT, externalPort: process.env.SERVER_EXTERNAL_PORT as string,
sessionCookieName: env.SESSION_COOKIE_NAME, sessionCookieName: process.env.SESSION_COOKIE_NAME as string,
resourceAccessTokenParam: env.RESOURCE_ACCESS_TOKEN_PARAM, resourceAccessTokenParam: process.env
resourceSessionRequestParam: env.RESOURCE_SESSION_REQUEST_PARAM, .RESOURCE_ACCESS_TOKEN_PARAM as string,
resourceAccessTokenHeadersId: env.RESOURCE_ACCESS_TOKEN_HEADERS_ID, resourceSessionRequestParam: process.env
resourceAccessTokenHeadersToken: .RESOURCE_SESSION_REQUEST_PARAM as string,
env.RESOURCE_ACCESS_TOKEN_HEADERS_TOKEN, resourceAccessTokenHeadersId: process.env
reoClientId: env.REO_CLIENT_ID, .RESOURCE_ACCESS_TOKEN_HEADERS_ID as string,
maxmind_db_path: env.MAXMIND_DB_PATH resourceAccessTokenHeadersToken: process.env
.RESOURCE_ACCESS_TOKEN_HEADERS_TOKEN as string,
reoClientId: process.env.REO_CLIENT_ID as string,
maxmind_db_path: process.env.MAXMIND_DB_PATH as string
}, },
app: { app: {
environment: env.ENVIRONMENT, environment: process.env.ENVIRONMENT as string,
sandbox_mode: env.SANDBOX_MODE, sandbox_mode: process.env.SANDBOX_MODE === "true" ? true : false,
version: env.APP_VERSION, version: process.env.APP_VERSION as string,
dashboardUrl: env.DASHBOARD_URL, dashboardUrl: process.env.DASHBOARD_URL as string,
notifications: { notifications: {
product_updates: env.PRODUCT_UPDATES_NOTIFICATION_ENABLED, product_updates:
new_releases: env.NEW_RELEASES_NOTIFICATION_ENABLED process.env.PRODUCT_UPDATES_NOTIFICATION_ENABLED === "true"
? true
: false,
new_releases:
process.env.NEW_RELEASES_NOTIFICATION_ENABLED === "true"
? true
: false
} }
}, },
email: { email: {
emailEnabled: env.EMAIL_ENABLED emailEnabled: process.env.EMAIL_ENABLED === "true" ? true : false
}, },
flags: { flags: {
disableUserCreateOrg: env.DISABLE_USER_CREATE_ORG, disableUserCreateOrg:
disableSignupWithoutInvite: env.DISABLE_SIGNUP_WITHOUT_INVITE, process.env.DISABLE_USER_CREATE_ORG === "true" ? true : false,
emailVerificationRequired: env.FLAGS_EMAIL_VERIFICATION_REQUIRED, disableSignupWithoutInvite:
allowRawResources: env.FLAGS_ALLOW_RAW_RESOURCES, process.env.DISABLE_SIGNUP_WITHOUT_INVITE === "true"
disableLocalSites: env.FLAGS_DISABLE_LOCAL_SITES, ? true
disableBasicWireguardSites: env.FLAGS_DISABLE_BASIC_WIREGUARD_SITES, : false,
enableClients: env.FLAGS_ENABLE_CLIENTS, emailVerificationRequired:
hideSupporterKey: env.HIDE_SUPPORTER_KEY, process.env.FLAGS_EMAIL_VERIFICATION_REQUIRED === "true"
usePangolinDns: env.USE_PANGOLIN_DNS ? true
: false,
allowRawResources:
process.env.FLAGS_ALLOW_RAW_RESOURCES === "true" ? true : false,
disableLocalSites:
process.env.FLAGS_DISABLE_LOCAL_SITES === "true" ? true : false,
disableBasicWireguardSites:
process.env.FLAGS_DISABLE_BASIC_WIREGUARD_SITES === "true"
? true
: false,
enableClients:
process.env.FLAGS_ENABLE_CLIENTS === "true" ? true : false,
hideSupporterKey:
process.env.HIDE_SUPPORTER_KEY === "true" ? true : false,
usePangolinDns:
process.env.USE_PANGOLIN_DNS === "true" ? true : false
}, },
branding: { branding: {
appName: env.BRANDING_APP_NAME, appName: process.env.BRANDING_APP_NAME as string,
background_image_path: env.BACKGROUND_IMAGE_PATH, background_image_path: process.env.BACKGROUND_IMAGE_PATH as string,
logo: { logo: {
lightPath: env.BRANDING_LOGO_LIGHT_PATH, lightPath: process.env.BRANDING_LOGO_LIGHT_PATH as string,
darkPath: env.BRANDING_LOGO_DARK_PATH, darkPath: process.env.BRANDING_LOGO_DARK_PATH as string,
authPage: { authPage: {
width: env.BRANDING_LOGO_AUTH_WIDTH, width: parseInt(
height: env.BRANDING_LOGO_AUTH_HEIGHT process.env.BRANDING_LOGO_AUTH_WIDTH as string
),
height: parseInt(
process.env.BRANDING_LOGO_AUTH_HEIGHT as string
)
}, },
navbar: { navbar: {
width: env.BRANDING_LOGO_NAVBAR_WIDTH, width: parseInt(
height: env.BRANDING_LOGO_NAVBAR_HEIGHT process.env.BRANDING_LOGO_NAVBAR_WIDTH as string
),
height: parseInt(
process.env.BRANDING_LOGO_NAVBAR_HEIGHT as string
)
} }
}, },
loginPage: { loginPage: {
titleText: env.LOGIN_PAGE_TITLE_TEXT, titleText: process.env.LOGIN_PAGE_TITLE_TEXT as string,
subtitleText: env.LOGIN_PAGE_SUBTITLE_TEXT subtitleText: process.env.LOGIN_PAGE_SUBTITLE_TEXT as string
}, },
signupPage: { signupPage: {
titleText: env.SIGNUP_PAGE_TITLE_TEXT, titleText: process.env.SIGNUP_PAGE_TITLE_TEXT as string,
subtitleText: env.SIGNUP_PAGE_SUBTITLE_TEXT subtitleText: process.env.SIGNUP_PAGE_SUBTITLE_TEXT as string
}, },
resourceAuthPage: { resourceAuthPage: {
showLogo: env.RESOURCE_AUTH_PAGE_SHOW_LOGO, showLogo:
hidePoweredBy: env.RESOURCE_AUTH_PAGE_HIDE_POWERED_BY, process.env.RESOURCE_AUTH_PAGE_SHOW_LOGO === "true"
titleText: env.RESOURCE_AUTH_PAGE_TITLE_TEXT, ? true
subtitleText: env.RESOURCE_AUTH_PAGE_SUBTITLE_TEXT : false,
hidePoweredBy:
process.env.RESOURCE_AUTH_PAGE_HIDE_POWERED_BY === "true"
? true
: false,
titleText: process.env.RESOURCE_AUTH_PAGE_TITLE_TEXT as string,
subtitleText: process.env
.RESOURCE_AUTH_PAGE_SUBTITLE_TEXT as string
}, },
footer: env.BRANDING_FOOTER footer: process.env.BRANDING_FOOTER as string
} }
}; };
} }