Skip to content

chore: add intercom (IN-1028)#3945

Open
joanagmaia wants to merge 2 commits intomainfrom
chore/add-intercom
Open

chore: add intercom (IN-1028)#3945
joanagmaia wants to merge 2 commits intomainfrom
chore/add-intercom

Conversation

@joanagmaia
Copy link
Contributor

@joanagmaia joanagmaia commented Mar 23, 2026

This pull request introduces Intercom integration into the frontend application, enabling user-specific Intercom chat support based on authentication state. The main changes include configuration additions, dynamic script loading and lifecycle management for Intercom, and hooks into the authentication flow to boot and shut down Intercom as users log in or out.

Intercom Integration

  • Added Intercom configuration to environment variables and application config, including appId, API base, and Auth0 claim keys for user identification. [1] [2] [3]
  • Implemented a new utility module frontend/src/utils/intercom/index.ts to handle dynamic loading, booting, updating, and shutdown of the Intercom widget, with support for JWT-based identity verification.

Authentication Flow Updates

  • Updated authentication actions to boot Intercom with user details and JWT after login, and to shut down Intercom on logout, ensuring proper lifecycle management tied to user sessions. [1] [2] [3]

Note

Medium Risk
Adds a third-party Intercom widget that boots using Auth0-provided user/JWT claims and injects an external script at runtime, which can affect auth/session behavior and client-side performance. Failures are mostly contained to logging, but misconfiguration could prevent chat from loading or leak incorrect identity metadata.

Overview
Adds Intercom support to the frontend, including a new config.intercom section and a VUE_APP_INTERCOM_APP_ID env var for configuring the widget.

Wires Intercom into the auth flow by booting the widget after Auth0 user hydration (using configured Auth0 claims for user_id and intercom_user_jwt) and shutting it down on logout.

Introduces a new utils/intercom module that dynamically loads the Intercom script, manages boot/update/shutdown state, and supports JWT-based identity verification via window.intercomSettings.

Written by Cursor Bugbot for commit b0e6cb1. This will update automatically on new commits. Configure here.

Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Intercom to the frontend and wires it into the auth lifecycle so the widget boots for authenticated users and shuts down on logout.

Changes:

  • Added Intercom configuration (env + app config) including Auth0 claim keys.
  • Introduced an Intercom utility for script loading + boot/update/shutdown.
  • Hooked Intercom boot/shutdown into the authentication flow (login/logout).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
frontend/src/utils/intercom/index.ts New Intercom loader/boot/update/shutdown utility module.
frontend/src/modules/auth/store/auth.actions.ts Boots Intercom after login and shuts it down on logout.
frontend/src/config.js Adds intercom config (appId, api base, Auth0 claim keys).
frontend/.env.dist.local Adds a distribution env var for Intercom app id.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +91 to +95
// Set JWT in intercomSettings before boot — required for identity verification
if (options.intercom_user_jwt) {
window.intercomSettings = window.intercomSettings || {};
window.intercomSettings.intercom_user_jwt = options.intercom_user_jwt;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

intercom_user_jwt is stripped out of the payload passed to Intercom('boot', ...). If identity verification relies on providing intercom_user_jwt in the boot call (as Intercom’s standard flow does), this can lead to users being booted without verification. Include intercom_user_jwt in the boot payload (or pass window.intercomSettings as the boot object after merging user fields) so verification is reliably applied.

Copilot uses AI. Check for mistakes.
Comment on lines +111 to +115
const { intercom_user_jwt: _jwt, ...bootOptions } = options;
window.Intercom('boot', {
api_base: config.intercom.apiBase,
app_id: config.intercom.appId,
...bootOptions,
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

intercom_user_jwt is stripped out of the payload passed to Intercom('boot', ...). If identity verification relies on providing intercom_user_jwt in the boot call (as Intercom’s standard flow does), this can lead to users being booted without verification. Include intercom_user_jwt in the boot payload (or pass window.intercomSettings as the boot object after merging user fields) so verification is reliably applied.

Suggested change
const { intercom_user_jwt: _jwt, ...bootOptions } = options;
window.Intercom('boot', {
api_base: config.intercom.apiBase,
app_id: config.intercom.appId,
...bootOptions,
window.Intercom('boot', {
api_base: config.intercom.apiBase,
app_id: config.intercom.appId,
...options,

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +78
if (!config.intercom.appId) {
console.info('Intercom: Disabled (no appId configured)');
reject(new Error('No Intercom app ID configured'));
return;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Treating “Intercom disabled by configuration” as a rejected Promise forces callers to handle this as an error path, even though it’s an expected state. Prefer resolving as a no-op when appId is missing (and/or exposing an isEnabled() helper) so downstream auth flows don’t need to special-case this.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +58
script.onerror = (error) => {
isLoading = false;
console.error('Intercom: Failed to load script', error);
};
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

If the script fails quickly (onerror), boot() will still poll for up to 10s before rejecting, which delays auth lifecycle completion and adds avoidable background work. Consider making loadScript() return a shared Promise (cached across calls) that resolves on onload and rejects on onerror, and have boot() await that instead of polling; this will fail fast, simplify control flow, and avoid repeated intervals/timeouts for concurrent boots.

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +132
const checkLoaded = setInterval(() => {
if (isLoaded && window.Intercom) {
clearInterval(checkLoaded);
clearTimeout(timeoutHandle);

if (isBooted) {
const { intercom_user_jwt: _jwt, ...updateOptions } = options;
update(updateOptions);
resolve();
return;
}

isBooted = true;
try {
const { intercom_user_jwt: _jwt, ...bootOptions } = options;
window.Intercom('boot', {
api_base: config.intercom.apiBase,
app_id: config.intercom.appId,
...bootOptions,
});
resolve();
} catch (error) {
isBooted = false;
console.error('Intercom: Boot failed', error);
reject(error);
}
}
}, 100);

const timeoutHandle = setTimeout(() => {
clearInterval(checkLoaded);
if (!isBooted) {
isLoading = false;
reject(new Error('Intercom script failed to load'));
}
}, 10000);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

If the script fails quickly (onerror), boot() will still poll for up to 10s before rejecting, which delays auth lifecycle completion and adds avoidable background work. Consider making loadScript() return a shared Promise (cached across calls) that resolves on onload and rejects on onerror, and have boot() await that instead of polling; this will fail fast, simplify control flow, and avoid repeated intervals/timeouts for concurrent boots.

Copilot uses AI. Check for mistakes.
email: user.email,
intercom_user_jwt: intercomJwt,
}).catch((error: any) => {
console.error('Intercom: Boot failed', error);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Logging the raw error object can inadvertently include sensitive context (depending on how errors are produced/serialized), and this path is triggered during authentication. Prefer logging a sanitized message (e.g., error?.message) and avoid dumping full objects that might contain user identifiers or token-related info.

Suggested change
console.error('Intercom: Boot failed', error);
console.error('Intercom: Boot failed:', (error && error.message) ? error.message : String(error));

Copilot uses AI. Check for mistakes.
VUE_APP_CONVERSATIONS_PUBLIC_URL=http://localhost:3000
VUE_APP_NANGO_URL=http://localhost:3003
VUE_APP_ENV=local
VUE_APP_INTERCOM_APP_ID=mxl90k6y
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

.env.dist.local is typically a template; committing a concrete app id can cause accidental usage against the wrong Intercom workspace in local/dev setups. Consider leaving this blank or using an obvious placeholder value (with a short comment) to encourage explicit configuration per environment.

Suggested change
VUE_APP_INTERCOM_APP_ID=mxl90k6y
# Set your Intercom app id for this environment (leave blank if not used).
VUE_APP_INTERCOM_APP_ID=

Copilot uses AI. Check for mistakes.
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

boot,
update,
shutdown,
});
Copy link

Choose a reason for hiding this comment

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

Exported useIntercom composable is never used

Low Severity

The useIntercom composable is exported but never imported anywhere in the codebase. The auth actions module directly imports boot and shutdown instead. This is dead code that adds unnecessary surface area to the module.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants