@mattrglobal/verifier-sdk-web 2.1.2-unstable.98 → 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.
@@ -11,7 +11,8 @@ export declare enum HandleRedirectCallbackErrorMessage {
11
11
  FailedToFindResponseCode = "Failed to find response code",
12
12
  FailedToFindChallenge = "Failed to find challenge",
13
13
  FailedToFindActiveSession = "Failed to find active session",
14
- FailedToGetSessionResult = "Failed to get session result"
14
+ FailedToGetSessionResult = "Failed to get session result",
15
+ StateMismatch = "State mismatch between stored session and back-channel result"
15
16
  }
16
17
  export type HandleRedirectCallbackError = BaseError<HandleRedirectCallbackErrorType>;
17
18
  /**
@@ -3,6 +3,14 @@ import { RequestCredentialsError, RequestCredentialsOptions, RequestCredentialsR
3
3
  /**
4
4
  * Requests credentials based on the provided options.
5
5
  *
6
+ * An optional `state` correlation reference can be supplied via {@link RequestCredentialsOptions} to link the session to a
7
+ * record in your own system. When provided it must be a non-empty string, and is carried through the presentation session
8
+ * and echoed back on the result: on {@link RequestCredentialsResponse} for cross-device flows, and via
9
+ * `handleRedirectCallback()` for same-device flows. Because `state` is transmitted in plain text on the wallet-facing
10
+ * request URI and stored in session records, it must not contain personally identifiable information (PII), credentials, or
11
+ * other sensitive data. When omitted, the OpenID4VP `state` claim falls back to the internal `sessionId` and no `state` is
12
+ * returned.
13
+ *
6
14
  * @param options - The options to request credentials with {@link RequestCredentialsOptions}.
7
15
  * @returns A promise that resolves to a result containing either the {@link RequestCredentialsResponse | requested credentials} or an {@link RequestCredentialsError | error}.
8
16
  */
@@ -249,6 +249,7 @@ export type PresentationSuccessResult = {
249
249
  credentialQuery: CredentialQuery[];
250
250
  credentials?: MobileCredentialPresentationCredential[];
251
251
  credentialErrors?: MobileCredentialError[];
252
+ state?: string;
252
253
  };
