@salesforce/retail-react-app 10.2.0-nightly-20260812155833 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,7 +1,4 @@
1
- ## v10.2.0-dev (Jul 13, 2026)
2
- - [Feature] Forward two backend-gating signals on the Commerce Client shopper-agent widget's `routingAttributes`: `clientVersion` (sourced from `cc_cdnVersion`, so the runtime can gate rich components on the client's capability version; omitted when unset) and `isCartMgmtSupported` (string `'true'`/`'false'`, default `'false'`, read from `cc_routingAttributes`). Brings the PWA commerce-client path to parity with the SFRA cartridge.
3
- - [Feature] Enable shopper identity (customer context) for the Commerce Client (Cimulate) shopper-agent provider. Unlike MIAW, Commerce Client widgets do not expose `getAuthLinkKey`, so the browser extracts the Commerce Client JWT from the deployment-scoped `cim_af_ct_<orgId>_<embeddedServiceName>` key (`sessionStorage` is authoritative; `localStorage` is a compatibility fallback) and POSTs it to a new same-origin proxy `POST /api/agent/authlink` (`registerAuthLinkRoute`, mounted in `app/ssr.js`). The proxy calls SCRT2's `/iamessage/api/v2/authorization/authlink` with an `Authorization: Bearer <jwt>` header to obtain an `auth_link_key`; the SCRT2 origin is read server-side from `scrt2Url` in `COMMERCE_AGENT_SETTINGS` (a different host from Core's My Domain) and validated against a Salesforce domain allowlist, with an Origin/Referer CSRF check, to prevent SSRF. The `auth_link_key` is then forwarded to the existing Token Bridge to bind the conversation to the shopper's SLAS session. Linking is idempotent — deduped by `conversationId` + SLAS identity — and re-runs both on a new conversation (`onCimulateWidgetReady`) and on a SLAS identity transition (guest ↔ registered / account switch), gated on `my_domain` resolution. [#3943](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3943)
4
- - [Bugfix] Fix the Shopper Agent Token Bridge proxy (`/api/agent/identity/bridge`) failing to reach Core in two cases: (1) same-origin POSTs were rejected with 403 `FORBIDDEN_ORIGIN` because the CSRF Origin check compared `URL.hostname` (no port) against `req.headers.host` (with port), so a non-standard dev port like `localhost:3000` never matched — now compares `URL.host`; (2) a scheme-less My Domain value (e.g. `orgfarm-1234.my.salesforce.com`) was rejected as 400 `UNTRUSTED_MYDOMAIN` because `new URL()` threw on it — the value is now normalized to an absolute `https://` origin before validation and fetch. The `AGENT_MYDOMAIN` environment variable configures the My Domain.
1
+ ## v10.2.0 (Aug 12, 2026)
5
2
  - [Bugfix] Fix the Data Cloud recommender catalog event field name: `personalizationContextId` → `personalizationContentId`. The official `@salesforce/cc-datacloud-typescript` SDK type and Salesforce docs both define `personalizationContentId` (Content); the `Context` spelling did not match, so the recommender UUID (`__recoUUID`) was sent under a key Data Cloud does not recognize and is expected to be dropped on ingest.
6
3
  - [Feature] Add `cc_showFab` for the Commerce Client shopper-agent widget: when `'true'`, renders a floating action button at `cc_widgetPosition` that opens the agent panel and hides while it is open. Defaults to `'false'`.
7
4
  - [Bugfix] Honor `cc_dialogFullHeight: 'false'`, which was previously dropped from the widget options so the bundle's full-height default always won.
@@ -31,14 +31,12 @@ import {
31
31
  getPersistedCommerceClientOpenState,
32
32
  persistCommerceClientOpenState,
33
33
  resetEmbeddedMessagingForCommerceSessionChange,
34
- resolveCommerceClientRoutingAttributes,
35
34
  resolveCommerceClientScriptUrl,
36
35
  validateCommerceClientAgentSettings
37
36
  } from '@salesforce/retail-react-app/app/utils/shopper-agent-utils'
38
37
  import {resolveCommerceClientOverrideOptions} from '@salesforce/retail-react-app/app/utils/commerce-client-overrides'
39
38
  import {callTokenBridge} from '@salesforce/retail-react-app/app/components/shopper-agent/token-bridge'
40
39
  import CommerceClientFab from '@salesforce/retail-react-app/app/components/shopper-agent/commerce-client-fab'
41
- import {callAuthLinkProxy} from '@salesforce/retail-react-app/app/components/shopper-agent/auth-link-proxy'
42
40
 
43
41
  const onClient = typeof window !== 'undefined'
44
42
 
@@ -209,7 +207,6 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
209
207
  salesforceOrgId,
210
208
  commerceOrgId,
211
209
  siteId,
212
- provider = 'miaw',
213
210
  enableConversationContext = 'false',
214
211
  conversationContext = [],
215
212
  enableAgentFromFloatingButton = 'true'
@@ -236,12 +233,6 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
236
233
  /**
237
234
  * Reset embedded messaging whenever customerType changes (login, logout, registration).
238
235
  * This ensures the chat context is cleared when user authentication state changes.
239
- *
240
- * MIAW-only: resetEmbeddedMessagingForCommerceSessionChange() drives
241
- * window.embeddedservice_bootstrap.userVerificationAPI.clearSession, which
242
- * exists only for the Salesforce Embedded Messaging (MIAW) provider. The
243
- * Commerce Client provider re-links its conversation in place instead of
244
- * clearing the session, so we no-op here for any non-MIAW provider.
245
236
  */
246
237
  useEffect(() => {
247
238
  const prev = prevCommerceCustomerTypeRef.current
@@ -252,11 +243,11 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
252
243
  return
253
244
  }
254
245
 
255
- // Reset on any customerType change (login, logout, register) — MIAW only.
256
- if (prev !== customerType && provider === 'miaw') {
246
+ // Reset on any customerType change (login, logout, register)
247
+ if (prev !== customerType) {
257
248
  resetEmbeddedMessagingForCommerceSessionChange()
258
249
  }
259
- }, [customerType, provider])
250
+ }, [customerType])
260
251
 
261
252
  const formatMessageRef = useRef(formatMessage)
262
253
  formatMessageRef.current = formatMessage
@@ -596,11 +587,6 @@ const DEFAULT_COMMERCE_CLIENT_PANEL_WIDTH = '420px'
596
587
  *
597
588
  * @param {Object} props - Component props
598
589
  * @param {Object} props.commerceAgentConfiguration - Commerce agent configuration object
599
- * @param {Object} props.lastAuthLinkKeyRef - Last successful conversation/shopper link key
600
- * @param {Object} props.lastCommerceClientJWTRef - Last successfully linked Commerce Client JWT
601
- * @param {Object} props.authLinkGenerationRef - Monotonic auth-link attempt generation
602
- * @param {Object} props.authLinkQueueRef - Serialized auth-link operation queue
603
- * @param {Object} props.lastAttemptedCommerceClientJWTRef - JWT used by the latest auth-link attempt
604
590
  * @param {string} props.commerceAgentConfiguration.scrt2Url - SCRT2 URL (passed to `messagingConfig.scrt2Url`)
605
591
  * @param {string} props.commerceAgentConfiguration.salesforceOrgId - Salesforce org ID (passed to `messagingConfig.orgId`)
606
592
  * @param {string} [props.commerceAgentConfiguration.cc_esDeveloperName] - Embedded Service developer name
@@ -623,19 +609,12 @@ const DEFAULT_COMMERCE_CLIENT_PANEL_WIDTH = '420px'
623
609
  * @param {string} [props.commerceAgentConfiguration.cc_isOpen] - When 'true', the widget opens automatically on page load (forwarded as `componentConfig.isOpen`); defaults to 'false'
624
610
  * @param {string} [props.commerceAgentConfiguration.cc_isDevelopment] - When 'true', logs widget events to the console (forwarded as `isDevelopment`)
625
611
  * @param {Object} [props.commerceAgentConfiguration.cc_theme] - Partial theme overrides for the widget
