@mattrglobal/verifier-sdk-web 2.1.2-unstable.99 → 2.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.
@@ -7,8 +7,8 @@
7
7
  * Do Not Translate or Localize
8
8
  *
9
9
  * Bundle of @mattrglobal/verifier-sdk-web
10
- * Generated: 2026-03-17
11
- * Version: 2.1.1
10
+ * Generated: 2026-06-08
11
+ * Version: 2.2.0
12
12
  * Dependencies:
13
13
  */
14
14
 
@@ -181,7 +181,8 @@ const PresentationResultRelaxValidator = v__namespace.object({
181
181
  credentialQuery: v__namespace.optional(v__namespace.unknown()),
182
182
  credentials: v__namespace.optional(v__namespace.unknown()),
183
183
  credentialErrors: v__namespace.optional(v__namespace.unknown()),
184
- error: v__namespace.optional(v__namespace.unknown())
184
+ error: v__namespace.optional(v__namespace.unknown()),
185
+ state: v__namespace.optional(v__namespace.string())
185
186
  });
186
187
 
187
188
  exports.Mode = void 0;
@@ -203,7 +204,8 @@ v__namespace.object({
203
204
  challenge: v__namespace.string(),
204
205
  redirectUri: v__namespace.optional(v__namespace.string()),
205
206
  walletProviderId: v__namespace.optional(v__namespace.string()),
206
- dcApiSupported: v__namespace.optional(v__namespace.boolean())
207
+ dcApiSupported: v__namespace.optional(v__namespace.boolean()),
208
+ state: v__namespace.optional(v__namespace.pipe(v__namespace.string(), v__namespace.minLength(1)))
207
209
  });
208
210
 
