@mxenabled/connect-widget 2.5.6 → 2.7.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/dist/index.es.js CHANGED
@@ -5316,6 +5316,30 @@ const addManualAccountSuccess = (account, member, institution) => ({
5316
5316
  payload: { account, member, institution }
5317
5317
  });
5318
5318
 
5319
+ const ConnectionStatusMap = {
5320
+ 0: "CREATED",
5321
+ 1: "PREVENTED",
5322
+ 2: "DENIED",
5323
+ 3: "CHALLENGED",
5324
+ 4: "REJECTED",
5325
+ 5: "LOCKED",
5326
+ 6: "CONNECTED",
5327
+ 7: "IMPEDED",
5328
+ 8: "RECONNECTED",
5329
+ 9: "DEGRADED",
5330
+ 10: "DISCONNECTED",
5331
+ 11: "DISCONTINUED",
5332
+ 12: "CLOSED",
5333
+ 13: "DELAYED",
5334
+ 14: "FAILED",
5335
+ 15: "UPDATED",
5336
+ 16: "DISABLED",
5337
+ 17: "IMPORTED",
5338
+ 18: "RESUMED",
5339
+ 19: "EXPIRED",
5340
+ 20: "IMPAIRED",
5341
+ 21: "PENDING"
5342
+ };
5319
5343
  const ReadableStatuses$1 = {
5320
5344
  PREVENTED: 1,
5321
5345
  DENIED: 2,
@@ -9164,8 +9188,27 @@ const { addVerificationData, addAggregationData, additionalProductReset } = conf
9164
9188
  const configSlice$1 = configSlice.reducer;
9165
9189
 
9166
9190
  const ACTIONABLE_ERROR_CODES = {
9167
- NO_ELIGIBLE_ACCOUNTS: 1e3
9168
- };
9191
+ NO_ELIGIBLE_ACCOUNTS: 1e3,
9192
+ NO_ACCOUNTS: 1001,
9193
+ ACCESS_DENIED: 1002,
9194
+ INCORRECT_OTP: 2001,
9195
+ INCORRECT_MFA: 2002,
9196
+ MFA_TIMEOUT: 2003,
9197
+ REAUTHORIZATION_REQUIRED: 2004,
9198
+ INVALID_CREDENTIALS: 2005,
9199
+ INSTITUTION_DOWN: 3e3,
9200
+ INSTITUTION_MAINTENANCE: 3001,
9201
+ INSTITUTION_UNAVAILABLE: 3002
9202
+ };
9203
+ const CODES_REQUIRING_CREDENTIALS = [
9204
+ ACTIONABLE_ERROR_CODES.INVALID_CREDENTIALS,
9205
+ ACTIONABLE_ERROR_CODES.REAUTHORIZATION_REQUIRED
9206
+ ];
9207
+ const CODES_REQUIRING_MFA = [
9208
+ ACTIONABLE_ERROR_CODES.INCORRECT_OTP,
9209
+ ACTIONABLE_ERROR_CODES.INCORRECT_MFA,
9210
+ ACTIONABLE_ERROR_CODES.MFA_TIMEOUT
9211
+ ];
9169
9212
  const ACTIVE_ACTIONABLE_ERROR_CODES = Object.values(ACTIONABLE_ERROR_CODES);
