Skip to content

fix: disable recaptcha and analytics when in dev mode#48

Merged
mfrancisc merged 9 commits intocodeready-toolchain:masterfrom
mfrancisc:newenv
Mar 26, 2026
Merged

fix: disable recaptcha and analytics when in dev mode#48
mfrancisc merged 9 commits intocodeready-toolchain:masterfrom
mfrancisc:newenv

Conversation

@mfrancisc
Copy link
Contributor

@mfrancisc mfrancisc commented Mar 25, 2026

wrt https://redhat-internal.slack.com/archives/C085PFGDLGY/p1774362139343779

Jira: https://redhat.atlassian.net/browse/SANDBOX-1738

e2e tests : codeready-toolchain/toolchain-e2e#1270

this PR adds a new configuration variable environment that can be defined at deploy time.
When set to DEV it will disable:

  • adobe analytics
  • amplitude analytics
  • privacy preferences modal
  • google recaptcha

by default it's set to PROD.

Summary by CodeRabbit

  • New Features

    • Add environment setting (DEV/PROD) to control runtime behavior for analytics and security.
  • Chores

    • Analytics scripts and analytics initialization now disabled in DEV.
    • reCAPTCHA initialization and token submission skipped in DEV.
    • Signup requests omit reCAPTCHA header in DEV.
  • Tests

    • Expanded tests to verify environment-dependent loading and behavior.

@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

Walkthrough

Adds a new sandbox.environment config key and uses it at runtime to conditionally load or skip third-party scripts (trustarc, dpal, reCAPTCHA, Segment) and to conditionally include reCAPTCHA headers during signup requests; DEV disables these scripts and token usage.

Changes

Cohort / File(s) Summary
Configuration
app-config.production.yaml, deploy/base/app-config.yaml
Add sandbox.environment entries (PROD in production config, DEV in base/deploy) to drive runtime environment behavior.
Type definitions
plugins/sandbox/config.d.ts
Expose optional environment?: string on Config['sandbox'].
Constants
plugins/sandbox/src/const.ts
Add exported SandboxEnvironment enum (DEV, PROD).
UI / Script injection
plugins/sandbox/src/components/SandboxHeader.tsx
Read sandbox.environment via configApiRef; effect now depends on environment and skips injecting trustarc and dpal scripts when DEV.
Hooks / Initialization
plugins/sandbox/src/hooks/useRecaptcha.ts, plugins/sandbox/src/hooks/useSandboxContext.tsx
useRecaptcha now accepts enabled (default true) and only loads reCAPTCHA when enabled. useSandboxContext reads sandbox.environment, derives isProd, passes it to useRecaptcha, and skips Segment init when not PROD.
API client
plugins/sandbox/src/api/RegistrationBackendClient.tsx
signup() omits requesting/sending a reCAPTCHA token and Recaptcha-Token header when environment is DEV; preserves token acquisition and header in PROD.
Tests
plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx
Update test harness to inject configApiRef via MockConfigApi/TestApiProvider, add DOM cleanup helpers, and add tests asserting analytics script presence for DEV, PROD, and unset environment.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant SandboxHeader
    participant ConfigAPI
    participant DOM
    participant SandboxContext
    participant RecaptchaLoader
    participant SegmentService
    participant RegistrationClient

    Browser->>SandboxHeader: mount
    SandboxHeader->>ConfigAPI: read sandbox.environment
    ConfigAPI-->>SandboxHeader: environment (DEV | PROD)
    alt environment == PROD
        SandboxHeader->>DOM: inject trustarc & dpal scripts
        SandboxHeader->>SandboxContext: set isProd = true
        SandboxContext->>RecaptchaLoader: useRecaptcha(enabled=true) -> load script
        SandboxContext->>SegmentService: init with write key
    else environment == DEV
        SandboxHeader->>DOM: skip injecting scripts
        SandboxHeader->>SandboxContext: set isProd = false
        SandboxContext->>RecaptchaLoader: useRecaptcha(enabled=false) -> skip load
        SandboxContext->>SegmentService: skip init
    end

    Browser->>RegistrationClient: submit signup form
    RegistrationClient->>ConfigAPI: read sandbox.environment
    ConfigAPI-->>RegistrationClient: environment
    alt environment == PROD
        RegistrationClient->>RecaptchaLoader: get token
        RecaptchaLoader-->>RegistrationClient: token
        RegistrationClient->>Browser: POST /signup with Recaptcha-Token header
    else environment == DEV
        RegistrationClient->>Browser: POST /signup without Recaptcha-Token header
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: disable recaptcha and analytics when in dev mode' accurately summarizes the primary changes in the PR, which add environment configuration to disable analytics and recaptcha in DEV mode.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx (1)

