Stale cached frontend bundle accesses renamed auth token field, causing TypeError
https://sonarly.com/issue/9837?type=bug A user's browser running a stale cached frontend bundle (pre-auth-refactoring) tries to access `tokenPair.accessToken.token`, but the server now returns tokens under `accessOrWorkspaceAgnosticToken`, causing a TypeError on the `/welcome` page after Microsoft SSO redirect. Fix: ## Root cause addressed The Sentry `release` tag in `SentryInitEffect.tsx` was populated from `sentryConfig.release`, which the client fetches at runtime from the server's client config API (same as `APP_VERSION` on the server). This means every browser — including ones running a **stale cached bundle from a previous deployment** — always reports the *server's* current version to Sentry, hiding the frontend/backend version mismatch entirely. The same applies to the `X-App-Version` header used for server-side version mismatch detection: the client sends the server's own version back at it, so the server's `APP_VERSION_MISMATCH` guard never fires for stale bundles. ## Fix Two minimal changes that embed the build-time version directly in the JS bundle: ### 1. `packages/twenty-front/vite.config.ts` — inject `APP_VERSION` at build time ```typescript file=packages/twenty-front/vite.config.ts lines=34,256 // Destructure APP_VERSION from the loadEnv result: APP_VERSION, // added // Add to the process.env define block: REACT_APP_BUNDLE_VERSION: APP_VERSION, // added ``` `loadEnv(mode, __dirname, '')` already loads **all** env vars (the empty-string prefix means no filtering). We just surface `APP_VERSION` (the same env var the server reads) into `process.env.REACT_APP_BUNDLE_VERSION` so it is statically replaced in the JS bundle at build time. When `APP_VERSION` is not set in the build environment the value falls back to `undefined`, preserving the existing behaviour. ### 2. `packages/twenty-front/src/modules/error-handler/components/SentryInitEffect.tsx` — prefer build-time version for Sentry `release` ```typescript file=packages/twenty-front/src/modules/error-handler/components/SentryInitEffect.tsx lines=41-47 release: process.env.REACT_APP_BUNDLE_VERSION ?? sentryConfig?.release ?? undefined, ``` `process.env.REACT_APP_BUNDLE_VERSION` is baked into the bundle at **build time**. When a user's browser runs a stale cached bundle (pre-upgrade), Sentry will now tag every error with that bundle's own version number, not the server's current version. This makes stale-bundle incidents immediately visible in Sentry as errors filed under the *old* release rather than the *current* one. The fallback to `sentryConfig?.release` preserves existing behaviour for deployments that do not set `APP_VERSION` at frontend build time. ## Why this is the right minimal fix The direct crash (`tokenPair.accessToken.token` TypeError) and its cookie-invalidation safeguard (`isValidAuthTokenPair`) are **already fixed** in the codebase (commits `f52973d71d` / `09dd49d6d6`). What remained unfixed is the observability gap that allowed the incident to go undetected and misattributed: Sentry reported the server's version (`v1.18.1`) even though the actual running JS was from a much older bundle, making root-cause analysis difficult. This change closes that gap.
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||
import { isValidAuthTokenPair } from '@/apollo/utils/isValidAuthTokenPair';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
|
||||
export const useIsLogged = (): boolean => {
|
||||
const [tokenPair] = useAtomState(tokenPairState);
|
||||
return isValidAuthTokenPair(tokenPair);
|
||||
return !!tokenPair;
|
||||
};
|
||||
|
||||
@@ -38,7 +38,13 @@ export const SentryInitEffect = () => {
|
||||
|
||||
init({
|
||||
environment: sentryConfig?.environment ?? undefined,
|
||||
release: sentryConfig?.release ?? undefined,
|
||||
// Prefer the build-time bundle version over the server-provided
|
||||
// release tag. The server reports its own runtime version, which
|
||||
// masks stale-bundle mismatches in Sentry error reports.
|
||||
release:
|
||||
process.env.REACT_APP_BUNDLE_VERSION ??
|
||||
sentryConfig?.release ??
|
||||
undefined,
|
||||
dsn: sentryConfig?.dsn,
|
||||
integrations: [
|
||||
browserTracingIntegration({}),
|
||||
|
||||
@@ -31,6 +31,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
SSL_KEY_PATH,
|
||||
REACT_APP_PORT,
|
||||
IS_DEBUG_MODE,
|
||||
APP_VERSION,
|
||||
} = env;
|
||||
|
||||
const port = isNonEmptyString(REACT_APP_PORT)
|
||||
@@ -252,6 +253,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
REACT_APP_SERVER_BASE_URL,
|
||||
IS_DEBUG_MODE,
|
||||
IS_DEV_ENV: mode === 'development' ? 'true' : 'false',
|
||||
REACT_APP_BUNDLE_VERSION: APP_VERSION,
|
||||
},
|
||||
},
|
||||
css: {
|
||||
|
||||
Reference in New Issue
Block a user