209
211
  const CreateSessionDigitalCredentialsValidator = v__namespace.object({
@@ -218,7 +220,8 @@ const CreateSessionOpenId4vpResponseValidator = v__namespace.object({
218
220
  type: v__namespace.optional(v__namespace.literal(SessionType.Openid4vp)),
219
221
  sessionId: v__namespace.string(),
220
222
  sessionKey: v__namespace.string(),
221
- sessionUrl: v__namespace.string()
223
+ sessionUrl: v__namespace.string(),
224
+ state: v__namespace.optional(v__namespace.string())
222
225
  });
223
226
 
224
227
  const CreateSessionResponseValidator = v__namespace.union([ CreateSessionDigitalCredentialsValidator, CreateSessionOpenId4vpResponseValidator ]);
@@ -246,11 +249,12 @@ var LocalStorageKey;
246
249
  (function(LocalStorageKey) {
247
250
  LocalStorageKey["challenge"] = "mattr_chg";
248
251
  LocalStorageKey["sessionId"] = "mattr_sid";
252
+ LocalStorageKey["state"] = "mattr_st";
249
253
  })(LocalStorageKey || (LocalStorageKey = {}));
250
254
 
251
255
  const MATTR_SDK_VERSION_HEADER = "x-mattr-sdk-version";
252
256
 
253
- const MATTR_SDK_VERSION_VALUE = "2.1.1";
257
+ const MATTR_SDK_VERSION_VALUE = "2.2.0";
254
258
 
255
259
  var MessageEventDataType;
256
260
 
@@ -280,7 +284,8 @@ const OpenId4vpConfigAutoDetectOptionsValidator = v__namespace.object({
280
284
  const RequestCredentialsOptionsValidator = v__namespace.object({
281
285
  credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
282
286
  challenge: v__namespace.optional(v__namespace.string()),
283
- openid4vpConfiguration: v__namespace.optional(v__namespace.union([ OpenId4vpConfigSameDeviceOptionsValidator, OpenId4vpConfigCrossDeviceOptionsValidator, OpenId4vpConfigAutoDetectOptionsValidator ]))
287
+ openid4vpConfiguration: v__namespace.optional(v__namespace.union([ OpenId4vpConfigSameDeviceOptionsValidator, OpenId4vpConfigCrossDeviceOptionsValidator, OpenId4vpConfigAutoDetectOptionsValidator ])),
288
+ state: v__namespace.optional(v__namespace.pipe(v__namespace.string(), v__namespace.minLength(1, "state must not be empty")))
284
289
  });
285
290
 
286
291
  exports.RequestCredentialsErrorType = void 0;
@@ -303,6 +308,7 @@ var RequestCredentialsErrorMessage;
303
308
  RequestCredentialsErrorMessage["DcApiResponseParseError"] = "Failed to parse response from Digital Credentials API";
304
309
  RequestCredentialsErrorMessage["Abort"] = "User aborted the session";
305
310
  RequestCredentialsErrorMessage["Timeout"] = "User session timeout";
311
+ RequestCredentialsErrorMessage["StateMismatch"] = "State mismatch between requested session and back-channel result";
306
312
  })(RequestCredentialsErrorMessage || (RequestCredentialsErrorMessage = {}));
307
313
 
308
314
  exports.AbortSessionErrorType = void 0;
@@ -492,18 +498,20 @@ const getHashParamValue = (hash, param) => {
492
498
  return urlParams.get(param);
493
499
  };
494
500
 
495
- const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId}) => {
501
+ const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId, state: state}) => {
496
502
  const openid4vpConfiguration = !!walletProviderId || !!redirectUri ? {
497
503
  redirectUri: redirectUri,
498
504
  walletProviderId: walletProviderId
499
505
  } : undefined;
500
- const postData = {
506
+ const postData = Object.assign({
501
507
  credentialQuery: credentialQuery,
502
508
  challenge: challenge,
503
509
  applicationId: applicationId,
504
510
  dcApiSupported: dcApiSupported,
505
511
  openid4vpConfiguration: openid4vpConfiguration
506
- };
512
+ }, state !== undefined ? {
513
+ state: state
514
+ } : {});
507
515
  const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/web/sessions`, {
508
516
  method: "POST",
509
517
  headers: {
@@ -621,7 +629,7 @@ const closeCrossDeviceModal = options => {
621
629
  };
622
630
 
623
631
  const receiveMessageHandler = options => async event => {
624
- const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge} = options;
632
+ const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge, state: state} = options;
625
633
  if (event.origin !== apiBaseUrl) {
626
634
  return;
627
635
  }
@@ -643,10 +651,22 @@ const receiveMessageHandler = options => async event => {
643
651
  });
644
652
  return;
645
653
  }
654
+ const resultState = "challenge" in result.value ? result.value.state : undefined;
655
+ if (state !== undefined && resultState !== undefined && state !== resultState) {
656
+ onFailure({
657
+ type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
658
+ message: RequestCredentialsErrorMessage.StateMismatch
659
+ });
660
+ closeCrossDeviceModal({
661
+ container: container
662
+ });
663
+ return;
664
+ }
646
665
  onComplete({
647
666
  result: "challenge" in result.value ? result.value : undefined,
648
667
  sessionId: result.value.sessionId,
649
- sessionCompletedInRedirect: false
668
+ sessionCompletedInRedirect: false,
669
+ state: resultState !== null && resultState !== void 0 ? resultState : state
650
670
  });
651
671
  closeCrossDeviceModal({
652
672
  container: container
@@ -692,7 +712,7 @@ const openCrossDeviceModal = options => {
692
712
  };
693
713
 
694
714
  const requestCredentialsWithCrossDevice = async options => {
695
- const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey} = options;
715
+ const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey, state: state} = options;
696
716
  const container = openCrossDeviceModal({
697
717
  sessionUrl: sessionUrl
698
718
  });
@@ -716,6 +736,7 @@ const requestCredentialsWithCrossDevice = async options => {
716
736
  sessionId: sessionId,
717
737
  apiBaseUrl: apiBaseUrl,
718
738
  challenge: challenge,
739
+ state: state,
719
740
  onComplete: data => resolve(neverthrow.ok(data)),
720
741
  onFailure: error => resolve(neverthrow.err(error))
721
742
  });
@@ -903,13 +924,18 @@ var SameDeviceRequestCredentialsErrorMessage;
903
924
  })(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
904
925
 
905
926
  const requestCredentialsSameDevice = async options => {
906
- const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId} = options;
927
+ const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId, state: state} = options;
907
928
  const abortController = setActiveSession({
908
929
  sessionId: sessionId,
909
930
  sessionKey: sessionKey
910
931
  });
911
932
  window.localStorage.setItem(LocalStorageKey.sessionId, sessionId);
912
933
  window.localStorage.setItem(LocalStorageKey.challenge, challenge);
934
+ if (state !== undefined) {
935
+ window.localStorage.setItem(LocalStorageKey.state, state);
936
+ } else {
937
+ window.localStorage.removeItem(LocalStorageKey.state);
938
+ }
913
939
  window.location.assign(sessionUrl);
914
940
  await sleep(SESSION_STATUS_POLLING_INITIAL_DELAY_MS);
915
941
  const checkResult = await withRetry((async () => {
@@ -960,7 +986,7 @@ const requestCredentials = async options => {
960
986
  }
961
987
  assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
962
988
  const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initializeOptions;
963
- const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration} = options;
989
+ const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration, state: state} = options;
964
990
  const dcApiSupported = isDigitalCredentialsApiSupported();
965
991
  const openId4VpRedirectUri = deriveOpenId4vpRedirectUri(openid4vpConfiguration);
966
992
  const createSessionResult = await createSession({
@@ -970,7 +996,8 @@ const requestCredentials = async options => {
970
996
  walletProviderId: (_a = openid4vpConfiguration === null || openid4vpConfiguration === void 0 ? void 0 : openid4vpConfiguration.walletProviderId) !== null && _a !== void 0 ? _a : undefined,
971
997
  apiBaseUrl: apiBaseUrl,
972
998
  applicationId: applicationId,
973
- dcApiSupported: dcApiSupported
999
+ dcApiSupported: dcApiSupported,
1000
+ state: state
974
1001
  });
975
1002
  if (createSessionResult.isErr()) {
976
1003
  return neverthrow.err({
@@ -1006,7 +1033,8 @@ const requestCredentials = async options => {
1006
1033
  applicationId: applicationId,
1007
1034
  sessionUrl: sessionUrl,
1008
1035
  sessionKey: sessionKey,
1009
- sessionId: sessionId
1036
+ sessionId: sessionId,
1037
+ state: state
1010
1038
  });
1011
1039
  }
1012
1040
  return await requestCredentialsWithCrossDevice({
@@ -1014,7 +1042,8 @@ const requestCredentials = async options => {
1014
1042
  apiBaseUrl: apiBaseUrl,
1015
1043
  sessionUrl: sessionUrl,
1016
1044
  sessionKey: sessionKey,
1017
- sessionId: sessionId
1045
+ sessionId: sessionId,
1046
+ state: state
1018
1047
  });
1019
1048
  };
1020
1049
 
@@ -1047,9 +1076,11 @@ var HandleRedirectCallbackErrorMessage;
1047
1076
  HandleRedirectCallbackErrorMessage["FailedToFindChallenge"] = "Failed to find challenge";
1048
1077
  HandleRedirectCallbackErrorMessage["FailedToFindActiveSession"] = "Failed to find active session";
1049
1078
  HandleRedirectCallbackErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
1079
+ HandleRedirectCallbackErrorMessage["StateMismatch"] = "State mismatch between stored session and back-channel result";
1050
1080
  })(HandleRedirectCallbackErrorMessage || (HandleRedirectCallbackErrorMessage = {}));
1051
1081
 
1052
1082
  const handleRedirectCallback = async () => {
1083
+ var _a;
1053
1084
  const initializeOptions = getInitializeOptions();
1054
1085
  if (!initializeOptions) {
1055
1086
  throw new Exception(InitializeErrorMessage.SdkNotInitialized);
@@ -1064,6 +1095,7 @@ const handleRedirectCallback = async () => {
1064
1095
  }
1065
1096
  const sessionId = window.localStorage.getItem(LocalStorageKey.sessionId);
1066
1097
  const challenge = window.localStorage.getItem(LocalStorageKey.challenge);
1098
+ const storedState = (_a = window.localStorage.getItem(LocalStorageKey.state)) !== null && _a !== void 0 ? _a : undefined;
1067
1099
  if (!sessionId || !challenge) {
1068
1100
  return neverthrow.err({
1069
1101
  type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
@@ -1083,9 +1115,22 @@ const handleRedirectCallback = async () => {
1083
1115
  cause: result.error
1084
1116
  });
1085
1117
  }
1118
+ const resultState = "challenge" in result.value ? result.value.state : undefined;
1119
+ if (storedState !== undefined && resultState !== undefined && storedState !== resultState) {
1120
+ window.localStorage.removeItem(LocalStorageKey.challenge);
1121
+ window.localStorage.removeItem(LocalStorageKey.sessionId);
1122
+ window.localStorage.removeItem(LocalStorageKey.state);
1123
+ return neverthrow.err({
1124
+ type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
1125
+ message: HandleRedirectCallbackErrorMessage.StateMismatch
1126
+ });
1127
+ }
1128
+ const state = resultState !== null && resultState !== void 0 ? resultState : storedState;
1129
+ window.localStorage.removeItem(LocalStorageKey.state);
1086
1130
  return neverthrow.ok({
1087
1131
  result: "challenge" in result.value ? result.value : undefined,
1088
- sessionId: result.value.sessionId
1132
+ sessionId: result.value.sessionId,
1133
+ state: state
1089
1134
  });
1090
1135
  };
1091
1136