diff --git a/frontend/index.html b/frontend/index.html index ee247f1f6..e3a051915 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -20,6 +20,7 @@ " /> Infisical +
diff --git a/frontend/scripts/initialize-standalone-build.sh b/frontend/scripts/initialize-standalone-build.sh index 644877d8f..972534326 100755 --- a/frontend/scripts/initialize-standalone-build.sh +++ b/frontend/scripts/initialize-standalone-build.sh @@ -6,6 +6,8 @@ scripts/replace-standalone-build-variable.sh "$BAKED_NEXT_PUBLIC_INTERCOM_ID" "$ scripts/replace-standalone-build-variable.sh "$BAKED_NEXT_PUBLIC_CAPTCHA_SITE_KEY" "$NEXT_PUBLIC_CAPTCHA_SITE_KEY" +scripts/set-frontend-config.sh + if [ "$TELEMETRY_ENABLED" != "false" ]; then echo "Telemetry is enabled" scripts/set-standalone-build-telemetry.sh true diff --git a/frontend/scripts/set-frontend-config.sh b/frontend/scripts/set-frontend-config.sh new file mode 100755 index 000000000..423662781 --- /dev/null +++ b/frontend/scripts/set-frontend-config.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Configuration output file +CONFIG_FILE="runtime-config.js" + +# Replace content in the config file with SENTRY_DSN interpolation +echo "window.__CONFIG__ = Object.freeze({ CAPTCHA_SITE_KEY: \"${CAPTCHA_SITE_KEY}\", CAPTCHA_SITE_KEY: \"${CAPTCHA_SITE_KEY}\", CAPTCHA_SITE_KEY: \"${CAPTCHA_SITE_KEY}\" })" > $CONFIG_FILE + +echo "Configuration file updated at $CONFIG_FILE" diff --git a/frontend/src/components/analytics/posthog.ts b/frontend/src/components/analytics/posthog.ts index f9285012e..539ba4ff5 100644 --- a/frontend/src/components/analytics/posthog.ts +++ b/frontend/src/components/analytics/posthog.ts @@ -1,18 +1,17 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -/* eslint-disable no-undef */ +import { envConfig } from "@app/config/env"; import posthog from "posthog-js"; -import { ENV, POSTHOG_API_KEY, POSTHOG_HOST } from "../utilities/config"; - export const initPostHog = () => { - // @ts-ignore console.log("Hi there 👋"); try { if (typeof window !== "undefined") { - // @ts-ignore - if (ENV === "production" && TELEMETRY_CAPTURING_ENABLED === true) { - posthog.init(POSTHOG_API_KEY, { - api_host: POSTHOG_HOST + if ( + envConfig.ENV === "production" && + envConfig.TELEMETRY_CAPTURING_ENABLED === true && + envConfig.POSTHOG_API_KEY + ) { + posthog.init(envConfig.POSTHOG_API_KEY, { + api_host: envConfig.POSTHOG_HOST }); } } diff --git a/frontend/src/components/navigation/RegionSelect.tsx b/frontend/src/components/navigation/RegionSelect.tsx index 7cbc22230..1a9024430 100644 --- a/frontend/src/components/navigation/RegionSelect.tsx +++ b/frontend/src/components/navigation/RegionSelect.tsx @@ -107,7 +107,7 @@ export const RegionSelect = () => { ))} - + diff --git a/frontend/src/components/utilities/config/index.ts b/frontend/src/components/utilities/config/index.ts deleted file mode 100644 index 9b3bf37f1..000000000 --- a/frontend/src/components/utilities/config/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -const ENV = process.env.NEXT_PUBLIC_ENV! || "development"; // investigate -const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!; -const POSTHOG_HOST = process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com"; -const INTERCOMid = process.env.NEXT_PUBLIC_INTERCOMid!; -const CAPTCHA_SITE_KEY = process.env.NEXT_PUBLIC_CAPTCHA_SITE_KEY!; - -export { CAPTCHA_SITE_KEY, ENV, INTERCOMid, POSTHOG_API_KEY, POSTHOG_HOST }; diff --git a/frontend/src/components/utilities/telemetry/Telemetry.ts b/frontend/src/components/utilities/telemetry/Telemetry.ts index 860314d16..ef2a3b55a 100644 --- a/frontend/src/components/utilities/telemetry/Telemetry.ts +++ b/frontend/src/components/utilities/telemetry/Telemetry.ts @@ -1,9 +1,7 @@ /* eslint-disable */ import { PostHog } from "posthog-js"; import { initPostHog } from "@app/components/analytics/posthog"; -import { ENV } from "@app/components/utilities/config"; - -declare let TELEMETRY_CAPTURING_ENABLED: any; +import { envConfig } from "@app/config/env"; class Capturer { api: PostHog; @@ -13,7 +11,7 @@ class Capturer { } capture(item: string) { - if (ENV === "production" && TELEMETRY_CAPTURING_ENABLED === true) { + if (envConfig.ENV === "production" && envConfig.TELEMETRY_CAPTURING_ENABLED === true) { try { this.api.capture(item); } catch (error) { @@ -23,7 +21,7 @@ class Capturer { } identify(id: string, email?: string) { - if (ENV === "production" && TELEMETRY_CAPTURING_ENABLED === true) { + if (envConfig.ENV === "production" && envConfig.TELEMETRY_CAPTURING_ENABLED === true) { try { this.api.identify(id, { email: email diff --git a/frontend/src/config.ts b/frontend/src/config.ts new file mode 100644 index 000000000..5a7202a37 --- /dev/null +++ b/frontend/src/config.ts @@ -0,0 +1 @@ +(window as any).__config__ = {}; diff --git a/frontend/src/config/env.ts b/frontend/src/config/env.ts new file mode 100644 index 000000000..296c6a87d --- /dev/null +++ b/frontend/src/config/env.ts @@ -0,0 +1,32 @@ +// akhilmhdh: These are runtime environment variables loaded from server +// The window body is filled with value from the server +// We add a script in index.html to load it from server before react loads +/* eslint-disable no-underscore-dangle */ +export const envConfig = { + ENV: import.meta.env.MODE, + get CAPTCHA_SITE_KEY() { + return ( + window?.__INFISICAL_RUNTIME_ENV__?.CAPTCHA_SITE_KEY || import.meta.env.VITE_CAPTCHA_SITE_KEY + ); + }, + get INTERCOM_ID() { + return window?.__INFISICAL_RUNTIME_ENV__?.INTERCOM_ID || import.meta.env.VITE_INTERCOM_ID; + }, + get POSTHOG_API_KEY() { + return ( + window?.__INFISICAL_RUNTIME_ENV__?.POSTHOG_API_KEY || import.meta.env.VITE_POSTHOG_API_KEY + ); + }, + get POSTHOG_HOST() { + return import.meta.env.VITE_POSTHOG_HOST! || "https://app.posthog.com"; + }, + get TELEMETRY_CAPTURING_ENABLED() { + return ( + window?.__INFISICAL_RUNTIME_ENV__?.TELEMETRY_CAPTURING_ENABLED || + import.meta.env.VITE_TELEMETRY_CAPTURING_ENABLED === true + ); + }, + get PLATFORM_VERSION() { + return import.meta.env.VITE_INFISICAL_PLATFORM_VERSION; + } +}; diff --git a/frontend/src/global.d.ts b/frontend/src/global.d.ts new file mode 100644 index 000000000..30b80cb70 --- /dev/null +++ b/frontend/src/global.d.ts @@ -0,0 +1,12 @@ +export {}; + +declare global { + interface Window { + __INFISICAL_RUNTIME_ENV__?: { + CAPTCHA_SITE_KEY?: string; + POSTHOG_API_KEY?: string; + INTERCOM_ID?: string; + TELEMETRY_CAPTURING_ENABLED: string; + }; + } +} diff --git a/frontend/src/layouts/AdminLayout/AdminLayout.tsx b/frontend/src/layouts/AdminLayout/AdminLayout.tsx index f74c9103b..f762acd9d 100644 --- a/frontend/src/layouts/AdminLayout/AdminLayout.tsx +++ b/frontend/src/layouts/AdminLayout/AdminLayout.tsx @@ -10,6 +10,7 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "@app/components/v2"; +import { envConfig } from "@app/config/env"; import { ProjectType } from "@app/hooks/api/workspace/types"; import { InsecureConnectionBanner } from "../OrganizationLayout/components/InsecureConnectionBanner"; @@ -18,8 +19,6 @@ import { INFISICAL_SUPPORT_OPTIONS } from "../OrganizationLayout/components/Side export const AdminLayout = () => { const { t } = useTranslation(); - const infisicalPlatformVersion = import.meta.env.VITE_INFISICAL_PLATFORM_VERSION; - return ( <>
@@ -61,10 +60,10 @@ export const AdminLayout = () => { ))} - {infisicalPlatformVersion && ( + {envConfig.PLATFORM_VERSION && (
- Version: {infisicalPlatformVersion} + Version: {envConfig.PLATFORM_VERSION}
)} diff --git a/frontend/src/layouts/OrganizationLayout/components/SidebarFooter/SidebarFooter.tsx b/frontend/src/layouts/OrganizationLayout/components/SidebarFooter/SidebarFooter.tsx index 8b4db193f..6a634a9c4 100644 --- a/frontend/src/layouts/OrganizationLayout/components/SidebarFooter/SidebarFooter.tsx +++ b/frontend/src/layouts/OrganizationLayout/components/SidebarFooter/SidebarFooter.tsx @@ -17,6 +17,7 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "@app/components/v2"; +import { envConfig } from "@app/config/env"; import { useOrganization, useSubscription } from "@app/context"; import { useGetOrgTrialUrl } from "@app/hooks/api"; @@ -49,8 +50,6 @@ export const SidebarFooter = () => { const { mutateAsync } = useGetOrgTrialUrl(); - const infisicalPlatformVersion = import.meta.env.VITE_INFISICAL_PLATFORM_VERSION; - return (
{ ))} - {infisicalPlatformVersion && ( + {envConfig.PLATFORM_VERSION && (
- Version: {infisicalPlatformVersion} + Version: {envConfig.PLATFORM_VERSION}
)} diff --git a/frontend/src/layouts/PersonalSettingsLayout/PersonalSettingsLayout.tsx b/frontend/src/layouts/PersonalSettingsLayout/PersonalSettingsLayout.tsx index f256dc2a2..8071d5043 100644 --- a/frontend/src/layouts/PersonalSettingsLayout/PersonalSettingsLayout.tsx +++ b/frontend/src/layouts/PersonalSettingsLayout/PersonalSettingsLayout.tsx @@ -10,6 +10,7 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "@app/components/v2"; +import { envConfig } from "@app/config/env"; import { ProjectType } from "@app/hooks/api/workspace/types"; import { InsecureConnectionBanner } from "../OrganizationLayout/components/InsecureConnectionBanner"; @@ -18,8 +19,6 @@ import { INFISICAL_SUPPORT_OPTIONS } from "../OrganizationLayout/components/Side export const PersonalSettingsLayout = () => { const { t } = useTranslation(); - const infisicalPlatformVersion = import.meta.env.VITE_INFISICAL_PLATFORM_VERSION; - return ( <>
@@ -61,10 +60,10 @@ export const PersonalSettingsLayout = () => { ))} - {infisicalPlatformVersion && ( + {envConfig.PLATFORM_VERSION && (
- Version: {infisicalPlatformVersion} + Version: {envConfig.PLATFORM_VERSION}
)} diff --git a/frontend/src/pages/auth/LoginPage/components/InitialStep/InitialStep.tsx b/frontend/src/pages/auth/LoginPage/components/InitialStep/InitialStep.tsx index d6b591fec..cc4ae8173 100644 --- a/frontend/src/pages/auth/LoginPage/components/InitialStep/InitialStep.tsx +++ b/frontend/src/pages/auth/LoginPage/components/InitialStep/InitialStep.tsx @@ -11,8 +11,8 @@ import { RegionSelect } from "@app/components/navigation/RegionSelect"; import { createNotification } from "@app/components/notifications"; import attemptCliLogin from "@app/components/utilities/attemptCliLogin"; import attemptLogin from "@app/components/utilities/attemptLogin"; -import { CAPTCHA_SITE_KEY } from "@app/components/utilities/config"; import { Button, IconButton, Input, Tooltip } from "@app/components/v2"; +import { envConfig } from "@app/config/env"; import { useServerConfig } from "@app/context"; import { useFetchServerStatus } from "@app/hooks/api"; import { LoginMethod } from "@app/hooks/api/admin/types"; @@ -351,11 +351,11 @@ export const InitialStep = ({ setStep, email, setEmail, password, setPassword }: className="select:-webkit-autofill:focus h-10" />
- {shouldShowCaptcha && ( + {shouldShowCaptcha && envConfig.CAPTCHA_SITE_KEY && (
setCaptchaToken(token)} ref={captchaRef} /> diff --git a/frontend/src/pages/auth/LoginPage/components/PasswordStep/PasswordStep.tsx b/frontend/src/pages/auth/LoginPage/components/PasswordStep/PasswordStep.tsx index cb49fc475..912ade1c0 100644 --- a/frontend/src/pages/auth/LoginPage/components/PasswordStep/PasswordStep.tsx +++ b/frontend/src/pages/auth/LoginPage/components/PasswordStep/PasswordStep.tsx @@ -10,9 +10,9 @@ import { Mfa } from "@app/components/auth/Mfa"; import { createNotification } from "@app/components/notifications"; import attemptCliLogin from "@app/components/utilities/attemptCliLogin"; import attemptLogin from "@app/components/utilities/attemptLogin"; -import { CAPTCHA_SITE_KEY } from "@app/components/utilities/config"; import SecurityClient from "@app/components/utilities/SecurityClient"; import { Button, Input, Spinner } from "@app/components/v2"; +import { envConfig } from "@app/config/env"; import { SessionStorageKeys } from "@app/const"; import { useToggle } from "@app/hooks"; import { useOauthTokenExchange, useSelectOrganization } from "@app/hooks/api"; @@ -329,11 +329,11 @@ export const PasswordStep = ({ providerAuthToken, email, password, setPassword } />
- {shouldShowCaptcha && ( + {shouldShowCaptcha && envConfig.CAPTCHA_SITE_KEY && (
setCaptchaToken(token)} ref={captchaRef} /> diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 11f02fe2a..e7ef95de4 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -1 +1,14 @@ /// +// +interface ImportMetaEnv { + readonly VITE_POSTHOG_API_KEY?: string; + readonly VITE_POSTHOG_HOST: string; + readonly VITE_INTERCOM_ID?: string; + readonly VITE_CAPTCHA_SITE_KEY?: string; + readonly VITE_INFISICAL_PLATFORM_VERSION?: string; + // more env variables... +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/nginx/default.dev.conf b/nginx/default.dev.conf index 2d651cba8..56d026616 100644 --- a/nginx/default.dev.conf +++ b/nginx/default.dev.conf @@ -14,6 +14,19 @@ server { proxy_pass http://backend:4000; proxy_redirect off; + proxy_cookie_path / "/; HttpOnly; SameSite=strict"; + } + + location /runtime-ui-env.js { + proxy_set_header X-Real-RIP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_pass http://backend:4000; + proxy_redirect off; + proxy_cookie_path / "/; HttpOnly; SameSite=strict"; } @@ -66,4 +79,4 @@ server { proxy_pass http://frontend:3000; proxy_redirect off; } -} \ No newline at end of file +}