153-177: Add one regression test for non-canonical environment values.

To lock down the dev-safety behavior, add a case for values like 'dev' / ' DEV ' so tracker scripts stay disabled unless value is explicitly canonical production.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx` around lines
153 - 177, Add a regression test to ensure non-canonical environment values
(e.g., 'dev', ' DEV ') are treated as non-PROD so analytics scripts remain
disabled: update SandboxHeader.test.tsx by adding a test that calls
renderComponent('My Page Title', 'dev') and another or a parameterized case for
' DEV ' (or trim/normalize variants) and assert
document.getElementById('trustarc') and document.getElementById('dpal') are
null; reference renderComponent and the analytics script ids ('trustarc',
'dpal') to locate the test area and follow the existing test structure used for
'DEV'/'PROD' cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/sandbox/src/hooks/useSandboxContext.tsx`:
- Around line 66-69: Normalize the environment string before comparing so
non-exact variants like "dev", " Dev ", or "dev\n" don't count as production:
change the isProd computation in useSandboxContext (the
configApi/getOptionalString usage that sets isProd and calls useRecaptcha) to
obtain the optional string, apply .trim() and .toUpperCase() and then compare to
'DEV' (i.e., isProd = (env?.trim().toUpperCase() ?? 'PROD') !== 'DEV'); apply
the exact same normalization pattern in the SandboxHeader component where it
parses sandbox.environment (replace the current loose comparison with the same
trim+toUpperCase flow) so both places behave consistently.

---

Nitpick comments:
In `@plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx`:
- Around line 153-177: Add a regression test to ensure non-canonical environment
values (e.g., 'dev', ' DEV ') are treated as non-PROD so analytics scripts
remain disabled: update SandboxHeader.test.tsx by adding a test that calls
renderComponent('My Page Title', 'dev') and another or a parameterized case for
' DEV ' (or trim/normalize variants) and assert
document.getElementById('trustarc') and document.getElementById('dpal') are
null; reference renderComponent and the analytics script ids ('trustarc',
'dpal') to locate the test area and follow the existing test structure used for
'DEV'/'PROD' cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 642e9fc7-d369-4797-92d0-60ddef19cd9a

📥 Commits

Reviewing files that changed from the base of the PR and between 3728a69 and 7e7d53d.

📒 Files selected for processing (7)
  • app-config.production.yaml
  • deploy/base/app-config.yaml
  • plugins/sandbox/config.d.ts
  • plugins/sandbox/src/components/SandboxHeader.tsx
  • plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx
  • plugins/sandbox/src/hooks/useRecaptcha.ts
  • plugins/sandbox/src/hooks/useSandboxContext.tsx

Comment on lines +66 to +69
const configApi = useApi(configApiRef);
const isProd =
(configApi.getOptionalString('sandbox.environment') ?? 'PROD') !== 'DEV';
useRecaptcha(isProd);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fail-open environment parsing can silently re-enable tracking.

Line 67 currently treats anything except exact 'DEV' as production. Values like dev, Dev, or ' DEV ' will enable reCAPTCHA/Segment unexpectedly.

🔧 Proposed fix
-  const isProd =
-    (configApi.getOptionalString('sandbox.environment') ?? 'PROD') !== 'DEV';
+  const environment =
+    (configApi.getOptionalString('sandbox.environment') ?? 'PROD')
+      .trim()
+      .toUpperCase();
+  const isProd = environment === 'PROD';

Please apply the same normalization pattern in plugins/sandbox/src/components/SandboxHeader.tsx (Lines 34-39) to keep behavior consistent.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const configApi = useApi(configApiRef);
const isProd =
(configApi.getOptionalString('sandbox.environment') ?? 'PROD') !== 'DEV';
useRecaptcha(isProd);
const configApi = useApi(configApiRef);
const environment =
(configApi.getOptionalString('sandbox.environment') ?? 'PROD')
.trim()
.toUpperCase();
const isProd = environment === 'PROD';
useRecaptcha(isProd);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/sandbox/src/hooks/useSandboxContext.tsx` around lines 66 - 69,
Normalize the environment string before comparing so non-exact variants like
"dev", " Dev ", or "dev\n" don't count as production: change the isProd
computation in useSandboxContext (the configApi/getOptionalString usage that
sets isProd and calls useRecaptcha) to obtain the optional string, apply .trim()
and .toUpperCase() and then compare to 'DEV' (i.e., isProd =
(env?.trim().toUpperCase() ?? 'PROD') !== 'DEV'); apply the exact same
normalization pattern in the SandboxHeader component where it parses
sandbox.environment (replace the current loose comparison with the same
trim+toUpperCase flow) so both places behave consistently.

Copy link
Contributor

@MikelAlejoBR MikelAlejoBR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking really good to me!

Copy link
Contributor

@rsoaresd rsoaresd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work 🚀

@openshift-ci
Copy link

openshift-ci bot commented Mar 25, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mfrancisc, MikelAlejoBR, rajivnathan, rsoaresd

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [MikelAlejoBR,mfrancisc,rajivnathan,rsoaresd]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@rsoaresd
Copy link
Contributor

/retest

failed after clicking on "Try it", I suspect that could be due to flakiness, but let's see

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/sandbox/src/api/RegistrationBackendClient.tsx`:
- Around line 114-116: Normalize and validate the sandbox.environment string
before computing isDev: read the raw value via
this.configApi.getOptionalString('sandbox.environment'), compute const env =
raw?.trim().toUpperCase(), set isDev = env === 'DEV', and if raw is non-empty
and env is not one of the expected values ('DEV' or 'PROD') emit a warning (use
the class logger or console.warn) so typos like "dev" or " DEV " don't silently
act as PROD; update the isDev computation in RegistrationBackendClient (the
const isDev) accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d41b7bad-1b4f-40cc-a8a5-1a44bc80c4d7

📥 Commits

Reviewing files that changed from the base of the PR and between 7e7d53d and fb000fb.

📒 Files selected for processing (1)
  • plugins/sandbox/src/api/RegistrationBackendClient.tsx

Comment on lines +114 to +116
const isDev =
(this.configApi.getOptionalString('sandbox.environment') ?? 'PROD') ===
'DEV';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Harden sandbox.environment parsing to avoid silent PROD fallback on typos.

Line 115 currently treats any non-DEV value as PROD. Since the config type is free-form string, values like dev or DEV will unexpectedly enable reCAPTCHA. Normalize and validate before branching.

Suggested fix
-    const isDev =
-      (this.configApi.getOptionalString('sandbox.environment') ?? 'PROD') ===
-      'DEV';
+    const environment = (
+      this.configApi.getOptionalString('sandbox.environment') ?? 'PROD'
+    )
+      .trim()
+      .toUpperCase();
+    if (environment !== 'DEV' && environment !== 'PROD') {
+      throw new Error(
+        `Invalid sandbox.environment: "${environment}". Expected "DEV" or "PROD".`,
+      );
+    }
+    const isDev = environment === 'DEV';

