feat: updated frontend use run time config inject value

This commit is contained in:
=
2025-01-06 12:29:58 +05:30
parent d0648ca596
commit d5412f916f
17 changed files with 111 additions and 41 deletions

View File

@@ -20,6 +20,7 @@
"
/>
<title>Infisical</title>
<script src="/runtime-ui-env.js"></script>
</head>
<body>
<div id="root"></div>

View File

@@ -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

View File

@@ -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"

View File

@@ -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
});
}
}

View File

@@ -107,7 +107,7 @@ export const RegionSelect = () => {
))}
</Select>
<Modal>
<ModalTrigger>
<ModalTrigger asChild>
<button type="button" className="mt-1 text-right text-xs text-mineshaft-400 underline">
Help me pick a data region
</button>

View File

@@ -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 };

View File

@@ -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

1
frontend/src/config.ts Normal file
View File

@@ -0,0 +1 @@
(window as any).__config__ = {};

View File

@@ -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;
}
};

12
frontend/src/global.d.ts vendored Normal file
View File

@@ -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;
};
}
}

View File

@@ -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 (
<>
<div className="dark hidden h-screen w-full flex-col overflow-x-hidden md:flex">
@@ -61,10 +60,10 @@ export const AdminLayout = () => {
</a>
</DropdownMenuItem>
))}
{infisicalPlatformVersion && (
{envConfig.PLATFORM_VERSION && (
<div className="mb-2 mt-2 w-full cursor-default pl-5 text-sm duration-200 hover:text-mineshaft-200">
<FontAwesomeIcon icon={faInfo} className="mr-4 px-[0.1rem]" />
Version: {infisicalPlatformVersion}
Version: {envConfig.PLATFORM_VERSION}
</div>
)}
</DropdownMenuContent>

View File

@@ -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 (
<div
className={`relative mt-10 ${
@@ -96,10 +95,10 @@ export const SidebarFooter = () => {
</a>
</DropdownMenuItem>
))}
{infisicalPlatformVersion && (
{envConfig.PLATFORM_VERSION && (
<div className="mb-2 mt-2 w-full cursor-default pl-5 text-sm duration-200 hover:text-mineshaft-200">
<FontAwesomeIcon icon={faInfo} className="mr-4 px-[0.1rem]" />
Version: {infisicalPlatformVersion}
Version: {envConfig.PLATFORM_VERSION}
</div>
)}
</DropdownMenuContent>

View File

@@ -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 (
<>
<div className="dark hidden h-screen w-full flex-col overflow-x-hidden md:flex">
@@ -61,10 +60,10 @@ export const PersonalSettingsLayout = () => {
</a>
</DropdownMenuItem>
))}
{infisicalPlatformVersion && (
{envConfig.PLATFORM_VERSION && (
<div className="mb-2 mt-2 w-full cursor-default pl-5 text-sm duration-200 hover:text-mineshaft-200">
<FontAwesomeIcon icon={faInfo} className="mr-4 px-[0.1rem]" />
Version: {infisicalPlatformVersion}
Version: {envConfig.PLATFORM_VERSION}
</div>
)}
</DropdownMenuContent>

View File

@@ -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"
/>
</div>
{shouldShowCaptcha && (
{shouldShowCaptcha && envConfig.CAPTCHA_SITE_KEY && (
<div className="mt-4">
<HCaptcha
theme="dark"
sitekey={CAPTCHA_SITE_KEY}
sitekey={envConfig.CAPTCHA_SITE_KEY}
onVerify={(token) => setCaptchaToken(token)}
ref={captchaRef}
/>

View File

@@ -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 }
/>
</div>
</div>
{shouldShowCaptcha && (
{shouldShowCaptcha && envConfig.CAPTCHA_SITE_KEY && (
<div className="mx-auto mt-4 flex w-full min-w-[22rem] items-center justify-center lg:w-1/6">
<HCaptcha
theme="dark"
sitekey={CAPTCHA_SITE_KEY}
sitekey={envConfig.CAPTCHA_SITE_KEY}
onVerify={(token) => setCaptchaToken(token)}
ref={captchaRef}
/>

View File

@@ -1 +1,14 @@
/// <reference types="vite/client" />
//
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;
}

View File

@@ -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;
}
}
}