626
- * @param {Object} [props.commerceAgentConfiguration.cc_routingAttributes] - Optional Agentforce routing attributes forwarded to the widget as `routingAttributes`. Augmented with `isCartMgmtSupported` (string `'true'`/`'false'`, default `'false'`) and, unless a `commerceClientScriptSourceUrl` override is set, `clientVersion` (from `cc_cdnVersion`) for backend component gating
612
+ * @param {Object} [props.commerceAgentConfiguration.cc_routingAttributes] - Optional Agentforce routing attributes forwarded to the widget as `routingAttributes`
627
613
  * @param {string} [props.commerceAgentConfiguration.cc_overridesUrl] - Optional HTTPS URL of a component override script, forwarded as `overridesUrl`
628
614
  * @param {Object} [props.commerceAgentConfiguration.cc_overrides] - Optional inline map of widget override keys (e.g. `ProductTile`) to already-registered custom element tag names, forwarded as `overrides`. Mutually exclusive with `cc_overridesUrl`, which it takes precedence over
629
615
  * @returns {JSX.Element} A container element the Commerce Client widget is rendered into
630
616
  */
631
- const CommerceClientAgentWindow = ({
632
- commerceAgentConfiguration,
633
- lastAuthLinkKeyRef,
634
- lastCommerceClientJWTRef,
635
- authLinkGenerationRef,
636
- authLinkQueueRef,
637
- lastAttemptedCommerceClientJWTRef
638
- }) => {
617
+ const CommerceClientAgentWindow = ({commerceAgentConfiguration}) => {
639
618
  const {
640
619
  scrt2Url,
641
620
  salesforceOrgId,
@@ -657,8 +636,6 @@ const CommerceClientAgentWindow = ({
657
636
  cc_enableDownloadTranscript = 'true',
658
637
  cc_theme,
659
638
  cc_searchConfig,
660
- cc_cdnVersion,
661
- commerceClientScriptSourceUrl,
662
639
  cc_routingAttributes,
663
640
  cc_overridesUrl,
664
641
  cc_overrides
@@ -666,319 +643,6 @@ const CommerceClientAgentWindow = ({
666
643
 
667
644
  // Loads the Commerce Client messaging UMD bundle, which exposes window.CimulateMessaging.
668
645
  const scriptLoadStatus = useScript(resolveCommerceClientScriptUrl(commerceAgentConfiguration))
669
- const {formatMessage} = useIntl()
670
- const toast = useToast()
671
- const toastRef = useRef(toast)
672
- toastRef.current = toast
673
-
674
- // Customer details and auth tokens for Commerce Client session init
675
- const {getTokenWhenReady} = useAccessToken()
676
- const getTokenWhenReadyRef = useRef(getTokenWhenReady)
677
- getTokenWhenReadyRef.current = getTokenWhenReady
678
-
679
- const {organizationId, siteId: configSiteId} = useConfig()
680
-
681
- // Fetch my_domain from the Shopper Configurations API. Auth-linking calls
682
- // Core (via the Token Bridge), which is only reachable once my_domain has
683
- // resolved, so we gate performAuthLink on it exactly like the MIAW provider.
684
- const {data: configurationsData} = useConfigurations({})
685
- const myDomain = configurationsData?.configurations?.find(
686
- (config) => config.configurationType === 'globalConfiguration' && config.id === 'my_domain'
687
- )?.value
688
-
689
- const configRef = useRef({organizationId, configSiteId, myDomain})
690
- configRef.current = {organizationId, configSiteId, myDomain}
691
-
692
- const formatMessageRef = useRef(formatMessage)
693
- formatMessageRef.current = formatMessage
694
-
695
- // --- Auth-link triggers ---
696
- // The SLAS shopper identity. Auth-linking binds the Commerce Client
697
- // conversation to THIS shopper, so a change on either side (new
698
- // conversation, or guest<->registered / account switch) must re-link.
699
- const {usid} = useUsid()
700
- const {customerType} = useCustomerType()
701
-
702
- // Latest identity values, read from a ref so the (stable, mount-once)
703
- // window listeners always see current values without re-subscribing.
704
- const identityRef = useRef({usid, customerType})
705
- identityRef.current = {usid, customerType}
706
-
707
- const commerceClientStorageScope = `${salesforceOrgId}_${
708
- cc_esDeveloperName || embeddedServiceName
709
- }`
710
- const commerceClientTokenKey = `cim_af_ct_${commerceClientStorageScope}`
711
- const commerceClientConversationKey = `cim_af_conv_${commerceClientStorageScope}`
712
- const isCommerceClientReady =
713
- !scriptLoadStatus?.error &&
714
- (scriptLoadStatus?.loaded || (onClient && Boolean(window.CimulateMessaging)))
715
- const effectiveScriptLoadStatus = useMemo(
716
- () => ({loaded: isCommerceClientReady, error: Boolean(scriptLoadStatus?.error)}),
717
- [isCommerceClientReady, scriptLoadStatus?.error]
718
- )
719
-
720
- // The helpers below feed the two re-link triggers (new conversation, SLAS
721
- // identity change), which both route through the idempotent performAuthLink().
722
-
723
- /**
724
- * Resolve a stable identifier for the current SLAS shopper. Guests share
725
- * the sentinel "guest" so a guest re-open does not look like a new identity,
726
- * while a login/logout/account-switch produces a different value.
727
- */
728
- const getSlasIdentity = () => {
729
- const {usid: currentUsid, customerType: currentType} = identityRef.current
730
- if (currentType === 'registered') {
731
- return `registered:${currentUsid || ''}`
732
- }
733
- return 'guest'
734
- }
735
-
736
- /**
737
- * Read the Commerce Client conversationId from this widget's scoped session
738
- * key (value shape: {"conversationId":"...","storedAt":...}). Returns null
739
- * if not present yet (e.g. conversation still being created).
740
- */
741
- const readConversationId = () => {
742
- try {
743
- const value = window.sessionStorage.getItem(commerceClientConversationKey)
744
- return value ? JSON.parse(value)?.conversationId || null : null
745
- } catch (err) {
746
- console.error('[Commerce Client] Failed to read conversationId', err)
747
- return null
748
- }
749
- }
750
-
751
- /**
752
- * Extract this widget's Commerce Client JWT from its scoped cim_af_ct_* key.
753
- * The session-scoped value is authoritative; localStorage is a compatibility
754
- * fallback for SDK versions that persist the same scoped key there.
755
- */
756
- const extractCommerceClientJWT = (excludedJWT = null) => {
757
- const stores = [window.sessionStorage, window.localStorage]
758
- for (const store of stores) {
759
- try {
760
- const data = JSON.parse(store.getItem(commerceClientTokenKey) || 'null')
761
- const accessToken = data?.accessToken
762
- if (typeof accessToken === 'string' && accessToken.trim().length > 0) {
763
- return accessToken !== excludedJWT ? accessToken : null
764
- }
765
- } catch (err) {
766
- console.error('[Commerce Client] Failed to parse storage for JWT', err)
767
- }
768
- }
769
- return null
770
- }
771
-
772
- /**
773
- * Poll storage for the Commerce Client JWT with capped exponential backoff.
774
- * The SDK stores the JWT asynchronously after a conversation is created, so
775
- * on the `onCimulateWidgetReady` signal the token may not exist yet.
776
- *
777
- * The per-attempt delay is capped (`maxDelay`) and we do NOT sleep after the
778
- * final check, so the worst-case wait is bounded (~4.5s with the defaults)
779
- * rather than growing unbounded with the retry count. The token normally
780
- * lands within the first second; the cap only affects the give-up path.
781
- */
782
- const waitForCommerceClientJWT = async (
783
- excludedJWT = null,
784
- maxRetries = 8,
785
- initialDelay = 100,
786
- maxDelay = 1000
787
- ) => {
788
- for (let attempt = 0; attempt < maxRetries; attempt++) {
789
- const jwt = extractCommerceClientJWT(excludedJWT)
790
- if (jwt) return jwt
791
- // No point sleeping after the last check — nothing reads the result.
792
- if (attempt === maxRetries - 1) break
793
- const delay = Math.min(maxDelay, initialDelay * Math.pow(2, attempt))
794
- await new Promise((resolve) => setTimeout(resolve, delay))
795
- }
796
- return null
797
- }
798
-
799
- /**
800
- * Idempotently link the current Commerce Client conversation to the current
801
- * SLAS shopper. Deduped by `${conversationId}:${slasIdentity}` — a no-op if
802
- * that exact pair was already linked successfully.
803
- *
804
- * @param {Object} opts
805
- * @param {string} opts.reason - Diagnostic label for the triggering signal.
806
- */
807
- const performAuthLink = ({reason, excludedJWT = null}) => {
808
- const generation = ++authLinkGenerationRef.current
809
- const scheduledJWT = extractCommerceClientJWT()
810
- if (scheduledJWT) {
811
- lastAttemptedCommerceClientJWTRef.current = scheduledJWT
812
- }
813
- const run = async () => {
814
- const {organizationId: orgId, configSiteId: sid, myDomain: domain} = configRef.current
815
- if (!orgId || !sid) {
816
- console.error('[Commerce Client] performAuthLink: missing organizationId or siteId')
817
- return
818
- }
819
-
820
- // The Token Bridge reaches Core, which needs my_domain resolved. The mount
821
- // is already gated on !isConfigurationsLoading, so this is a defensive skip
822
- // rather than a call to the bridge with an unresolved domain.
823
- if (!domain) {
824
- console.warn(
825
- `[Commerce Client] performAuthLink(${reason}): my_domain not resolved yet`
826
- )
827
- return
828
- }
829
-
830
- const slasIdentity = getSlasIdentity()
831
-
832
- try {
833
- const commerceClientJWT = await waitForCommerceClientJWT(excludedJWT)
834
- if (!commerceClientJWT) {
835
- console.warn(
836
- `[Commerce Client] performAuthLink(${reason}): no JWT after polling`
837
- )
838
- return
839
- }
840
- lastAttemptedCommerceClientJWTRef.current = commerceClientJWT
841
- if (generation !== authLinkGenerationRef.current) return
842
-
843
- // Dedup on (conversation, shopper). conversationId is read here — after
844
- // the JWT poll — so a still-creating conversation has time to appear.
845
- // A new-conversation trigger waits for a different JWT before reaching
846
- // this guard, so it can bypass a still-stale conversationId safely.
847
- const conversationId = readConversationId()
848
- const linkKey = `${conversationId || 'unknown'}:${slasIdentity}`
849
- if (!excludedJWT && lastAuthLinkKeyRef.current === linkKey) {
850
- // Already linked this exact (conversation, shopper) pair.
851
- console.warn(
852
- `[Commerce Client] performAuthLink(${reason}): already linked, skipping`
853
- )
854
- return
855
- }
856
-
857
- const isHttpOnly =
858
- typeof window !== 'undefined'
859
- ? window.__MRT_ENABLE_HTTPONLY_SESSION_COOKIES__ === 'true'
860
- : process.env.MRT_ENABLE_HTTPONLY_SESSION_COOKIES === 'true'
861
-
862
- const slasAccessToken = isHttpOnly
863
- ? undefined
864
- : await getTokenWhenReadyRef.current()
865
- if (generation !== authLinkGenerationRef.current) return
866
-
867
- // Step 1: auth link key from SCRT. The SCRT authlink endpoint
868
- // authenticates with the Commerce Client JWT (Bearer) alone — it
869
- // needs neither the siteId nor the conversationId.
870
- const authLinkResponse = await callAuthLinkProxy({commerceClientJWT})
871
- if (generation !== authLinkGenerationRef.current) return
872
- const authLinkKey = authLinkResponse?.auth_link_key || authLinkResponse?.authLinkKey
873
- if (!authLinkKey || typeof authLinkKey !== 'string') {
874
- console.error(
875
- `[Commerce Client] performAuthLink(${reason}): no auth link key`,
876
- authLinkResponse
877
- )
878
- return
879
- }
880
-
881
- // Step 2: token bridge (links conversation to the SLAS shopper).
882
- // Operations are serialized so the newest identity is the final
883
- // server-side mutation even when an older request was already sent.
884
- const result = await callTokenBridge({authLinkKey, slasAccessToken, siteId: sid})
885
- if (generation !== authLinkGenerationRef.current) return
886
- if (result.status !== HTTP_OK) {
887
- const errorCode = result.body?.error || `HTTP_${result.status}`
888
- console.error(
889
- `[Commerce Client] performAuthLink(${reason}): token bridge failed`,
890
- {
891
- status: result.status,
892
- error: errorCode
893
- }
894
- )
895
- toastRef.current({
896
- title: formatMessageRef.current(SESSION_INIT_ERROR_MESSAGE),
897
- status: 'error'
898
- })
899
- return
900
- }
901
-
902
- lastAuthLinkKeyRef.current = linkKey
903
- lastCommerceClientJWTRef.current = commerceClientJWT
904
- } catch (error) {
905
- if (generation !== authLinkGenerationRef.current) return
906
- console.error(`[Commerce Client] performAuthLink(${reason}) threw`, error)
907
- toastRef.current({
908
- title: formatMessageRef.current(SESSION_INIT_ERROR_MESSAGE),
909
- status: 'error'
910
- })
911
- }
912
- }
913
-
914
- const queued = authLinkQueueRef.current.then(run, run)
915
- authLinkQueueRef.current = queued
916
- return queued
917
- }
918
-
919
- // Keep a stable ref so window listeners registered once always call the
920
- // latest performAuthLink closure (which reads current config/identity).
921
- const performAuthLinkRef = useRef(performAuthLink)
922
- performAuthLinkRef.current = performAuthLink
923
-
924
- /**
925
- * Trigger 1 — new Commerce Client conversation.
926
- * `onCimulateWidgetReady` is a cancelable handshake the widget dispatches
927
- * ONLY when it creates a NEW conversation (not on sessionStorage resume).
928
- * We use it purely as the "new conversation identity" signal and run the
929
- * link asynchronously — we do NOT call preventDefault()/done() here, so the
930
- * widget proceeds immediately; the JWT poll in performAuthLink waits for the
931
- * new conversation's token to land.
932
- */
933
- useEffect(() => {
934
- if (!isCommerceClientReady) {
935
- return
936
- }
937
- const handleWidgetReady = () => {
938
- // Clear-chat can dispatch this event before storage rotates. Wait for
939
- // the new token rather than authenticating the previous conversation.
940
- const excludedJWT =
941
- lastAttemptedCommerceClientJWTRef.current || lastCommerceClientJWTRef.current
942
- performAuthLinkRef.current({
943
- reason: 'widget-ready',
944
- excludedJWT: excludedJWT || null
945
- })
946
- }
947
- window.addEventListener('onCimulateWidgetReady', handleWidgetReady)
948
- return () => {
949
- window.removeEventListener('onCimulateWidgetReady', handleWidgetReady)
950
- }
951
- }, [isCommerceClientReady])
952
-
953
- /**
954
- * Trigger 2 — SLAS shopper identity transition.
955
- * Login, logout, registration and account switch all rotate the SLAS token
956
- * (reflected here as a change in customerType/usid). The conversation is
957
- * unchanged but is now linked to the wrong (or anonymous) shopper, so we
958
- * re-link. Skips the initial mount; the composite dedup key in
959
- * performAuthLink prevents a redundant link if nothing effectively changed.
960
- */
961
- const prevSlasIdentityRef = useRef(undefined)
962
- useEffect(() => {
963
- if (!isCommerceClientReady) {
964
- return
965
- }
966
- const identity = getSlasIdentity()
967
- const prev = prevSlasIdentityRef.current
968
- prevSlasIdentityRef.current = identity
969
-
970
- // A resumed conversation does not emit widget-ready, so link it here.
971
- // A genuine cold start still waits for the widget-ready trigger.
972
- if (prev === undefined) {
973
- if (readConversationId()) {
974
- performAuthLinkRef.current({reason: 'resumed-conversation'})
975
- }
976
- return
977
- }
978
- if (prev !== identity) {
979
- performAuthLinkRef.current({reason: 'slas-identity-change'})
980
- }
981
- }, [customerType, usid, isCommerceClientReady])
982
646
 
983
647
  const isDialog = cc_displayType === 'dialog'
984
648
  const isFullHeight = isDialog && cc_dialogFullHeight === 'true'
@@ -1016,11 +680,7 @@ const CommerceClientAgentWindow = ({
1016
680
  capabilitiesVersion: cc_capabilitiesVersion,
1017
681
  enableEscalationToAgent: cc_enableEscalationToAgent !== 'false',
1018
682
  enableDownloadTranscript: cc_enableDownloadTranscript !== 'false',
1019
- routingAttributes: resolveCommerceClientRoutingAttributes({
1020
- cc_routingAttributes,
1021
- cc_cdnVersion,
1022
- commerceClientScriptSourceUrl
1023
- }),
683
+ routingAttributes: cc_routingAttributes,
1024
684
  logoUrl: cc_logoUrl,
1025
685
  headerText: cc_headerText,
1026
686
  disclaimerMarkdown: cc_disclaimerMarkdown,
@@ -1051,8 +711,6 @@ const CommerceClientAgentWindow = ({
1051
711
  cc_enableEscalationToAgent,
1052
712
  cc_enableDownloadTranscript,
1053
713
  cc_routingAttributes,
1054
- cc_cdnVersion,
1055
- commerceClientScriptSourceUrl,
1056
714
  cc_logoUrl,
1057
715
  cc_headerText,
1058
716
  cc_disclaimerMarkdown,
@@ -1071,7 +729,7 @@ const CommerceClientAgentWindow = ({
1071
729
  )
1072
730
 
1073
731
  // Inject the widget into the container once the bundle is loaded
1074
- useCommerceClientMessaging(effectiveScriptLoadStatus, widgetOptions)
732
+ useCommerceClientMessaging(scriptLoadStatus, widgetOptions)
1075
733
 
1076
734
  return (
1077
735
  <>
@@ -1094,12 +752,7 @@ CommerceClientAgentWindow.propTypes = {
1094
752
  * @type {Object}
1095
753
  * @required
1096
754
  */
1097
- commerceAgentConfiguration: PropTypes.object.isRequired,
1098
- lastAuthLinkKeyRef: PropTypes.shape({current: PropTypes.string}).isRequired,
1099
- lastCommerceClientJWTRef: PropTypes.shape({current: PropTypes.string}).isRequired,
1100
- authLinkGenerationRef: PropTypes.shape({current: PropTypes.number}).isRequired,
1101
- authLinkQueueRef: PropTypes.shape({current: PropTypes.object}).isRequired,
1102
- lastAttemptedCommerceClientJWTRef: PropTypes.shape({current: PropTypes.string}).isRequired
755
+ commerceAgentConfiguration: PropTypes.object.isRequired
1103
756
  }
1104
757
 
1105
758
  /**
@@ -1135,14 +788,6 @@ CommerceClientAgentWindow.propTypes = {
1135
788
  * @see {@link isEnabled} - Enabled state checker
1136
789
  */
1137
790
  const ShopperAgent = ({commerceAgentConfiguration, basketDoneLoading}) => {
1138
- // Preserve successful-link state while the inner widget unmounts during a
1139
- // basket refresh so a same-identity remount stays deduped and login re-links.
1140
- const lastAuthLinkKeyRef = useRef(null)
1141
- const lastCommerceClientJWTRef = useRef(null)
1142
- const authLinkGenerationRef = useRef(0)
1143
- const authLinkQueueRef = useRef(Promise.resolve())
1144
- const lastAttemptedCommerceClientJWTRef = useRef(null)
1145
-
1146
791
  // Extract enabled state and provider from configuration.
1147
792
  // `provider` defaults to 'miaw' to preserve backwards compatibility with the
1148
793
  // existing Salesforce Embedded Messaging (MIAW) integration.
@@ -1172,11 +817,6 @@ const ShopperAgent = ({commerceAgentConfiguration, basketDoneLoading}) => {
1172
817
  <div data-testid="shopper-agent">
1173
818
  <CommerceClientAgentWindow
1174
819
  commerceAgentConfiguration={commerceAgentConfiguration}
1175
- lastAuthLinkKeyRef={lastAuthLinkKeyRef}
1176
- lastCommerceClientJWTRef={lastCommerceClientJWTRef}
1177
- authLinkGenerationRef={authLinkGenerationRef}
1178
- authLinkQueueRef={authLinkQueueRef}
1179
- lastAttemptedCommerceClientJWTRef={lastAttemptedCommerceClientJWTRef}
1180
820
  />
1181
821
  </div>
1182
822
  ) : null