From da79fe227f3d55608e99cd2276db888e17f38c18 Mon Sep 17 00:00:00 2001 From: Sjoerd Vink <sjoerdvink@Sjoerds-MacBook-Pro.local> Date: Tue, 5 Nov 2024 08:59:17 -0500 Subject: [PATCH] Reapply "feat: fallback for all env variables to prevent crash" This reverts commit 3c2b3ca5ef4d7e25f027b1c6838cbab24e6bf96a. --- apps/web/src/components/navbar/navbar.tsx | 9 +-- apps/web/src/main.tsx | 5 +- libs/config/src/featureFlags.ts | 61 ++++++++++++------- libs/shared/lib/data-access/broker/broker.tsx | 3 +- .../security/useAuthentication.tsx | 5 +- libs/shared/lib/inspector/InspectorPanel.tsx | 3 +- libs/shared/lib/sidebar/index.tsx | 5 +- 7 files changed, 57 insertions(+), 34 deletions(-) diff --git a/apps/web/src/components/navbar/navbar.tsx b/apps/web/src/components/navbar/navbar.tsx index 5cb0e428e..ecd864a38 100644 --- a/apps/web/src/components/navbar/navbar.tsx +++ b/apps/web/src/components/navbar/navbar.tsx @@ -13,8 +13,9 @@ import { useAuthCache, useAuthentication } from '@graphpolaris/shared/lib/data-a import { DropdownItem } from '@graphpolaris/shared/lib/components/dropdowns'; import GpLogo from './gp-logo'; import { Popover, PopoverContent, PopoverTrigger } from '@graphpolaris/shared/lib/components/layout/Popover'; -import { showSharableExploration } from 'config'; -import { Button, useActiveSaveStateAuthorization } from '@graphpolaris/shared'; +import { useDispatch } from 'react-redux'; +import { getEnvVariable, showManagePermissions, showSharableExploration } from 'config'; +import { Button, Dialog, DialogContent, DialogTrigger, useActiveSaveStateAuthorization, useSessionCache } from '@graphpolaris/shared'; import { ManagementTrigger, ManagementViews } from '@graphpolaris/shared/lib/management'; const AuthURL = import.meta.env.GP_AUTH_URL; @@ -25,7 +26,7 @@ export const Navbar = () => { const authCache = useAuthCache(); const authorization = useActiveSaveStateAuthorization(); const [menuOpen, setMenuOpen] = useState(false); - const buildInfo = import.meta.env.GRAPHPOLARIS_VERSION; + const buildInfo = getEnvVariable('GRAPHPOLARIS_VERSION'); const [managementOpen, setManagementOpen] = useState<boolean>(false); const [current, setCurrent] = useState<ManagementViews>('overview'); @@ -88,7 +89,7 @@ export const Navbar = () => { <DropdownItem value="Log out" onClick={() => { - location.replace(`${AuthURL}/outpost.goauthentik.io/sign_out`); + location.replace(`${getEnvVariable('GP_AUTH_URL')}/outpost.goauthentik.io/sign_out`); }} /> </> diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx index e25807e6d..f7029e4d6 100644 --- a/apps/web/src/main.tsx +++ b/apps/web/src/main.tsx @@ -5,12 +5,13 @@ import * as Sentry from '@sentry/react'; import { store } from '@graphpolaris/shared/lib/data-access/store'; import App from './app/App'; import { createRoot } from 'react-dom/client'; +import { getEnvVariable } from 'config'; import './main.css'; import { ErrorBoundary } from '@graphpolaris/shared/lib/components/errorBoundary'; -if (import.meta.env.SENTRY_ENABLED) { +if (getEnvVariable('SENTRY_ENABLED')) { Sentry.init({ - dsn: import.meta.env.SENTRY_URL, + dsn: getEnvVariable('SENTRY_URL'), integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()], tracesSampleRate: 1.0, replaysSessionSampleRate: 0.1, diff --git a/libs/config/src/featureFlags.ts b/libs/config/src/featureFlags.ts index b6364d037..21d94384f 100644 --- a/libs/config/src/featureFlags.ts +++ b/libs/config/src/featureFlags.ts @@ -1,32 +1,49 @@ -// Safely retrieve environment variable values with a default fallback -const getEnvVariable = (key: string, defaultValue: string = 'false'): string => { - return import.meta.env[key] ?? defaultValue; +const envFallbacks: Record<string, any> = { + SENTRY_ENABLED: false, + SENTRY_URL: '', + GRAPHPOLARIS_VERSION: 'prod', + GP_AUTH_URL: '', + BACKEND_WSS_URL: '', + BACKEND_URL: '', + BACKEND_USER: '', + WIP_TABLEVIS: true, + WIP_NODELINKVIS: true, + WIP_RAWJSONVIS: true, + WIP_PAOHVIS: true, + WIP_MATRIXVIS: true, + WIP_SEMANTICSUBSTRATESVIS: true, + WIP_MAPVIS: true, + WIP_INSIGHT_SHARING: true, + WIP_VIEWER_PERMISSIONS: true, + WIP_SHARABLE_EXPLORATION: true, }; -// Check if the environment is production -const isProduction = (): boolean => { - return getEnvVariable('GRAPHPOLARIS_VERSION', 'dev') === 'prod'; -}; +type EnvFallbackKey = keyof typeof envFallbacks; -// Check if the Manage Permissions feature is enabled -const showManagePermissions = (): boolean => { - return !isProduction() || (isProduction() && getEnvVariable('WIP_VIEWER_PERMISSIONS') === 'false'); +// Safely retrieve environment variable values with a default fallback +const getEnvVariable = (key: EnvFallbackKey): any => { + const value = import.meta.env[key]; + if (value === undefined) { + console.error(`Environment variable ${key} is missing, using fallback value.`); + return envFallbacks[key]; + } + return value; }; -// Check if the Insight Sharing feature is enabled -const showInsightSharing = (): boolean => { - return !isProduction() || (isProduction() && getEnvVariable('WIP_INSIGHT_SHARING') === 'false'); +// Check if the environment is production +const isProduction = (): boolean => { + return getEnvVariable('GRAPHPOLARIS_VERSION') === 'prod'; }; -// Check if the Insight Sharing feature is enabled -const showSharableExploration = (): boolean => { - return !isProduction() || (isProduction() && getEnvVariable('WIP_SHARABLE_EXPLORATION') === 'false'); +// Utility to check if a WIP feature is enabled +const isWIPFeatureEnabled = (featureKey: string): boolean => { + return getEnvVariable(`WIP_${featureKey.toUpperCase()}`) === 'false'; }; -// Utility to check if a specific visualization is released based on environment variables -const isVisualizationReleased = (visualizationName: string): boolean => { - const visualizationFlag = getEnvVariable(`WIP_${visualizationName.toUpperCase()}`, 'false'); - return !isProduction() || (isProduction() && visualizationFlag === 'false'); -}; +// Feature flags with checks for production and WIP feature flags +const showManagePermissions = (): boolean => !isProduction() || isWIPFeatureEnabled('viewer_permissions'); +const showInsightSharing = (): boolean => !isProduction() || isWIPFeatureEnabled('insight_sharing'); +const showSharableExploration = (): boolean => !isProduction() || isWIPFeatureEnabled('sharable_exploration'); +const isVisualizationReleased = (visualizationName: string): boolean => !isProduction() || isWIPFeatureEnabled(visualizationName); -export { isProduction, showManagePermissions, showInsightSharing, showSharableExploration, isVisualizationReleased }; +export { getEnvVariable, isProduction, showManagePermissions, showInsightSharing, showSharableExploration, isVisualizationReleased }; diff --git a/libs/shared/lib/data-access/broker/broker.tsx b/libs/shared/lib/data-access/broker/broker.tsx index f915a2f24..361434842 100644 --- a/libs/shared/lib/data-access/broker/broker.tsx +++ b/libs/shared/lib/data-access/broker/broker.tsx @@ -4,6 +4,7 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ +import { getEnvVariable } from 'config'; import { UseIsAuthorizedState } from '../store/authSlice'; import { ReceiveMessageI, SendMessageI, SendMessageWithSessionI } from './types'; @@ -38,7 +39,7 @@ export class Broker { /** Get the singleton instance of the Broker. */ public static instance(): Broker { - if (!this.singletonInstance) this.singletonInstance = new Broker(import.meta.env.BACKEND_WSS_URL); + if (!this.singletonInstance) this.singletonInstance = new Broker(getEnvVariable('BACKEND_WSS_URL')); return this.singletonInstance; } diff --git a/libs/shared/lib/data-access/security/useAuthentication.tsx b/libs/shared/lib/data-access/security/useAuthentication.tsx index fcb507b86..18310f738 100644 --- a/libs/shared/lib/data-access/security/useAuthentication.tsx +++ b/libs/shared/lib/data-access/security/useAuthentication.tsx @@ -1,8 +1,9 @@ +import { getEnvVariable } from 'config'; import { useAppDispatch, useAuthCache } from '../store'; import { authenticated, changeRoom, UserAuthenticationHeader } from '../store/authSlice'; -const domain = import.meta.env.BACKEND_URL; -const userURI = import.meta.env.BACKEND_USER; +const domain = getEnvVariable('BACKEND_URL'); +const userURI = getEnvVariable('BACKEND_USER'); export const fetchSettings: RequestInit = { method: 'GET', diff --git a/libs/shared/lib/inspector/InspectorPanel.tsx b/libs/shared/lib/inspector/InspectorPanel.tsx index 074ad172e..d1c881bc6 100644 --- a/libs/shared/lib/inspector/InspectorPanel.tsx +++ b/libs/shared/lib/inspector/InspectorPanel.tsx @@ -9,9 +9,10 @@ import { SelectionConfig } from '../vis/components/config/SelectionConfig'; import { SchemaSettings } from '../schema/panel/SchemaSettings'; import { QuerySettings } from '../querybuilder/panel/querysidepanel/QuerySettings'; import { useActiveVisualization } from '@graphpolaris/shared/lib/data-access'; +import { getEnvVariable } from 'config'; export function InspectorPanel(props: { children?: React.ReactNode }) { - const buildInfo = import.meta.env.GRAPHPOLARIS_VERSION; + const buildInfo = getEnvVariable('GRAPHPOLARIS_VERSION'); const selection = useSelection(); const focus = useFocus(); const dispatch = useDispatch(); diff --git a/libs/shared/lib/sidebar/index.tsx b/libs/shared/lib/sidebar/index.tsx index 7c2f42419..8307fea03 100644 --- a/libs/shared/lib/sidebar/index.tsx +++ b/libs/shared/lib/sidebar/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../components'; import ColorMode from '../components/color-mode'; +import { getEnvVariable } from 'config'; export type SideNavTab = 'Schema' | 'Search' | undefined; @@ -29,8 +30,8 @@ export function Sidebar({ tab: SideNavTab; openMonitoringDialog: () => void; }) { - const isProd = import.meta.env.GRAPHPOLARIS_VERSION === 'prod'; - const isInsightSharingWIP = import.meta.env.WIP_INSIGHT_SHARING === 'true'; + const isProd = getEnvVariable('GRAPHPOLARIS_VERSION') === 'prod'; + const isInsightSharingWIP = getEnvVariable('WIP_INSIGHT_SHARING') === true; return ( <div className="side-bar w-fit h-full flex shrink"> -- GitLab