253
254
  export type PresentationResultRelax = {
254
255
  sessionId: string;
@@ -257,6 +258,7 @@ export type PresentationResultRelax = {
257
258
  credentials?: unknown;
258
259
  credentialErrors?: unknown;
259
260
  error?: unknown;
261
+ state?: string;
260
262
  };
261
263
  export declare const PresentationResultRelaxValidator: v.ObjectSchema<{
262
264
  readonly sessionId: v.StringSchema<undefined>;
@@ -266,6 +268,7 @@ export declare const PresentationResultRelaxValidator: v.ObjectSchema<{
266
268
  readonly credentials: v.OptionalSchema<v.UnknownSchema, undefined>;
267
269
  readonly credentialErrors: v.OptionalSchema<v.UnknownSchema, undefined>;
268
270
  readonly error: v.OptionalSchema<v.UnknownSchema, undefined>;
271
+ readonly state: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
269
272
  }, undefined>;
270
273
  export type PresentationFailureResult = {
271
274
  sessionId: string;
@@ -275,6 +278,7 @@ export type PresentationFailureResult = {
275
278
  type: PresentationErrorType;
276
279
  message: string;
277
280
  };
281
+ state?: string;
278
282
  };
279
283
  /**
280
284
  * The result of a hidden credential presentation request, retured when `resultAvailableInFrontChannel` is set to false in verifier's configuration
@@ -338,6 +342,7 @@ export declare const CreateSessionRequestValidator: v.ObjectSchema<{
338
342
  readonly redirectUri: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
339
343
  readonly walletProviderId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
340
344
  readonly dcApiSupported: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
345
+ readonly state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
341
346
  }, undefined>;
342
347
  export type CreateSessionResponse = v.InferOutput<typeof CreateSessionResponseValidator>;
343
348
  export declare const CreateSessionResponseValidator: v.UnionSchema<[v.ObjectSchema<{
@@ -351,6 +356,7 @@ export declare const CreateSessionResponseValidator: v.UnionSchema<[v.ObjectSche
351
356
  readonly sessionId: v.StringSchema<undefined>;
352
357
  readonly sessionKey: v.StringSchema<undefined>;
353
358
  readonly sessionUrl: v.StringSchema<undefined>;
359
+ readonly state: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
354
360
  }, undefined>], undefined>;
355
361
  export type AbortSessionRequest = v.InferOutput<typeof AbortSessionRequestValidator>;
356
362
  export declare const AbortSessionRequestValidator: v.ObjectSchema<{
@@ -3,10 +3,11 @@ import { BaseError } from "../../common";
3
3
  import { CredentialQuery, Mode, PresentationSessionResult } from "./credential-presentation";
4
4
  export declare enum LocalStorageKey {
5
5
  challenge = "mattr_chg",
6
- sessionId = "mattr_sid"
6
+ sessionId = "mattr_sid",
7
+ state = "mattr_st"
7
8
  }
8
9
  export declare const MATTR_SDK_VERSION_HEADER = "x-mattr-sdk-version";
9
- export declare const MATTR_SDK_VERSION_VALUE = "2.1.1";
10
+ export declare const MATTR_SDK_VERSION_VALUE = "2.2.0";
10
11
  export declare enum MessageEventDataType {
11
12
  PresentationCompleted = "PresentationCompleted",// { type: "PresentationCompleted", responseCode, sessionId }
12
13
  PresentationTimeout = "PresentationTimeout",// { type: "PresentationTimeout", sessionId }
@@ -19,6 +20,7 @@ export type SameDeviceRequestCredentialsOptions = {
19
20
  sessionUrl: string;
20
21
  sessionKey: string;
21
22
  sessionId: string;
23
+ state?: string;
22
24
  };
23
25
  export type CrossDeviceRequestCredentialsOptions = {
24
26
  challenge: string;
@@ -26,6 +28,7 @@ export type CrossDeviceRequestCredentialsOptions = {
26
28
  sessionUrl: string;
27
29
  sessionKey: string;
28
30
  sessionId: string;
31
+ state?: string;
29
32
  };
30
33
  /**
31
34
  * Options for openid4vpConfiguration to request credentials via a same-device flow.
@@ -123,6 +126,12 @@ export type RequestCredentialsOptions = {
123
126
  * Optional configuration for openid4vp presentation flow
124
127
  */
125
128
  openid4vpConfiguration?: OpenIdvpConfiguration;
129
+ /**
130
+ * An optional customer-supplied correlation reference attached to the presentation session.
131
+ * When provided, replaces the internal sessionId as the OpenID4VP `state` claim and is
132
+ * appended as a plain query parameter to the auth request URI.
133
+ */
134
+ state?: string;
126
135
  };
127
136
  export declare const RequestCredentialsOptionsValidator: v.ObjectSchema<{
128
137
  readonly credentialQuery: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
@@ -155,6 +164,7 @@ export declare const RequestCredentialsOptionsValidator: v.ObjectSchema<{
155
164
  readonly redirectUri: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, "Must not be empty">, v.UrlAction<string, undefined>]>;
156
165
  readonly mode: v.OptionalSchema<v.PicklistSchema<[Mode.CrossDevice, Mode.SameDevice], undefined>, undefined>;
157
166
  }, undefined>], undefined>, undefined>;
167
+ readonly state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "state must not be empty">]>, undefined>;
158
168
  }, undefined>;
159
169
  export type MessageEvent = {
160
170
  data: {
@@ -181,6 +191,12 @@ export type RequestCredentialsResponse = {
181
191
  * Indicates that session is completed and the flow will continue on the redirected page
182
192
  */
183
193
  sessionCompletedInRedirect?: boolean;
194
+ /**
195
+ * The customer-supplied correlation reference echoed back from the session.
196
+ * Present only when `state` was provided to `requestCredentials()`.
197
+ * For same-device flows, surfaced via `handleRedirectCallback()` instead.
198
+ */
199
+ state?: string;
184
200
  };
185
201
  /**
186
202
  * The error type for the requestCredentials function
@@ -199,7 +215,8 @@ export declare enum RequestCredentialsErrorMessage {
199
215
  DcApiError = "Failed to request credentials with Digital Credentials API",
200
216
  DcApiResponseParseError = "Failed to parse response from Digital Credentials API",
201
217
  Abort = "User aborted the session",
202
- Timeout = "User session timeout"
218
+ Timeout = "User session timeout",
219
+ StateMismatch = "State mismatch between requested session and back-channel result"
203
220
  }
204
221
  /**
205
222
  * The error type for the `abortCredentialRequest` function
@@ -230,6 +247,12 @@ export type HandleRedirectCallbackResponse = {
230
247
  * Session identifier which can be used to fetch a presentation result via a back channel.
231
248
  */
232
249
  sessionId: string;
250
+ /**
251
+ * The customer-supplied correlation reference.
252
+ * Prefers the back-channel `result.state` value when available; falls back to the
253
+ * value stored in `localStorage` before the wallet redirect.
254
+ */
255
+ state?: string;
233
256
  };
234
257
  /**
235
258
  * Options for the initialize function
@@ -26,7 +26,7 @@ export declare const getHashParamValue: (hash: string, param: string) => string
26
26
  * @param walletProviderId - optional, The ID of the wallet provider, if not provided the default wallet provider will be used.
27
27
  * @returns A promise that resolves to a result containing either the created session response or an error.
28
28
  */
29
- export declare const createSession: ({ credentialQuery, challenge, redirectUri, apiBaseUrl, walletProviderId, dcApiSupported, applicationId, }: CreateSessionRequest & InitializeOptions) => Promise<Result<CreateSessionResponse, SafeFetchValidateResponseError>>;
29
+ export declare const createSession: ({ credentialQuery, challenge, redirectUri, apiBaseUrl, walletProviderId, dcApiSupported, applicationId, state, }: CreateSessionRequest & InitializeOptions) => Promise<Result<CreateSessionResponse, SafeFetchValidateResponseError>>;
30
30
  /**
31
31
  * Abort a session with the provided parameters.
32
32
  *
@@ -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
  * neverthrow -- 4.3.0
@@ -624,6 +624,23 @@
624
624
  if (list.length > 1) return "(".concat(list.join(" ".concat(separator, " ")), ")");
625
625
  return (_list$ = list[0]) !== null && _list$ !== void 0 ? _list$ : "never";
626
626
  }
627
+ function minLength(requirement, message$1) {
628
+ return {
629
+ kind: "validation",
630
+ type: "min_length",
631
+ reference: minLength,
632
+ async: false,
633
+ expects: ">=".concat(requirement),
634
+ requirement: requirement,
635
+ message: message$1,
636
+ "~run": function run(dataset, config$1) {
637
+ if (dataset.typed && dataset.value.length < this.requirement) _addIssue(this, "length", dataset, config$1, {
638
+ received: "".concat(dataset.value.length)
639
+ });
640
+ return dataset;
641
+ }
642
+ };
643
+ }
627
644
  function nonEmpty(message$1) {
628
645
  return {
629
646
  kind: "validation",
@@ -1320,7 +1337,8 @@
1320
1337
  credentialQuery: optional(unknown()),
1321
1338
  credentials: optional(unknown()),
1322
1339
  credentialErrors: optional(unknown()),
1323
- error: optional(unknown())
1340
+ error: optional(unknown()),
1341
+ state: optional(string())
1324
1342
  });
1325
1343
  exports.Mode = void 0;
1326
1344
  (function(Mode) {
@@ -1337,7 +1355,8 @@
1337
1355
  challenge: string(),
1338
1356
  redirectUri: optional(string()),
1339
1357
  walletProviderId: optional(string()),
1340
- dcApiSupported: optional(_boolean())
1358
+ dcApiSupported: optional(_boolean()),
1359
+ state: optional(pipe(string(), minLength(1)))
1341
1360
  });
1342
1361
  const CreateSessionDigitalCredentialsValidator = object({
1343
1362
  type: literal(SessionType.DigitalCredentialsApi),
@@ -1350,7 +1369,8 @@
1350
1369
  type: optional(literal(SessionType.Openid4vp)),
1351
1370
  sessionId: string(),
1352
1371
  sessionKey: string(),
1353
- sessionUrl: string()
1372
+ sessionUrl: string(),
1373
+ state: optional(string())
1354
1374
  });
1355
1375
  const CreateSessionResponseValidator = union([ CreateSessionDigitalCredentialsValidator, CreateSessionOpenId4vpResponseValidator ]);
1356
1376
  const GetSessionStatusResponseValidator = union([ object({
@@ -1363,9 +1383,10 @@
1363
1383
  (function(LocalStorageKey) {
1364
1384
  LocalStorageKey["challenge"] = "mattr_chg";
1365
1385
  LocalStorageKey["sessionId"] = "mattr_sid";
1386
+ LocalStorageKey["state"] = "mattr_st";
1366
1387
  })(LocalStorageKey || (LocalStorageKey = {}));
1367
1388
  const MATTR_SDK_VERSION_HEADER = "x-mattr-sdk-version";
1368
- const MATTR_SDK_VERSION_VALUE = "2.1.1";
1389
+ const MATTR_SDK_VERSION_VALUE = "2.2.0";
1369
1390
  var MessageEventDataType;
1370
1391
  (function(MessageEventDataType) {
1371
1392
  MessageEventDataType["PresentationCompleted"] = "PresentationCompleted";
@@ -1389,7 +1410,8 @@
1389
1410
  const RequestCredentialsOptionsValidator = object({
1390
1411
  credentialQuery: pipe(array(CredentialQueryValidator), nonEmpty()),
1391
1412
  challenge: optional(string()),
1392
- openid4vpConfiguration: optional(union([ OpenId4vpConfigSameDeviceOptionsValidator, OpenId4vpConfigCrossDeviceOptionsValidator, OpenId4vpConfigAutoDetectOptionsValidator ]))
1413
+ openid4vpConfiguration: optional(union([ OpenId4vpConfigSameDeviceOptionsValidator, OpenId4vpConfigCrossDeviceOptionsValidator, OpenId4vpConfigAutoDetectOptionsValidator ])),
1414
+ state: optional(pipe(string(), minLength(1, "state must not be empty")))
1393
1415
  });
1394
1416
  exports.RequestCredentialsErrorType = void 0;
1395
1417
  (function(RequestCredentialsErrorType) {
@@ -1408,6 +1430,7 @@
1408
1430
  RequestCredentialsErrorMessage["DcApiResponseParseError"] = "Failed to parse response from Digital Credentials API";
1409
1431
  RequestCredentialsErrorMessage["Abort"] = "User aborted the session";
1410
1432
  RequestCredentialsErrorMessage["Timeout"] = "User session timeout";
1433
+ RequestCredentialsErrorMessage["StateMismatch"] = "State mismatch between requested session and back-channel result";
1411
1434
  })(RequestCredentialsErrorMessage || (RequestCredentialsErrorMessage = {}));
1412
1435
  exports.AbortSessionErrorType = void 0;
1413
1436
  (function(AbortSessionErrorType) {
@@ -1590,18 +1613,20 @@
1590
1613
  const urlParams = new URLSearchParams(hash.split("#")[1]);
1591
1614
  return urlParams.get(param);
1592
1615
  };
1593
- const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId}) => {
1616
+ const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId, state: state}) => {
1594
1617
  const openid4vpConfiguration = !!walletProviderId || !!redirectUri ? {
1595
1618
  redirectUri: redirectUri,
1596
1619
  walletProviderId: walletProviderId
1597
1620
  } : undefined;
1598
- const postData = {
1621
+ const postData = Object.assign({
1599
1622
  credentialQuery: credentialQuery,
1600
1623
  challenge: challenge,
1601
1624
  applicationId: applicationId,
1602
1625
  dcApiSupported: dcApiSupported,
1603
1626
  openid4vpConfiguration: openid4vpConfiguration
1604
- };
1627
+ }, state !== undefined ? {
1628
+ state: state
1629
+ } : {});
1605
1630
  const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/web/sessions`, {
1606
1631
  method: "POST",
1607
1632
  headers: {
@@ -1708,7 +1733,7 @@
1708
1733
  removeWindowMessageEventListener();
1709
1734
  };
1710
1735
  const receiveMessageHandler = options => async event => {
1711
- const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge} = options;
1736
+ const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge, state: state} = options;
1712
1737
  if (event.origin !== apiBaseUrl) {
1713
1738
  return;
1714
1739
  }
@@ -1730,10 +1755,22 @@
1730
1755
  });
1731
1756
  return;
1732
1757
  }
1758
+ const resultState = "challenge" in result.value ? result.value.state : undefined;
1759
+ if (state !== undefined && resultState !== undefined && state !== resultState) {
1760
+ onFailure({
1761
+ type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
1762
+ message: RequestCredentialsErrorMessage.StateMismatch
1763
+ });
1764
+ closeCrossDeviceModal({
1765
+ container: container
1766
+ });
1767
+ return;
1768
+ }
1733
1769
  onComplete({
1734
1770
  result: "challenge" in result.value ? result.value : undefined,
1735
1771
  sessionId: result.value.sessionId,
1736
- sessionCompletedInRedirect: false
1772
+ sessionCompletedInRedirect: false,
1773
+ state: resultState !== null && resultState !== void 0 ? resultState : state
1737
1774
  });
1738
1775
  closeCrossDeviceModal({
1739
1776
  container: container
@@ -1777,7 +1814,7 @@
1777
1814
  return modalContainer;
1778
1815
  };
1779
1816
  const requestCredentialsWithCrossDevice = async options => {
1780
- const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey} = options;
1817
+ const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey, state: state} = options;
1781
1818
  const container = openCrossDeviceModal({
1782
1819
  sessionUrl: sessionUrl
1783
1820
  });
@@ -1801,6 +1838,7 @@
1801
1838
  sessionId: sessionId,
1802
1839
  apiBaseUrl: apiBaseUrl,
1803
1840
  challenge: challenge,
1841
+ state: state,
1804
1842
  onComplete: data => resolve(ok(data)),
1805
1843
  onFailure: error => resolve(err(error))
1806
1844
  });
@@ -1975,13 +2013,18 @@
1975
2013
  SameDeviceRequestCredentialsErrorMessage["FailedToCreateSession"] = "Failed to create session";
1976
2014
  })(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
1977
2015
  const requestCredentialsSameDevice = async options => {
1978
- const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId} = options;
2016
+ const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId, state: state} = options;
1979
2017
  const abortController = setActiveSession({
1980
2018
  sessionId: sessionId,
1981
2019
  sessionKey: sessionKey
1982
2020
  });
1983
2021
  window.localStorage.setItem(LocalStorageKey.sessionId, sessionId);
1984
2022
  window.localStorage.setItem(LocalStorageKey.challenge, challenge);
2023
+ if (state !== undefined) {
2024
+ window.localStorage.setItem(LocalStorageKey.state, state);
2025
+ } else {
2026
+ window.localStorage.removeItem(LocalStorageKey.state);
2027
+ }
1985
2028
  window.location.assign(sessionUrl);
1986
2029
  await sleep(SESSION_STATUS_POLLING_INITIAL_DELAY_MS);
1987
2030
  const checkResult = await withRetry((async () => {
@@ -2031,7 +2074,7 @@
2031
2074
  }
2032
2075
  assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
2033
2076
  const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initializeOptions;
2034
- const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration} = options;
2077
+ const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration, state: state} = options;
2035
2078
  const dcApiSupported = isDigitalCredentialsApiSupported();
2036
2079
  const openId4VpRedirectUri = deriveOpenId4vpRedirectUri(openid4vpConfiguration);
2037
2080
  const createSessionResult = await createSession({
@@ -2041,7 +2084,8 @@
2041
2084
  walletProviderId: (_a = openid4vpConfiguration === null || openid4vpConfiguration === void 0 ? void 0 : openid4vpConfiguration.walletProviderId) !== null && _a !== void 0 ? _a : undefined,
2042
2085
  apiBaseUrl: apiBaseUrl,
2043
2086
  applicationId: applicationId,
2044
- dcApiSupported: dcApiSupported
2087
+ dcApiSupported: dcApiSupported,
2088
+ state: state
2045
2089
  });
2046
2090
  if (createSessionResult.isErr()) {
2047
2091
  return err({
@@ -2077,7 +2121,8 @@
2077
2121
  applicationId: applicationId,
2078
2122
  sessionUrl: sessionUrl,
2079
2123
  sessionKey: sessionKey,
2080
- sessionId: sessionId
2124
+ sessionId: sessionId,
2125
+ state: state
2081
2126
  });
2082
2127
  }
2083
2128
  return await requestCredentialsWithCrossDevice({
@@ -2085,7 +2130,8 @@
2085
2130
  apiBaseUrl: apiBaseUrl,
2086
2131
  sessionUrl: sessionUrl,
2087
2132
  sessionKey: sessionKey,
2088
- sessionId: sessionId
2133
+ sessionId: sessionId,
2134
+ state: state
2089
2135
  });
2090
2136
  };
2091
2137
  const deriveOpenId4vpRedirectUri = openid4vpConfiguration => {
@@ -2113,8 +2159,10 @@
2113
2159
  HandleRedirectCallbackErrorMessage["FailedToFindChallenge"] = "Failed to find challenge";
2114
2160
  HandleRedirectCallbackErrorMessage["FailedToFindActiveSession"] = "Failed to find active session";
2115
2161
  HandleRedirectCallbackErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
2162
+ HandleRedirectCallbackErrorMessage["StateMismatch"] = "State mismatch between stored session and back-channel result";
2116
2163
  })(HandleRedirectCallbackErrorMessage || (HandleRedirectCallbackErrorMessage = {}));
2117
2164
  const handleRedirectCallback = async () => {
2165
+ var _a;
2118
2166
  const initializeOptions = getInitializeOptions();
2119
2167
  if (!initializeOptions) {
2120
2168
  throw new Exception(InitializeErrorMessage.SdkNotInitialized);
@@ -2129,6 +2177,7 @@
2129
2177
  }
2130
2178
  const sessionId = window.localStorage.getItem(LocalStorageKey.sessionId);
2131
2179
  const challenge = window.localStorage.getItem(LocalStorageKey.challenge);
2180
+ const storedState = (_a = window.localStorage.getItem(LocalStorageKey.state)) !== null && _a !== void 0 ? _a : undefined;
2132
2181
  if (!sessionId || !challenge) {
2133
2182
  return err({
2134
2183
  type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
@@ -2148,9 +2197,22 @@
2148
2197
  cause: result.error
2149
2198
  });
2150
2199
  }
2200
+ const resultState = "challenge" in result.value ? result.value.state : undefined;
2201
+ if (storedState !== undefined && resultState !== undefined && storedState !== resultState) {
2202
+ window.localStorage.removeItem(LocalStorageKey.challenge);
2203
+ window.localStorage.removeItem(LocalStorageKey.sessionId);
2204
+ window.localStorage.removeItem(LocalStorageKey.state);
2205
+ return err({
2206
+ type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
2207
+ message: HandleRedirectCallbackErrorMessage.StateMismatch
2208
+ });
2209
+ }
2210
+ const state = resultState !== null && resultState !== void 0 ? resultState : storedState;
2211
+ window.localStorage.removeItem(LocalStorageKey.state);
2151
2212
  return ok({
2152
2213
  result: "challenge" in result.value ? result.value : undefined,
2153
- sessionId: result.value.sessionId
2214
+ sessionId: result.value.sessionId,
2215
+ state: state
2154
2216
  });
2155
2217
  };
2156
2218
  const utils = {