9170
9213
  const canHandleActionableError = (errorCode, mode) => {
9171
9214
  if (errorCode === ACTIONABLE_ERROR_CODES.NO_ELIGIBLE_ACCOUNTS && mode !== VERIFY_MODE) {
@@ -9615,9 +9658,12 @@ function getStepFromMember(member, mode = AGG_MODE) {
9615
9658
  const connection_status = member.connection_status;
9616
9659
  if (member && memberIsBlockedForCostReasons(member)) {
9617
9660
  return STEPS.INSTITUTION_DISABLED;
9618
- } else if (member?.error?.error_code && canHandleActionableError(member?.error?.error_code, mode) || hasNoSingleAccountSelectOptions(member))
9619
- return STEPS.ACTIONABLE_ERROR;
9620
- else if (connection_status === ReadableStatuses$1.CHALLENGED)
9661
+ } else if (member?.error?.error_code && canHandleActionableError(member?.error?.error_code, mode) || hasNoSingleAccountSelectOptions(member)) {
9662
+ const errorCode = member?.error?.error_code;
9663
+ if (CODES_REQUIRING_CREDENTIALS.includes(errorCode)) return STEPS.ENTER_CREDENTIALS;
9664
+ if (CODES_REQUIRING_MFA.includes(errorCode)) return STEPS.MFA;
9665
+ else return STEPS.ACTIONABLE_ERROR;
9666
+ } else if (connection_status === ReadableStatuses$1.CHALLENGED)
9621
9667
  return STEPS.MFA;
9622
9668
  else if (connection_status === ReadableStatuses$1.CONNECTED)
9623
9669
  return STEPS.CONNECTED;
@@ -70375,8 +70421,8 @@ const VIEWS$2 = {
70375
70421
  GENERAL_SUPPORT: "generalSupport",
70376
70422
  SUCCESS: "success"
70377
70423
  };
70378
- const Support = React__default.forwardRef((props, supportNavRef) => {
70379
- const { loadToView, onClose } = props;
70424
+ const Support$1 = React__default.forwardRef((props, supportNavRef) => {
70425
+ const { loadToView = VIEWS$2.MENU, onClose } = props;
70380
70426
  const [currentView, setCurrentView] = useState(loadToView);
70381
70427
  const [email, setEmail] = useState("");
70382
70428
  const [ariaLiveRegionMessage, setAriaLiveRegionMessage] = useState("");
@@ -70469,14 +70515,11 @@ const getStyles$15 = (tokens) => ({
70469
70515
  margin: "0 auto 0 auto"
70470
70516
  }
70471
70517
  });
70472
- Support.propTypes = {
70518
+ Support$1.propTypes = {
70473
70519
  loadToView: PropTypes$1.oneOf([VIEWS$2.MENU, VIEWS$2.REQ_INSTITUTION, VIEWS$2.GENERAL_SUPPORT]),
70474
70520
  onClose: PropTypes$1.func.isRequired
70475
70521
  };
70476
- Support.defaultPops = {
70477
- loadToView: VIEWS$2.MENU
70478
- };
70479
- Support.displayName = "Support";
70522
+ Support$1.displayName = "Support";
70480
70523
 
70481
70524
  const focusElement = (element) => {
70482
70525
  if (element && "focus" in element) {
@@ -70710,7 +70753,7 @@ const Search$2 = React__default.forwardRef((props, navigationRef) => {
70710
70753
  }
70711
70754
  if (state.showSupportView) {
70712
70755
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
70713
- Support,
70756
+ Support$1,
70714
70757
  {
70715
70758
  loadToView: VIEWS$2.REQ_INSTITUTION,
70716
70759
  onClose: () => dispatch({ type: SEARCH_ACTIONS.HIDE_SUPPORT }),
@@ -72070,7 +72113,7 @@ const MFAStep = React__default.forwardRef((props, navigationRef) => {
72070
72113
  }, [isSubmitting]);
72071
72114
  if (showSupportView) {
72072
72115
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
72073
- Support,
72116
+ Support$1,
72074
72117
  {
72075
72118
  loadToView: VIEWS$2.GENERAL_SUPPORT,
72076
72119
  onClose: () => setShowSupportView(false),
@@ -75230,6 +75273,18 @@ const buildFormSchema = (loginFields) => {
75230
75273
  };
75231
75274
  }, {});
75232
75275
  };
75276
+ const shouldShowMessageBox = (error, currentMember, mode = AGG_MODE) => {
75277
+ const noErrors = _isEmpty(error);
75278
+ const isDenied = currentMember.connection_status === ReadableStatuses$1.DENIED;
75279
+ const isErrorCodeCredentialRelated = currentMember?.error?.error_code && canHandleActionableError(currentMember?.error?.error_code, mode);
75280
+ if (noErrors && isDenied) {
75281
+ return true;
75282
+ } else if (isErrorCodeCredentialRelated) {
75283
+ return true;
75284
+ } else {
75285
+ return false;
75286
+ }
75287
+ };
75233
75288
 
75234
75289
  const CREDENTIAL_FIELD_TYPES = {
75235
75290
  PASSWORD: 1};
@@ -75550,7 +75605,7 @@ const Credentials = React__default.forwardRef(
75550
75605
  ]);
75551
75606
  if (showSupportView) {
75552
75607
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
75553
- Support,
75608
+ Support$1,
75554
75609
  {
75555
75610
  loadToView: VIEWS$2.MENU,
75556
75611
  onClose: () => setShowSupportView(false),
@@ -75636,7 +75691,7 @@ const Credentials = React__default.forwardRef(
75636
75691
  }
75637
75692
  ),
75638
75693
  !_isEmpty(error) && /* @__PURE__ */ jsxRuntimeExports.jsx(SlideDown, { delay: getNextDelay(), children: /* @__PURE__ */ jsxRuntimeExports.jsx(MemberError, { error, institution }) }),
75639
- _isEmpty(error) && currentMember.connection_status === ReadableStatuses$1.DENIED && /* @__PURE__ */ jsxRuntimeExports.jsx(SlideDown, { delay: getNextDelay(), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
75694
+ shouldShowMessageBox(error, currentMember, connectConfig.mode) && /* @__PURE__ */ jsxRuntimeExports.jsx(SlideDown, { delay: getNextDelay(), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
75640
75695
  MessageBox,
75641
75696
  {
75642
75697
  "data-test": "credentials-error-message-box",
@@ -76881,7 +76936,10 @@ const LoginError = React__default.forwardRef(
76881
76936
  const connectConfig = useSelector(selectConnectConfig);
76882
76937
  const initialConfig = useSelector(selectInitialConfig);
76883
76938
  const pageViewInfo = PageviewInfo.CONNECT_LOGIN_ERROR;
76884
- useAnalyticsPath(...pageViewInfo);
76939
+ useAnalyticsPath(...pageViewInfo, {
76940
+ connection_status: member.connection_status || "UNKNOWN",
76941
+ readable_status: ConnectionStatusMap[member.connection_status] || "UNKNOWN"
76942
+ });
76885
76943
  const [isLeaving, setIsLeaving] = useState(false);
76886
76944
  const [showSupportView, setShowSupportView] = useState(false);
76887
76945
  const getNextDelay = getDelay();
@@ -77063,7 +77121,7 @@ const LoginError = React__default.forwardRef(
77063
77121
  const statusActions = memberStatusActionsMap[member.connection_status] || defaultMemberStatusAction;
77064
77122
  if (showSupportView) {
77065
77123
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
77066
- Support,
77124
+ Support$1,
77067
77125
  {
77068
77126
  loadToView: VIEWS$2.GENERAL_SUPPORT,
77069
77127
  onClose: () => setShowSupportView(false),
@@ -77118,38 +77176,69 @@ LoginError.propTypes = {
77118
77176
  };
77119
77177
  LoginError.displayName = "LoginError";
77120
77178
 
77121
- const ActionableError = () => {
77179
+ const useActionableErrorMap = (jobDetailCode, setShowSupport) => {
77122
77180
  const postMessageFunctions = useContext(PostMessageContext);
77123
- const institution = useSelector((state) => state.connect.selectedInstitution);
77124
- const currentMember = useSelector(getCurrentMember);
77125
- const initialConfig = useSelector(selectInitialConfig);
77126
- const jobDetailCode = currentMember.error.error_code;
77127
- const tokens = useTokens();
77128
- const styles = getStyles$A(tokens);
77129
- const getNextDelay = getDelay();
77181
+ const initialConfig = useSelector((state) => state.connect.initialConfig);
77130
77182
  const dispatch = useDispatch();
77183
+ const goToSearch = () => {
77184
+ postMessageFunctions.onPostMessage("connect/backToSearch");
77185
+ dispatch({
77186
+ type: ActionTypes$2.ACTIONABLE_ERROR_CONNECT_DIFFERENT_INSTITUTION,
77187
+ payload: initialConfig.mode
77188
+ });
77189
+ };
77190
+ const goToSupport = () => setShowSupport(true);
77191
+ const goToCredentials = () => dispatch({ type: ActionTypes$2.ACTIONABLE_ERROR_LOG_IN_AGAIN });
77131
77192
  const messagingMap = useMemo(
77132
77193
  () => ({
77133
77194
  [ACTIONABLE_ERROR_CODES.NO_ELIGIBLE_ACCOUNTS]: {
77134
77195
  title: __("No eligible accounts"),
77135
- primaryAction: {
77136
- label: __("Log in again"),
77137
- action: () => dispatch({ type: ActionTypes$2.ACTIONABLE_ERROR_LOG_IN_AGAIN })
77138
- },
77139
- secondaryActions: {
77140
- label: __("Connect a different institution"),
77141
- action: () => {
77142
- postMessageFunctions.onPostMessage("connect/backToSearch");
77143
- dispatch({
77144
- type: ActionTypes$2.ACTIONABLE_ERROR_CONNECT_DIFFERENT_INSTITUTION,
77145
- payload: initialConfig.mode
77146
- });
77147
- }
77148
- }
77196
+ primaryAction: { label: __("Log in again"), action: goToCredentials },
77197
+ secondaryActions: { label: __("Connect a different institution"), action: goToSearch }
77198
+ },
77199
+ [ACTIONABLE_ERROR_CODES.NO_ACCOUNTS]: {
77200
+ title: __("No accounts found"),
77201
+ primaryAction: { label: __("Return to institution selection"), action: goToSearch },
77202
+ secondaryActions: { label: __("Get help"), action: goToSupport }
77203
+ },
77204
+ [ACTIONABLE_ERROR_CODES.ACCESS_DENIED]: {
77205
+ title: __("Additional permissions needed"),
77206
+ primaryAction: { label: __("Review instructions"), action: goToCredentials },
77207
+ secondaryActions: { label: __("Get help"), action: goToSupport }
77208
+ },
77209
+ [ACTIONABLE_ERROR_CODES.INSTITUTION_DOWN]: {
77210
+ title: __("Unable to connect"),
77211
+ primaryAction: { label: __("Return to institution selection"), action: goToSearch },
77212
+ secondaryActions: { label: __("Get help"), action: goToSupport }
77213
+ },
77214
+ [ACTIONABLE_ERROR_CODES.INSTITUTION_MAINTENANCE]: {
77215
+ title: __("Maintenance in progress"),
77216
+ primaryAction: { label: __("Return to institution selection"), action: goToSearch },
77217
+ secondaryActions: { label: __("Get help"), action: goToSupport }
77218
+ },
77219
+ [ACTIONABLE_ERROR_CODES.INSTITUTION_UNAVAILABLE]: {
77220
+ title: __("Unable to connect"),
77221
+ primaryAction: { label: __("Return to institution selection"), action: goToSearch },
77222
+ secondaryActions: { label: __("Get help"), action: goToSupport }
77149
77223
  }
77150
77224
  }),
77151
77225
  [dispatch]
77152
77226
  );
77227
+ return messagingMap[jobDetailCode];
77228
+ };
77229
+
77230
+ const Support = Support$1;
77231
+ const ActionableError = () => {
77232
+ const supportNavRef = useRef(null);
77233
+ const postMessageFunctions = useContext(PostMessageContext);
77234
+ const institution = useSelector((state) => state.connect.selectedInstitution);
77235
+ const currentMember = useSelector(getCurrentMember);
77236
+ const jobDetailCode = currentMember.error.error_code;
77237
+ const tokens = useTokens();
77238
+ const styles = getStyles$A(tokens);
77239
+ const getNextDelay = getDelay();
77240
+ const [showSupport, setShowSupport] = React__default.useState(false);
77241
+ const errorDetails = useActionableErrorMap(jobDetailCode, setShowSupport);
77153
77242
  useEffect(() => {
77154
77243
  postMessageFunctions.onPostMessage("connect/invalidData", {
77155
77244
  member: {
@@ -77158,7 +77247,14 @@ const ActionableError = () => {
77158
77247
  }
77159
77248
  });
77160
77249
  }, [jobDetailCode]);
77161
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
77250
+ return showSupport ? /* @__PURE__ */ jsxRuntimeExports.jsx(
77251
+ Support,
77252
+ {
77253
+ loadToView: VIEWS$2.GENERAL_SUPPORT,
77254
+ onClose: () => setShowSupport(false),
77255
+ ref: supportNavRef
77256
+ }
77257
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
77162
77258
  /* @__PURE__ */ jsxRuntimeExports.jsx(SlideDown, { delay: getNextDelay(), children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles.logoWrapper, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { badgeContent: "!", color: "error", sx: styles.badge, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
77163
77259
  K0,
77164
77260
  {
@@ -77176,7 +77272,7 @@ const ActionableError = () => {
77176
77272
  style: styles.title,
77177
77273
  truncate: false,
77178
77274
  variant: "H2",
77179
- children: messagingMap[jobDetailCode].title
77275
+ children: errorDetails?.title
77180
77276
  }
77181
77277
  ),
77182
77278
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -77197,10 +77293,10 @@ const ActionableError = () => {
77197
77293
  {
77198
77294
  "data-test": "actionable-error-primary-button",
77199
77295
  fullWidth: true,
77200
- onClick: messagingMap[jobDetailCode].primaryAction.action,
77296
+ onClick: errorDetails?.primaryAction.action,
77201
77297
  style: { marginBottom: 8 },
77202
77298
  variant: "contained",
77203
- children: messagingMap[jobDetailCode].primaryAction.label
77299
+ children: errorDetails?.primaryAction.label
77204
77300
  }
77205
77301
  ),
77206
77302
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -77208,10 +77304,10 @@ const ActionableError = () => {
77208
77304
  {
77209
77305
  "data-test": "actionable-error-secondary-button",
77210
77306
  fullWidth: true,
77211
- onClick: messagingMap[jobDetailCode].secondaryActions.action,
77307
+ onClick: errorDetails?.secondaryActions.action,
77212
77308
  style: { marginBottom: 8 },
77213
77309
  variant: "text",
77214
- children: messagingMap[jobDetailCode].secondaryActions.label
77310
+ children: errorDetails?.secondaryActions.label
77215
77311
  }
77216
77312
  )
77217
77313
  ] })