mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-08 07:04:02 -05:00
feat: updated frontend use run time config inject value
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"
|
||||
/>
|
||||
<title>Infisical</title>
|
||||
<script src="/runtime-ui-env.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -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
|
||||
|
||||
9
frontend/scripts/set-frontend-config.sh
Executable file
9
frontend/scripts/set-frontend-config.sh
Executable 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"
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 };
|
||||
@@ -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
1
frontend/src/config.ts
Normal file
@@ -0,0 +1 @@
|
||||
(window as any).__config__ = {};
|
||||
32
frontend/src/config/env.ts
Normal file
32
frontend/src/config/env.ts
Normal 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
12
frontend/src/global.d.ts
vendored
Normal 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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
13
frontend/src/vite-env.d.ts
vendored
13
frontend/src/vite-env.d.ts
vendored
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user