As per coding guidelines, "**: Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isDev =
(this.configApi.getOptionalString('sandbox.environment') ?? 'PROD') ===
'DEV';
const environment = (
this.configApi.getOptionalString('sandbox.environment') ?? 'PROD'
)
.trim()
.toUpperCase();
if (environment !== 'DEV' && environment !== 'PROD') {
throw new Error(
`Invalid sandbox.environment: "${environment}". Expected "DEV" or "PROD".`,
);
}
const isDev = environment === 'DEV';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/sandbox/src/api/RegistrationBackendClient.tsx` around lines 114 -
116, Normalize and validate the sandbox.environment string before computing
isDev: read the raw value via
this.configApi.getOptionalString('sandbox.environment'), compute const env =
raw?.trim().toUpperCase(), set isDev = env === 'DEV', and if raw is non-empty
and env is not one of the expected values ('DEV' or 'PROD') emit a warning (use
the class logger or console.warn) so typos like "dev" or " DEV " don't silently
act as PROD; update the isDev computation in RegistrationBackendClient (the
const isDev) accordingly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
plugins/sandbox/src/api/RegistrationBackendClient.tsx (1)

115-117: ⚠️ Potential issue | 🟠 Major

Normalize sandbox.environment before comparison.

Line 115 only treats exact 'DEV' as DEV. Values like 'dev' or ' DEV ' silently behave as PROD and can unexpectedly re-enable reCAPTCHA on dev deployments. Normalize (trim().toUpperCase()) before branching, and warn on unexpected values.

Suggested fix
-    const isDev =
-      (this.configApi.getOptionalString('sandbox.environment') ??
-        SandboxEnvironment.PROD) === SandboxEnvironment.DEV;
+    const rawEnvironment = this.configApi.getOptionalString('sandbox.environment');
+    const environment = (rawEnvironment ?? SandboxEnvironment.PROD).trim().toUpperCase();
+    if (
+      rawEnvironment &&
+      environment !== SandboxEnvironment.DEV &&
+      environment !== SandboxEnvironment.PROD
+    ) {
+      // Prefer class logger if available
+      // eslint-disable-next-line no-console
+      console.warn(
+        `Invalid sandbox.environment value "${rawEnvironment}". Expected DEV or PROD.`,
+      );
+    }
+    const isDev = environment === SandboxEnvironment.DEV;

As per coding guidelines, "**: Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/sandbox/src/api/RegistrationBackendClient.tsx` around lines 115 -
117, The current isDev check in RegistrationBackendClient.tsx uses the raw value
from configApi.getOptionalString('sandbox.environment') which treats only exact
'DEV' as DEV; normalize the value by calling .trim().toUpperCase() before
comparing to SandboxEnvironment.DEV and defaulting to SandboxEnvironment.PROD,
and emit a warning via the logger if the original value is non-empty and not one
of the expected normalized values (e.g., not 'DEV' or 'PROD') so misconfigured
casing/whitespace is visible; update the isDev logic and add the warning near
where isDev is computed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@plugins/sandbox/src/api/RegistrationBackendClient.tsx`:
- Around line 115-117: The current isDev check in RegistrationBackendClient.tsx
uses the raw value from configApi.getOptionalString('sandbox.environment') which
treats only exact 'DEV' as DEV; normalize the value by calling
.trim().toUpperCase() before comparing to SandboxEnvironment.DEV and defaulting
to SandboxEnvironment.PROD, and emit a warning via the logger if the original
value is non-empty and not one of the expected normalized values (e.g., not
'DEV' or 'PROD') so misconfigured casing/whitespace is visible; update the isDev
logic and add the warning near where isDev is computed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d05d2dc2-cfa0-4d26-be23-90c02c03dcdf

📥 Commits

Reviewing files that changed from the base of the PR and between fb000fb and e33db94.

📒 Files selected for processing (5)
  • plugins/sandbox/src/api/RegistrationBackendClient.tsx
  • plugins/sandbox/src/components/SandboxHeader.tsx
  • plugins/sandbox/src/components/__tests__/SandboxHeader.test.tsx
  • plugins/sandbox/src/const.ts
  • plugins/sandbox/src/hooks/useSandboxContext.tsx
✅ Files skipped from review due to trivial changes (1)
  • plugins/sandbox/src/const.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/sandbox/src/hooks/useSandboxContext.tsx
  • plugins/sandbox/src/components/SandboxHeader.tsx

@mfrancisc mfrancisc merged commit 38c57c8 into codeready-toolchain:master Mar 26, 2026
4 of 5 checks passed
@mfrancisc mfrancisc deleted the newenv branch March 26, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants