Skip to content

feat(webexconnect): bringing Webex Connect SDK into webex-js-sdk monorepo - #5201

Open
riag23 wants to merge 1 commit into
webex:nextfrom
riag23:webex-connect
Open

feat(webexconnect): bringing Webex Connect SDK into webex-js-sdk monorepo#5201
riag23 wants to merge 1 commit into
webex:nextfrom
riag23:webex-connect

Conversation

@riag23

@riag23 riag23 commented Aug 31, 2026

Copy link
Copy Markdown

COMPLETES <CAI-8541>

This pull request addresses

The Webex Connect JavaScript SDK (IMIClient, aes, mqttws31, service worker)
previously lived in the separate wxconnect-js-sdk repository, and the Webex Connect
sample app under docs/samples/webexconnect/ vendored its own drifted copy of that
source. There was no single canonical copy of the SDK in this monorepo, no shared
build/test pipeline for it, and no wiring to surface the sample from the docs index.

by making the following changes

  • New private package @webex/webexconnect (packages/webexconnect/): the SDK
    source (src/IMIClient.js, src/aes.js, src/mqttws31.js, sw/sw.js) moved in
    byte-for-byte unmodified as the single canonical copy. Marked "private": true
    so it is never published to npm.
  • Build tooling: a webpack.config.js (production, source-mapped) that emits
    dist/webex-connect-sdk.min.js and dist/sw.min.js, preserving the reserved global
    names (IMI, CryptoJS, MQTT/Paho, etc.) and injecting the JS_SDK_VERSION banner.
  • Sample de-duplication: scripts/sync-sample.js runs after build:src and copies
    the four build artifacts into docs/samples/webexconnect/, so the sample now consumes
    the canonical build instead of its own vendored SDK source. Added the Webex Connect
    sample and linked it from docs/index.html and docs/samples/index.html.
  • CI workflow (.github/workflows/webexconnect-deploy.yml): builds, tests, and
    assembles the SDK bundles + source maps as artifacts on workflow_dispatch / tag push.
    It intentionally never triggers on push to next and the publish step is
    deliberately omitted (left as a TODO) pending security/legal review and sign-off.
  • Deploy matrix guard (.github/workflows/deploy.yml): added an explicit sed
    filter so @webex/webexconnect can never leak into the deploy/publish matrix even if
    private: true were ever accidentally removed.
  • Registered ./packages/webexconnect in the root workspace list.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

  • Package build: yarn workspace @webex/webexconnect run build:src produces
    dist/webex-connect-sdk.min.js, dist/sw.min.js, and their source maps, and syncs
    them into docs/samples/webexconnect/.
  • Automated tests: yarn workspace @webex/webexconnect run test — ESLint style
    check plus the Jest smoke test, which evaluates the built bundle and asserts the IMI
    global and core public constructors (ICConfig, ICMessage, ICDeviceProfile,
    IMIconnect) are exposed.
  • Sample app: loaded docs/samples/webexconnect/ in minified mode against the freshly
    built canonical bundle and verified registration/connection and messaging flows.
  • CI: confirmed the SDK source (src/**/*.js) is byte-for-byte identical to the
    originals and that the private package is excluded from the deploy matrix.

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was used to create a draft that was subsequently customized or modified
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Please Specify: Cursor
  • This PR is related to
    • Feature

I certified that

  • I have read and followed contributing guidelines
  • I discussed changes with code owners prior to submitting this pull request
  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the documentation accordingly
ezgif-777285218568ccbe

@riag23
riag23 requested a review from a team as a code owner August 31, 2026 12:12
@gitguardian

gitguardian Bot commented Aug 31, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0d1030262

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +84 to +86
ev.waitUntil(async () => {
self.clients.claim();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass a promise to the activation event

When the service worker first activates, waitUntil receives an async function object rather than a promise, so that function is never invoked and clients.claim() does not run. The activation event can also throw a TypeError, leaving already-open pages uncontrolled until their next navigation; pass the promise returned by self.clients.claim() directly to waitUntil.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

@@ -0,0 +1,57 @@
(async function include_sdk_source_files() {
let appConfig = await fetch("app.config.json").then(response => response.json());
let env = appConfig["sourceCodeType"] || IMISourceCodeType.Source;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Define the source-code enum before using its fallback

When app.config.json omits or empties sourceCodeType, the intended default path evaluates IMISourceCodeType.Source while the later const IMISourceCodeType is still in its temporal dead zone. This throws a ReferenceError and prevents the SDK scripts from loading, so the enum must be initialized before this fallback expression.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d30b1a393e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1889 to +1892
var sw = navigator.serviceWorker.controller;
if (sw) {
sw.postMessage(msg);
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Send registration to the scoped SDK worker

When an integration page is already controlled by another service worker, navigator.serviceWorker.controller refers to that host worker, not the Webex Connect worker registered under root + 'sw/' + appId + '/'. This branch posts REGISTER_APP_CLIENT to the unrelated worker and returns without using the scoped registration, leaving the SDK worker's client map empty; its filtered clients.matchAll() then excludes the page from message delivery and notification-click routing. Resolve the registration by scope instead of preferring the page controller.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

Comment on lines +417 to +418
event.waitUntil(Promise.all([clickReadDeliveryFetchPromise, clientsPromise])
.then(async ([resp, clientList]) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Decouple notification navigation from the tracking fetch

When the tracking endpoint is unreachable, such as while the user is offline, this Promise.all rejects before the callback that focuses an existing client or opens the notification URL runs. The notification is already closed, so clicking it appears to do nothing; navigation should proceed even if the best-effort read-receipt request fails.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 460a54323b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +7930 to +7931
if (!messaging) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Convert the OAuth lifetime into an absolute expiry

When the token endpoint returns the standard expires_in lifetime (for example, 3600 seconds), storing it directly as expiresAt makes _isTokenValid() compare the current Unix timestamp against 3600, so every newly minted token is immediately considered expired. In token-exchange mode _getAjaxHeader() consequently omits Authorization, including from the registration request; compute the expiry as the current Unix time plus expires_in.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

Comment on lines +7029 to +7030
if (self.appId) {
swScope = root + 'sw/' + self.appId + '/';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope the worker so it controls the integration page

When the integration page is served at the configured root, as in the included sample, the child scope root + 'sw/' + appId + '/' does not contain that page. Service-worker fetch events are selected by the requesting client's URL rather than the request URL, so the fetch listener in sw/sw.js never sees the page's /deliveryupdate?rr=... requests and its duplicate read-receipt suppression is inactive; use a scope that covers the integration page or move that interception out of this worker.

Useful? React with 👍 / 👎.

Comment on lines +3572 to +3573
setRoot: function (folder) {
self.root = folder;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the ICConfig instance in its setters

When a caller invokes setRoot() after constructing ICConfig, self resolves to the browser global rather than the constructor-local variable, so this writes window.root while getRoot() continues returning the old instance value. Service-worker URLs and scopes therefore still use the previous root; assign through this here and in the sibling setAssetPath() and setShouldRequestNotificationPermission() setters.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only: bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

Comment on lines +1 to +2
(async function include_sdk_source_files() {
let appConfig = await fetch("app.config.json").then(response => response.json());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make sample startup wait for the SDK-ready event

When app.config.json is slower than the page's other resources, this async IIFE yields at fetch() and allows parsing and the window load event to finish before the SDK script is even appended. api-demo.html starts IMI.IMIconnect from its load handler without listening for IMISdkReady, so that timing produces IMI is not defined and the demo never starts; expose/await the loader promise or make every startup path wait for the ready event.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This PR is Phase 1 only bring the Webex Connect SDK into the monorepo as a private package, with the SDK source copied unmodified.

@rarajes2 rarajes2 added the validated If the pull request is validated for automation. label Sep 2, 2026
@riag23 riag23 changed the title Webex Connect SDK → webex-js-sdk: Phase 1, bringing SDK into monorepo feat(webexconnect): Webex Connect SDK → webex-js-sdk: Phase 1, bringing SDK into monorepo Sep 3, 2026
@riag23 riag23 changed the title feat(webexconnect): Webex Connect SDK → webex-js-sdk: Phase 1, bringing SDK into monorepo feat(webexconnect): bringing Webex Connect SDK into webex-js-sdk monorepo Sep 3, 2026
@riag23 riag23 closed this Sep 3, 2026
@riag23 riag23 reopened this Sep 3, 2026
…repo

Add a private @webex/webexconnect package with the canonical SDK source,
sample app, and build workflow. Sample credentials are placeholders, and
bundled min.js/source maps are not committed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot removed the validated If the pull request is validated for automation. label Sep 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df44ba942c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +21 to +23
"test": "yarn test:style && yarn test:unit",
"test:style": "eslint 'src/**/*.js'",
"test:unit": "jest"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Build the bundle before invoking the smoke test

On a clean checkout, running the documented yarn workspace @webex/webexconnect run test command reaches Jest without first creating dist/webex-connect-sdk.min.js; dist/ is gitignored, and smoke.test.js immediately reads that file, so the test command fails with ENOENT unless the developer happens to have built previously. Add a pre-test build step or make the test generate the bundle it evaluates.

Useful? React with 👍 / 👎.

module.exports = {
rootDir: '.',
testEnvironment: 'node',
testMatch: ['<rootDir>/test/**/*.test.js'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wire the routing test into a test command

The added UA-routing suite lives at docs/samples/webexconnect/tests/push-routing.test.js, but this Jest pattern only discovers files under packages/webexconnect/test/. The PR unit workflow invokes this workspace's test:unit script, and a repo-wide search finds no node --test invocation or other reference to the routing test, so all seven routing cases are silently skipped in CI; add an explicit command for this Node test or move it into a discovered suite.

Useful? React with 👍 / 👎.

@riag23 riag23 added the validated If the pull request is validated for automation. label Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

validated If the pull request is validated for automation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants