@mattrglobal/verifier-sdk-web 1.1.1-unstable.16 → 1.1.1-unstable.161
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/README.md +63 -42
- package/dist/lib/verifier-js-no-deps.cjs.js +590 -198
- package/dist/lib/verifier-js-no-deps.cjs.js.map +1 -1
- package/dist/lib/verifier-js.cjs.js +716 -312
- package/dist/lib/verifier-js.cjs.js.map +1 -1
- package/dist/typings/common/safeFetch.d.ts +6 -3
- package/dist/typings/common/sleep.d.ts +1 -0
- package/dist/typings/index.d.ts +6 -6
- package/dist/typings/verifier/abortCredentialRequest.d.ts +6 -0
- package/dist/typings/verifier/handleRedirectCallback.d.ts +1 -1
- package/dist/typings/verifier/index.d.ts +3 -1
- package/dist/typings/verifier/initialize.d.ts +12 -0
- package/dist/typings/verifier/instanceContext.d.ts +7 -0
- package/dist/typings/verifier/requestCredentialsCrossDevice.d.ts +3 -47
- package/dist/typings/verifier/requestCredentialsDigitalCredentialsApi.d.ts +16 -0
- package/dist/typings/verifier/requestCredentialsSameDevice.d.ts +1 -1
- package/dist/typings/verifier/types/credential-presentation.d.ts +129 -21
- package/dist/typings/verifier/types/verifier-web-sdk.d.ts +129 -186
- package/dist/typings/verifier/utils.d.ts +25 -5
- package/dist/verifier-js.development.js +661 -294
- package/dist/verifier-js.development.js.map +1 -1
- package/dist/verifier-js.production.esm.js +2 -2
- package/dist/verifier-js.production.esm.js.map +1 -1
- package/dist/verifier-js.production.js +2 -2
- package/dist/verifier-js.production.js.map +1 -1
- package/package.json +2 -2
- package/dist/typings/verifier/initialise.d.ts +0 -12
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Do Not Translate or Localize
|
|
8
8
|
*
|
|
9
9
|
* Bundle of @mattrglobal/verifier-sdk-web
|
|
10
|
-
* Generated: 2025-
|
|
10
|
+
* Generated: 2025-05-20
|
|
11
11
|
* Version: 1.1.0
|
|
12
12
|
* Dependencies:
|
|
13
13
|
*/
|
|
@@ -89,47 +89,21 @@ const assertType = (validator, message) => data => {
|
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
var SafeFetchCommonRespondErrorType;
|
|
93
|
-
|
|
94
|
-
(function(SafeFetchCommonRespondErrorType) {
|
|
95
|
-
SafeFetchCommonRespondErrorType["UnexpectedRespond"] = "UnexpectedRespond";
|
|
96
|
-
})(SafeFetchCommonRespondErrorType || (SafeFetchCommonRespondErrorType = {}));
|
|
97
|
-
|
|
98
|
-
var SafeFetchErrorType;
|
|
99
|
-
|
|
100
|
-
(function(SafeFetchErrorType) {
|
|
101
|
-
SafeFetchErrorType["HttpError"] = "HttpError";
|
|
102
|
-
SafeFetchErrorType["UnknownError"] = "UnknownError";
|
|
103
|
-
})(SafeFetchErrorType || (SafeFetchErrorType = {}));
|
|
104
|
-
|
|
105
|
-
const safeFetch = async (input, init) => {
|
|
106
|
-
try {
|
|
107
|
-
const response = await fetch(input, init);
|
|
108
|
-
if (response.status > 299 || response.status < 200) {
|
|
109
|
-
return neverthrow.err({
|
|
110
|
-
type: SafeFetchErrorType.HttpError,
|
|
111
|
-
message: `HTTP error, status = ${response.status}`,
|
|
112
|
-
status: response.status
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return neverthrow.ok(response);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
return neverthrow.err({
|
|
118
|
-
type: SafeFetchErrorType.UnknownError,
|
|
119
|
-
message: "Unknown error",
|
|
120
|
-
cause: error
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
92
|
exports.MobileCredentialVerificationReasonType = void 0;
|
|
126
93
|
|
|
127
94
|
(function(MobileCredentialVerificationReasonType) {
|
|
128
|
-
MobileCredentialVerificationReasonType["
|
|
129
|
-
MobileCredentialVerificationReasonType["
|
|
130
|
-
MobileCredentialVerificationReasonType["
|
|
131
|
-
MobileCredentialVerificationReasonType["
|
|
132
|
-
MobileCredentialVerificationReasonType["
|
|
95
|
+
MobileCredentialVerificationReasonType["TrustedIssuerCertificateExpired"] = "TrustedIssuerCertificateExpired";
|
|
96
|
+
MobileCredentialVerificationReasonType["TrustedIssuerCertificateNotYetValid"] = "TrustedIssuerCertificateNotYetValid";
|
|
97
|
+
MobileCredentialVerificationReasonType["IssuerNotTrusted"] = "IssuerNotTrusted";
|
|
98
|
+
MobileCredentialVerificationReasonType["MobileCredentialInvalid"] = "MobileCredentialInvalid";
|
|
99
|
+
MobileCredentialVerificationReasonType["MobileCredentialExpired"] = "MobileCredentialExpired";
|
|
100
|
+
MobileCredentialVerificationReasonType["MobileCredentialNotYetValid"] = "MobileCredentialNotYetValid";
|
|
101
|
+
MobileCredentialVerificationReasonType["InvalidSignerCertificate"] = "InvalidSignerCertificate";
|
|
102
|
+
MobileCredentialVerificationReasonType["DeviceKeyInvalid"] = "DeviceKeyInvalid";
|
|
103
|
+
MobileCredentialVerificationReasonType["UnsupportedCurve"] = "UnsupportedCurve";
|
|
104
|
+
MobileCredentialVerificationReasonType["StatusRevoked"] = "StatusRevoked";
|
|
105
|
+
MobileCredentialVerificationReasonType["StatusSuspended"] = "StatusSuspended";
|
|
106
|
+
MobileCredentialVerificationReasonType["StatusUnknown"] = "StatusUnknown";
|
|
133
107
|
})(exports.MobileCredentialVerificationReasonType || (exports.MobileCredentialVerificationReasonType = {}));
|
|
134
108
|
|
|
135
109
|
exports.ClaimType = void 0;
|
|
@@ -164,6 +138,15 @@ exports.OpenidPresentationCredentialProfileSupported = void 0;
|
|
|
164
138
|
OpenidPresentationCredentialProfileSupported["MOBILE"] = "mobile";
|
|
165
139
|
})(exports.OpenidPresentationCredentialProfileSupported || (exports.OpenidPresentationCredentialProfileSupported = {}));
|
|
166
140
|
|
|
141
|
+
var PresentationStatusCode;
|
|
142
|
+
|
|
143
|
+
(function(PresentationStatusCode) {
|
|
144
|
+
PresentationStatusCode["AwaitingRequestRetrieval"] = "AwaitingRequestRetrieval";
|
|
145
|
+
PresentationStatusCode["AwaitingResponse"] = "AwaitingResponse";
|
|
146
|
+
PresentationStatusCode["ResponseSubmitted"] = "ResponseSubmitted";
|
|
147
|
+
PresentationStatusCode["ResultReady"] = "ResultReady";
|
|
148
|
+
})(PresentationStatusCode || (PresentationStatusCode = {}));
|
|
149
|
+
|
|
167
150
|
const CredentialQueryValidator = v__namespace.object({
|
|
168
151
|
profile: v__namespace.picklist([ exports.OpenidPresentationCredentialProfileSupported.MOBILE ]),
|
|
169
152
|
docType: v__namespace.string(),
|
|
@@ -191,18 +174,63 @@ const PresentationResultRelaxValidator = v__namespace.object({
|
|
|
191
174
|
error: v__namespace.optional(v__namespace.unknown())
|
|
192
175
|
});
|
|
193
176
|
|
|
177
|
+
exports.Mode = void 0;
|
|
178
|
+
|
|
179
|
+
(function(Mode) {
|
|
180
|
+
Mode["SameDevice"] = "sameDevice";
|
|
181
|
+
Mode["CrossDevice"] = "crossDevice";
|
|
182
|
+
})(exports.Mode || (exports.Mode = {}));
|
|
183
|
+
|
|
184
|
+
var SessionType;
|
|
185
|
+
|
|
186
|
+
(function(SessionType) {
|
|
187
|
+
SessionType["DigitalCredentialsApi"] = "digital-credentials-api";
|
|
188
|
+
SessionType["Openid4vp"] = "openid4vp";
|
|
189
|
+
})(SessionType || (SessionType = {}));
|
|
190
|
+
|
|
194
191
|
v__namespace.object({
|
|
195
192
|
credentialQuery: v__namespace.array(CredentialQueryValidator),
|
|
196
193
|
challenge: v__namespace.string(),
|
|
197
194
|
redirectUri: v__namespace.optional(v__namespace.string()),
|
|
198
|
-
walletProviderId: v__namespace.optional(v__namespace.string())
|
|
195
|
+
walletProviderId: v__namespace.optional(v__namespace.string()),
|
|
196
|
+
dcApiSupported: v__namespace.optional(v__namespace.boolean())
|
|
199
197
|
});
|
|
200
198
|
|
|
201
|
-
const
|
|
199
|
+
const CreateSessionDigitalCredentialsValidator = v__namespace.object({
|
|
200
|
+
type: v__namespace.literal(SessionType.DigitalCredentialsApi),
|
|
202
201
|
sessionId: v__namespace.string(),
|
|
202
|
+
sessionKey: v__namespace.string(),
|
|
203
|
+
sessionTtl: v__namespace.number(),
|
|
204
|
+
request: v__namespace.record(v__namespace.string(), v__namespace.any())
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const CreateSessionOpenId4vpResponseValidator = v__namespace.object({
|
|
208
|
+
type: v__namespace.optional(v__namespace.literal(SessionType.Openid4vp)),
|
|
209
|
+
sessionId: v__namespace.string(),
|
|
210
|
+
sessionKey: v__namespace.string(),
|
|
203
211
|
sessionUrl: v__namespace.string()
|
|
204
212
|
});
|
|
205
213
|
|
|
214
|
+
const CreateSessionResponseValidator = v__namespace.union([ CreateSessionDigitalCredentialsValidator, CreateSessionOpenId4vpResponseValidator ]);
|
|
215
|
+
|
|
216
|
+
v__namespace.object({
|
|
217
|
+
sessionId: v__namespace.string(),
|
|
218
|
+
sessionKey: v__namespace.string(),
|
|
219
|
+
apiBaseUrl: v__namespace.string()
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
v__namespace.object({
|
|
223
|
+
sessionId: v__namespace.string(),
|
|
224
|
+
sessionKey: v__namespace.string()
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const GetSessionStatusResponseValidator = v__namespace.union([ v__namespace.object({
|
|
228
|
+
status: v__namespace.picklist([ PresentationStatusCode.ResultReady ]),
|
|
229
|
+
responseCode: v__namespace.optional(v__namespace.string())
|
|
230
|
+
}), v__namespace.object({
|
|
231
|
+
status: v__namespace.string()
|
|
232
|
+
}) ]);
|
|
233
|
+
|
|
206
234
|
var LocalStorageKey;
|
|
207
235
|
|
|
208
236
|
(function(LocalStorageKey) {
|
|
@@ -210,12 +238,9 @@ var LocalStorageKey;
|
|
|
210
238
|
LocalStorageKey["sessionId"] = "mattr_sid";
|
|
211
239
|
})(LocalStorageKey || (LocalStorageKey = {}));
|
|
212
240
|
|
|
213
|
-
|
|
241
|
+
const MATTR_SDK_VERSION_HEADER = "x-mattr-sdk-version";
|
|
214
242
|
|
|
215
|
-
|
|
216
|
-
Mode["sameDevice"] = "sameDevice";
|
|
217
|
-
Mode["crossDevice"] = "crossDevice";
|
|
218
|
-
})(exports.Mode || (exports.Mode = {}));
|
|
243
|
+
const MATTR_SDK_VERSION_VALUE = "2.0.0";
|
|
219
244
|
|
|
220
245
|
var MessageEventDataType;
|
|
221
246
|
|
|
@@ -225,69 +250,186 @@ var MessageEventDataType;
|
|
|
225
250
|
MessageEventDataType["PresentationAbort"] = "PresentationAbort";
|
|
226
251
|
})(MessageEventDataType || (MessageEventDataType = {}));
|
|
227
252
|
|
|
228
|
-
const
|
|
229
|
-
credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
|
|
230
|
-
redirectUri: v__namespace.string(),
|
|
231
|
-
challenge: v__namespace.optional(v__namespace.string()),
|
|
253
|
+
const OpenId4vpConfigSameDeviceOptionsValidator = v__namespace.object({
|
|
232
254
|
walletProviderId: v__namespace.optional(v__namespace.string()),
|
|
233
|
-
mode: v__namespace.
|
|
255
|
+
mode: v__namespace.literal(exports.Mode.SameDevice),
|
|
256
|
+
redirectUri: v__namespace.string()
|
|
234
257
|
});
|
|
235
258
|
|
|
236
|
-
const
|
|
237
|
-
credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
|
|
238
|
-
crossDeviceCallback: v__namespace.object({
|
|
239
|
-
onComplete: v__namespace.function(),
|
|
240
|
-
onFailure: v__namespace.function()
|
|
241
|
-
}),
|
|
242
|
-
challenge: v__namespace.optional(v__namespace.string()),
|
|
259
|
+
const OpenId4vpConfigCrossDeviceOptionsValidator = v__namespace.object({
|
|
243
260
|
walletProviderId: v__namespace.optional(v__namespace.string()),
|
|
244
|
-
mode: v__namespace.
|
|
261
|
+
mode: v__namespace.literal(exports.Mode.CrossDevice)
|
|
245
262
|
});
|
|
246
263
|
|
|
247
|
-
const
|
|
248
|
-
credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
|
|
249
|
-
crossDeviceCallback: v__namespace.object({
|
|
250
|
-
onComplete: v__namespace.function(),
|
|
251
|
-
onFailure: v__namespace.function()
|
|
252
|
-
}),
|
|
253
|
-
redirectUri: v__namespace.string(),
|
|
254
|
-
challenge: v__namespace.optional(v__namespace.string()),
|
|
264
|
+
const OpenId4vpConfigAutoDetectOptionsValidator = v__namespace.object({
|
|
255
265
|
walletProviderId: v__namespace.optional(v__namespace.string()),
|
|
256
|
-
|
|
266
|
+
redirectUri: v__namespace.string(),
|
|
267
|
+
mode: v__namespace.optional(v__namespace.picklist([ exports.Mode.CrossDevice, exports.Mode.SameDevice ]))
|
|
257
268
|
});
|
|
258
269
|
|
|
259
|
-
const RequestCredentialsOptionsValidator = v__namespace.
|
|
270
|
+
const RequestCredentialsOptionsValidator = v__namespace.object({
|
|
271
|
+
credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
|
|
272
|
+
challenge: v__namespace.optional(v__namespace.string()),
|
|
273
|
+
openid4vpConfiguration: v__namespace.optional(v__namespace.union([ OpenId4vpConfigSameDeviceOptionsValidator, OpenId4vpConfigCrossDeviceOptionsValidator, OpenId4vpConfigAutoDetectOptionsValidator ]))
|
|
274
|
+
});
|
|
260
275
|
|
|
261
276
|
exports.RequestCredentialsErrorType = void 0;
|
|
262
277
|
|
|
263
278
|
(function(RequestCredentialsErrorType) {
|
|
264
279
|
RequestCredentialsErrorType["RequestCredentialsFailed"] = "RequestCredentialsFailed";
|
|
280
|
+
RequestCredentialsErrorType["Timeout"] = "Timeout";
|
|
281
|
+
RequestCredentialsErrorType["Abort"] = "Abort";
|
|
265
282
|
})(exports.RequestCredentialsErrorType || (exports.RequestCredentialsErrorType = {}));
|
|
266
283
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
284
|
+
var RequestCredentialsErrorMessage;
|
|
285
|
+
|
|
286
|
+
(function(RequestCredentialsErrorMessage) {
|
|
287
|
+
RequestCredentialsErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
|
|
288
|
+
RequestCredentialsErrorMessage["FailedToGetSessionStatus"] = "Failed to get session status";
|
|
289
|
+
RequestCredentialsErrorMessage["FailedToCreateSession"] = "Failed to create session";
|
|
290
|
+
RequestCredentialsErrorMessage["FailedToVerifyCredentialResponse"] = "Failed to verify credential response";
|
|
291
|
+
RequestCredentialsErrorMessage["MissingOpenId4vpConfig"] = "Identified openid4vp session, but missing openId4vpConfiguration on `requestCredentials`";
|
|
292
|
+
RequestCredentialsErrorMessage["DcApiError"] = "Failed to request credentials with Digital Credentials API";
|
|
293
|
+
RequestCredentialsErrorMessage["DcApiResponseParseError"] = "Failed to parse response from Digital Credentials API";
|
|
294
|
+
RequestCredentialsErrorMessage["Abort"] = "User aborted the session";
|
|
295
|
+
RequestCredentialsErrorMessage["Timeout"] = "User session timeout";
|
|
296
|
+
})(RequestCredentialsErrorMessage || (RequestCredentialsErrorMessage = {}));
|
|
297
|
+
|
|
298
|
+
exports.AbortSessionErrorType = void 0;
|
|
299
|
+
|
|
300
|
+
(function(AbortSessionErrorType) {
|
|
301
|
+
AbortSessionErrorType["AbortSessionFailed"] = "AbortSessionFailed";
|
|
302
|
+
})(exports.AbortSessionErrorType || (exports.AbortSessionErrorType = {}));
|
|
303
|
+
|
|
304
|
+
var AbortSessionErrorMessage;
|
|
305
|
+
|
|
306
|
+
(function(AbortSessionErrorMessage) {
|
|
307
|
+
AbortSessionErrorMessage["FailedToAbortSession"] = "Failed to abort session";
|
|
308
|
+
})(AbortSessionErrorMessage || (AbortSessionErrorMessage = {}));
|
|
309
|
+
|
|
310
|
+
const InitializeOptionsValidator = v__namespace.object({
|
|
311
|
+
apiBaseUrl: v__namespace.pipe(v__namespace.string(), v__namespace.nonEmpty("Must not be empty")),
|
|
312
|
+
applicationId: v__namespace.pipe(v__namespace.string(), v__namespace.nonEmpty("Must not be empty"))
|
|
270
313
|
});
|
|
271
314
|
|
|
272
|
-
|
|
315
|
+
var SafeFetchCommonResponseErrorType;
|
|
273
316
|
|
|
274
|
-
|
|
317
|
+
(function(SafeFetchCommonResponseErrorType) {
|
|
318
|
+
SafeFetchCommonResponseErrorType["UnexpectedResponse"] = "UnexpectedResponse";
|
|
319
|
+
})(SafeFetchCommonResponseErrorType || (SafeFetchCommonResponseErrorType = {}));
|
|
275
320
|
|
|
276
|
-
|
|
277
|
-
InitialiseErrorMessage["SdkNotInitialised"] = "SDK not initialised";
|
|
278
|
-
})(InitialiseErrorMessage || (InitialiseErrorMessage = {}));
|
|
321
|
+
var SafeFetchErrorType;
|
|
279
322
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
323
|
+
(function(SafeFetchErrorType) {
|
|
324
|
+
SafeFetchErrorType["HttpError"] = "HttpError";
|
|
325
|
+
SafeFetchErrorType["UnknownError"] = "UnknownError";
|
|
326
|
+
})(SafeFetchErrorType || (SafeFetchErrorType = {}));
|
|
327
|
+
|
|
328
|
+
const safeFetch = async (input, init) => {
|
|
329
|
+
try {
|
|
330
|
+
const headers = Object.assign(Object.assign({}, init === null || init === void 0 ? void 0 : init.headers), {
|
|
331
|
+
[MATTR_SDK_VERSION_HEADER]: `verifier-sdk-web/${MATTR_SDK_VERSION_VALUE}`
|
|
332
|
+
});
|
|
333
|
+
const response = await fetch(input, Object.assign(Object.assign({}, init), {
|
|
334
|
+
headers: headers
|
|
335
|
+
}));
|
|
336
|
+
if (response.status > 299 || response.status < 200) {
|
|
337
|
+
return neverthrow.err({
|
|
338
|
+
type: SafeFetchErrorType.HttpError,
|
|
339
|
+
message: `HTTP error, status = ${response.status}`,
|
|
340
|
+
status: response.status
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
return neverthrow.ok(response);
|
|
344
|
+
} catch (error) {
|
|
345
|
+
return neverthrow.err({
|
|
346
|
+
type: SafeFetchErrorType.UnknownError,
|
|
347
|
+
message: "Unknown error",
|
|
348
|
+
cause: error
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
let initializeOptions = undefined;
|
|
354
|
+
|
|
355
|
+
var InitializeErrorMessage;
|
|
356
|
+
|
|
357
|
+
(function(InitializeErrorMessage) {
|
|
358
|
+
InitializeErrorMessage["SdkNotInitialized"] = "SDK not initialized";
|
|
359
|
+
})(InitializeErrorMessage || (InitializeErrorMessage = {}));
|
|
360
|
+
|
|
361
|
+
const initialize = options => {
|
|
362
|
+
assertType(InitializeOptionsValidator, "Invalid initialize options")(options);
|
|
363
|
+
initializeOptions = options;
|
|
283
364
|
};
|
|
284
365
|
|
|
285
|
-
const
|
|
366
|
+
const getInitializeOptions = () => initializeOptions;
|
|
367
|
+
|
|
368
|
+
let sessionAbortController = undefined;
|
|
369
|
+
|
|
370
|
+
let _sessionId = undefined;
|
|
371
|
+
|
|
372
|
+
let _sessionKey = undefined;
|
|
373
|
+
|
|
374
|
+
let _sessionTimeoutId = undefined;
|
|
375
|
+
|
|
376
|
+
const getActiveSession = () => {
|
|
377
|
+
const sessionId = _sessionId;
|
|
378
|
+
const sessionKey = _sessionKey;
|
|
379
|
+
const sessionTimeoutId = _sessionTimeoutId;
|
|
380
|
+
if (sessionId) {
|
|
381
|
+
return {
|
|
382
|
+
sessionId: sessionId,
|
|
383
|
+
sessionKey: sessionKey,
|
|
384
|
+
sessionTimeoutId: sessionTimeoutId
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return undefined;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
const setActiveSession = session => {
|
|
391
|
+
const {sessionId: sessionId, sessionKey: sessionKey, sessionTimeoutId: sessionTimeoutId} = session;
|
|
392
|
+
_sessionId = sessionId;
|
|
393
|
+
_sessionKey = sessionKey;
|
|
394
|
+
_sessionTimeoutId = sessionTimeoutId;
|
|
395
|
+
const abortController = new AbortController;
|
|
396
|
+
sessionAbortController = abortController;
|
|
397
|
+
return abortController;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const removeActiveSession = () => {
|
|
401
|
+
sessionAbortController === null || sessionAbortController === void 0 ? void 0 : sessionAbortController.abort();
|
|
402
|
+
if (_sessionTimeoutId) {
|
|
403
|
+
window.clearTimeout(_sessionTimeoutId);
|
|
404
|
+
}
|
|
405
|
+
sessionAbortController = undefined;
|
|
406
|
+
_sessionKey = undefined;
|
|
407
|
+
_sessionId = undefined;
|
|
408
|
+
_sessionTimeoutId = undefined;
|
|
409
|
+
};
|
|
286
410
|
|
|
287
411
|
const defaultRetryDelay = attempt => Math.pow(2, attempt) * 1e3;
|
|
288
412
|
|
|
289
413
|
const defaultRetry = 2;
|
|
290
414
|
|
|
415
|
+
const withRetry = async (fn, options) => {
|
|
416
|
+
const {retries: retries = defaultRetry, retryDelay: retryDelay = defaultRetryDelay, attempt: attempt = 0} = options;
|
|
417
|
+
try {
|
|
418
|
+
return await fn();
|
|
419
|
+
} catch (err) {
|
|
420
|
+
if (retries > 0) {
|
|
421
|
+
const delay = typeof retryDelay === "function" ? retryDelay(attempt) : retryDelay;
|
|
422
|
+
await new Promise((resolve => setTimeout(resolve, delay)));
|
|
423
|
+
return await withRetry(fn, Object.assign(Object.assign({}, options), {
|
|
424
|
+
retries: retries - 1,
|
|
425
|
+
retryDelay: retryDelay,
|
|
426
|
+
attempt: attempt + 1
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
throw err;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
291
433
|
const withRetrySafeFetch = async (fn, options) => {
|
|
292
434
|
const {retries: retries = defaultRetry, retryDelay: retryDelay = defaultRetryDelay, attempt: attempt = 0, retryHttpStatus: retryHttpStatus} = options;
|
|
293
435
|
const result = await fn();
|
|
@@ -316,17 +458,15 @@ const getHashParamValue = (hash, param) => {
|
|
|
316
458
|
return urlParams.get(param);
|
|
317
459
|
};
|
|
318
460
|
|
|
319
|
-
const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl,
|
|
320
|
-
const postData =
|
|
461
|
+
const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId}) => {
|
|
462
|
+
const postData = {
|
|
321
463
|
credentialQuery: credentialQuery,
|
|
322
|
-
challenge: challenge
|
|
323
|
-
|
|
324
|
-
redirectUri: redirectUri
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
walletProviderId: walletProviderId
|
|
329
|
-
} : {});
|
|
464
|
+
challenge: challenge,
|
|
465
|
+
applicationId: applicationId,
|
|
466
|
+
redirectUri: redirectUri,
|
|
467
|
+
walletProviderId: walletProviderId,
|
|
468
|
+
dcApiSupported: dcApiSupported
|
|
469
|
+
};
|
|
330
470
|
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions`, {
|
|
331
471
|
method: "POST",
|
|
332
472
|
headers: {
|
|
@@ -340,8 +480,42 @@ const createSession = async ({credentialQuery: credentialQuery, challenge: chall
|
|
|
340
480
|
const data = await responseResult.value.json();
|
|
341
481
|
if (!isType(CreateSessionResponseValidator)(data)) {
|
|
342
482
|
return neverthrow.err({
|
|
343
|
-
type:
|
|
344
|
-
message: "Create session
|
|
483
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
484
|
+
message: "Create session returned unsupported response"
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
return neverthrow.ok(data);
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
const abortSession = async ({apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey}) => {
|
|
491
|
+
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/abort`, {
|
|
492
|
+
method: "POST",
|
|
493
|
+
headers: {
|
|
494
|
+
"Content-Type": "application/json",
|
|
495
|
+
Authorization: `Bearer ${sessionKey}`
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
if (responseResult.isErr()) {
|
|
499
|
+
return neverthrow.err(responseResult.error);
|
|
500
|
+
}
|
|
501
|
+
return neverthrow.ok(undefined);
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
const getSessionStatus = async ({apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey}) => {
|
|
505
|
+
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/status`, {
|
|
506
|
+
method: "GET",
|
|
507
|
+
headers: {
|
|
508
|
+
Authorization: `Bearer ${sessionKey}`
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
if (responseResult.isErr()) {
|
|
512
|
+
return neverthrow.err(responseResult.error);
|
|
513
|
+
}
|
|
514
|
+
const data = await responseResult.value.json();
|
|
515
|
+
if (!isType(GetSessionStatusResponseValidator)(data)) {
|
|
516
|
+
return neverthrow.err({
|
|
517
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
518
|
+
message: "Get session status return unsupported response"
|
|
345
519
|
});
|
|
346
520
|
}
|
|
347
521
|
return neverthrow.ok(data);
|
|
@@ -369,7 +543,7 @@ const exchangeSessionResult = async ({challenge: challenge, responseCode: respon
|
|
|
369
543
|
const data = await responseResult.value.json();
|
|
370
544
|
if (!isType(PresentationResultRelaxValidator)(data)) {
|
|
371
545
|
return neverthrow.err({
|
|
372
|
-
type:
|
|
546
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
373
547
|
message: "Exchange session result return unsupported response",
|
|
374
548
|
details: {
|
|
375
549
|
data: data
|
|
@@ -384,22 +558,7 @@ const isMobileDetect = userAgent => isMobile.isMobile({
|
|
|
384
558
|
tablet: false
|
|
385
559
|
});
|
|
386
560
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
(function(CrossDeviceCallbackErrorType) {
|
|
390
|
-
CrossDeviceCallbackErrorType["Timeout"] = "Timeout";
|
|
391
|
-
CrossDeviceCallbackErrorType["Abort"] = "Abort";
|
|
392
|
-
CrossDeviceCallbackErrorType["RequestCredentialsFailed"] = "RequestCredentialsFailed";
|
|
393
|
-
})(exports.CrossDeviceCallbackErrorType || (exports.CrossDeviceCallbackErrorType = {}));
|
|
394
|
-
|
|
395
|
-
var CrossDeviceRequestCredentialsErrorMessage;
|
|
396
|
-
|
|
397
|
-
(function(CrossDeviceRequestCredentialsErrorMessage) {
|
|
398
|
-
CrossDeviceRequestCredentialsErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
|
|
399
|
-
CrossDeviceRequestCredentialsErrorMessage["FailedToCreateSession"] = "Failed to create session";
|
|
400
|
-
CrossDeviceRequestCredentialsErrorMessage["Abort"] = "User aborted the session";
|
|
401
|
-
CrossDeviceRequestCredentialsErrorMessage["Timeout"] = "User session timeout";
|
|
402
|
-
})(CrossDeviceRequestCredentialsErrorMessage || (CrossDeviceRequestCredentialsErrorMessage = {}));
|
|
561
|
+
const getVersion = () => MATTR_SDK_VERSION_VALUE;
|
|
403
562
|
|
|
404
563
|
var WindowEventListenerType;
|
|
405
564
|
|
|
@@ -407,10 +566,13 @@ var WindowEventListenerType;
|
|
|
407
566
|
WindowEventListenerType["message"] = "message";
|
|
408
567
|
})(WindowEventListenerType || (WindowEventListenerType = {}));
|
|
409
568
|
|
|
410
|
-
let listener;
|
|
569
|
+
let listener = undefined;
|
|
411
570
|
|
|
412
571
|
const removeWindowMessageEventListener = () => {
|
|
413
|
-
|
|
572
|
+
if (listener) {
|
|
573
|
+
window.removeEventListener(WindowEventListenerType.message, listener, false);
|
|
574
|
+
}
|
|
575
|
+
listener = undefined;
|
|
414
576
|
};
|
|
415
577
|
|
|
416
578
|
const closeCrossDeviceModal = options => {
|
|
@@ -422,8 +584,7 @@ const closeCrossDeviceModal = options => {
|
|
|
422
584
|
};
|
|
423
585
|
|
|
424
586
|
const receiveMessageHandler = options => async event => {
|
|
425
|
-
const {
|
|
426
|
-
const {onComplete: onComplete, onFailure: onFailure} = crossDeviceCallback;
|
|
587
|
+
const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge} = options;
|
|
427
588
|
if (event.origin !== apiBaseUrl) {
|
|
428
589
|
return;
|
|
429
590
|
}
|
|
@@ -437,8 +598,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
437
598
|
});
|
|
438
599
|
if (result.isErr()) {
|
|
439
600
|
onFailure({
|
|
440
|
-
type: exports.
|
|
441
|
-
message:
|
|
601
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
602
|
+
message: RequestCredentialsErrorMessage.FailedToGetSessionResult
|
|
442
603
|
});
|
|
443
604
|
closeCrossDeviceModal({
|
|
444
605
|
container: container
|
|
@@ -446,8 +607,9 @@ const receiveMessageHandler = options => async event => {
|
|
|
446
607
|
return;
|
|
447
608
|
}
|
|
448
609
|
onComplete({
|
|
449
|
-
result: result.value,
|
|
450
|
-
sessionId: result.value.sessionId
|
|
610
|
+
result: "challenge" in result.value ? result.value : undefined,
|
|
611
|
+
sessionId: result.value.sessionId,
|
|
612
|
+
sessionCompletedInRedirect: false
|
|
451
613
|
});
|
|
452
614
|
closeCrossDeviceModal({
|
|
453
615
|
container: container
|
|
@@ -456,8 +618,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
456
618
|
}
|
|
457
619
|
if (event.data.type === MessageEventDataType.PresentationTimeout) {
|
|
458
620
|
onFailure({
|
|
459
|
-
type: exports.
|
|
460
|
-
message:
|
|
621
|
+
type: exports.RequestCredentialsErrorType.Timeout,
|
|
622
|
+
message: RequestCredentialsErrorMessage.Timeout
|
|
461
623
|
});
|
|
462
624
|
closeCrossDeviceModal({
|
|
463
625
|
container: container
|
|
@@ -466,8 +628,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
466
628
|
}
|
|
467
629
|
if (event.data.type === MessageEventDataType.PresentationAbort) {
|
|
468
630
|
onFailure({
|
|
469
|
-
type: exports.
|
|
470
|
-
message:
|
|
631
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
632
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
471
633
|
});
|
|
472
634
|
closeCrossDeviceModal({
|
|
473
635
|
container: container
|
|
@@ -492,41 +654,202 @@ const openCrossDeviceModal = options => {
|
|
|
492
654
|
return modalContainer;
|
|
493
655
|
};
|
|
494
656
|
|
|
495
|
-
const
|
|
496
|
-
const {challenge: challenge,
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
657
|
+
const requestCredentialsWithCrossDevice = async options => {
|
|
658
|
+
const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey} = options;
|
|
659
|
+
const container = openCrossDeviceModal({
|
|
660
|
+
sessionUrl: sessionUrl
|
|
661
|
+
});
|
|
662
|
+
return await new Promise((resolve => {
|
|
663
|
+
const abortController = setActiveSession({
|
|
664
|
+
sessionId: sessionId,
|
|
665
|
+
sessionKey: sessionKey
|
|
666
|
+
});
|
|
667
|
+
abortController.signal.addEventListener("abort", (() => {
|
|
668
|
+
closeCrossDeviceModal({
|
|
669
|
+
container: container
|
|
670
|
+
});
|
|
671
|
+
resolve(neverthrow.err({
|
|
672
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
673
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
674
|
+
}));
|
|
675
|
+
}));
|
|
676
|
+
removeWindowMessageEventListener();
|
|
677
|
+
listener = receiveMessageHandler({
|
|
678
|
+
container: container,
|
|
679
|
+
sessionId: sessionId,
|
|
680
|
+
apiBaseUrl: apiBaseUrl,
|
|
681
|
+
challenge: challenge,
|
|
682
|
+
onComplete: data => resolve(neverthrow.ok(data)),
|
|
683
|
+
onFailure: error => resolve(neverthrow.err(error))
|
|
684
|
+
});
|
|
685
|
+
window.addEventListener(WindowEventListenerType.message, listener, false);
|
|
686
|
+
}));
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
const abortCredentialRequest = async () => {
|
|
690
|
+
const initializeOptions = getInitializeOptions();
|
|
691
|
+
if (!initializeOptions) {
|
|
692
|
+
throw new Exception(InitializeErrorMessage.SdkNotInitialized);
|
|
693
|
+
}
|
|
694
|
+
const {apiBaseUrl: apiBaseUrl} = initializeOptions;
|
|
695
|
+
const session = getActiveSession();
|
|
696
|
+
if (!session || !session.sessionKey) {
|
|
697
|
+
return neverthrow.ok(undefined);
|
|
698
|
+
}
|
|
699
|
+
const {sessionId: sessionId, sessionKey: sessionKey} = session;
|
|
700
|
+
removeActiveSession();
|
|
701
|
+
const abortSessionResult = await abortSession({
|
|
501
702
|
apiBaseUrl: apiBaseUrl,
|
|
502
|
-
|
|
503
|
-
|
|
703
|
+
sessionId: sessionId,
|
|
704
|
+
sessionKey: sessionKey
|
|
504
705
|
});
|
|
505
|
-
if (
|
|
706
|
+
if (abortSessionResult.isErr()) {
|
|
506
707
|
return neverthrow.err({
|
|
507
|
-
type: exports.
|
|
508
|
-
message:
|
|
509
|
-
cause:
|
|
708
|
+
type: exports.AbortSessionErrorType.AbortSessionFailed,
|
|
709
|
+
message: AbortSessionErrorMessage.FailedToAbortSession,
|
|
710
|
+
cause: abortSessionResult.error
|
|
510
711
|
});
|
|
511
712
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
container: container,
|
|
713
|
+
return neverthrow.ok(undefined);
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
const requestCredentialsWithDigitalCredentialsApi = async options => {
|
|
717
|
+
const {apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey, challenge: challenge, request: request, sessionTtl: sessionTtl} = options;
|
|
718
|
+
const sessionTimeoutId = window.setTimeout((() => removeActiveSession()), sessionTtl * 1e3);
|
|
719
|
+
const abortController = setActiveSession({
|
|
520
720
|
sessionId: sessionId,
|
|
721
|
+
sessionKey: sessionKey,
|
|
722
|
+
sessionTimeoutId: sessionTimeoutId
|
|
723
|
+
});
|
|
724
|
+
const credentialResponseResult = await getCredentials(request, abortController);
|
|
725
|
+
if (credentialResponseResult.isErr()) {
|
|
726
|
+
await abortCredentialRequest();
|
|
727
|
+
return neverthrow.err(credentialResponseResult.error);
|
|
728
|
+
}
|
|
729
|
+
const credentialResponse = credentialResponseResult.value;
|
|
730
|
+
const parsedCredentialResponseResult = parseCredentialResponse(credentialResponse);
|
|
731
|
+
if (parsedCredentialResponseResult.isErr()) {
|
|
732
|
+
await abortCredentialRequest();
|
|
733
|
+
return neverthrow.err(parsedCredentialResponseResult.error);
|
|
734
|
+
}
|
|
735
|
+
const parsedCredentialResponse = parsedCredentialResponseResult.value;
|
|
736
|
+
const credentialVerificationResult = await verifyCredentialResponse({
|
|
521
737
|
apiBaseUrl: apiBaseUrl,
|
|
522
|
-
|
|
738
|
+
sessionId: sessionId,
|
|
739
|
+
sessionKey: sessionKey,
|
|
740
|
+
challenge: challenge,
|
|
741
|
+
protocol: parsedCredentialResponse.protocol,
|
|
742
|
+
data: parsedCredentialResponse.data
|
|
523
743
|
});
|
|
524
|
-
|
|
744
|
+
if (credentialVerificationResult.isErr()) {
|
|
745
|
+
return neverthrow.err({
|
|
746
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
747
|
+
message: RequestCredentialsErrorMessage.FailedToVerifyCredentialResponse,
|
|
748
|
+
cause: credentialVerificationResult.error
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
const verificationResult = credentialVerificationResult.value;
|
|
525
752
|
return neverthrow.ok({
|
|
753
|
+
result: "challenge" in verificationResult ? verificationResult : undefined,
|
|
526
754
|
sessionId: sessionId
|
|
527
755
|
});
|
|
528
756
|
};
|
|
529
757
|
|
|
758
|
+
const getCredentials = async (request, abortController) => {
|
|
759
|
+
try {
|
|
760
|
+
const credentialResponse = await navigator.credentials.get(Object.assign(Object.assign({}, request), {
|
|
761
|
+
signal: abortController.signal
|
|
762
|
+
}));
|
|
763
|
+
return neverthrow.ok(credentialResponse);
|
|
764
|
+
} catch (exception) {
|
|
765
|
+
return neverthrow.err({
|
|
766
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
767
|
+
message: RequestCredentialsErrorMessage.DcApiError,
|
|
768
|
+
cause: exception
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
const parseCredentialResponse = credentialResponse => {
|
|
774
|
+
if (!credentialResponse) {
|
|
775
|
+
return neverthrow.err({
|
|
776
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
777
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
778
|
+
details: {
|
|
779
|
+
response: credentialResponse
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
if (typeof credentialResponse === "object") {
|
|
784
|
+
return neverthrow.ok(credentialResponse);
|
|
785
|
+
}
|
|
786
|
+
if (typeof credentialResponse === "string") {
|
|
787
|
+
try {
|
|
788
|
+
const parsed = JSON.parse(credentialResponse);
|
|
789
|
+
return neverthrow.ok(parsed);
|
|
790
|
+
} catch (_a) {
|
|
791
|
+
return neverthrow.err({
|
|
792
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
793
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
794
|
+
details: {
|
|
795
|
+
response: credentialResponse
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return neverthrow.err({
|
|
801
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
802
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
803
|
+
details: {
|
|
804
|
+
response: credentialResponse
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
const verifyCredentialResponse = async options => {
|
|
810
|
+
const {apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey, challenge: challenge, protocol: protocol, data: data} = options;
|
|
811
|
+
const requestBody = {
|
|
812
|
+
protocol: protocol,
|
|
813
|
+
data: data,
|
|
814
|
+
challenge: challenge
|
|
815
|
+
};
|
|
816
|
+
const credentialVerificationResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/dc-api/response`, {
|
|
817
|
+
method: "POST",
|
|
818
|
+
headers: {
|
|
819
|
+
"Content-Type": "application/json",
|
|
820
|
+
Authorization: `Bearer ${sessionKey}`
|
|
821
|
+
},
|
|
822
|
+
body: JSON.stringify(requestBody)
|
|
823
|
+
});
|
|
824
|
+
if (credentialVerificationResult.isErr()) {
|
|
825
|
+
return neverthrow.err(credentialVerificationResult.error);
|
|
826
|
+
}
|
|
827
|
+
const credentialVerificationResponse = await credentialVerificationResult.value.json();
|
|
828
|
+
if (!isType(PresentationResultRelaxValidator)(credentialVerificationResponse)) {
|
|
829
|
+
return neverthrow.err({
|
|
830
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
831
|
+
message: "Verify credential returned unsupported response",
|
|
832
|
+
details: {
|
|
833
|
+
response: credentialVerificationResponse
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
return neverthrow.ok(credentialVerificationResponse);
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
const isDigitalCredentialsApiSupported = () => {
|
|
841
|
+
var _a;
|
|
842
|
+
return "DigitalCredential" in window && typeof window.DigitalCredential === "function" && typeof ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.credentials) === null || _a === void 0 ? void 0 : _a.get) === "function";
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
const sleep = ms => new Promise((resolve => setTimeout(resolve, ms)));
|
|
846
|
+
|
|
847
|
+
const SESSION_STATUS_POLLING_MAX_RETRY = 1e3;
|
|
848
|
+
|
|
849
|
+
const SESSION_STATUS_POLLING_INTERVAL_MS = 3e3;
|
|
850
|
+
|
|
851
|
+
const SESSION_STATUS_POLLING_INITIAL_DELAY_MS = 3e3;
|
|
852
|
+
|
|
530
853
|
var SameDeviceRequestCredentialsErrorMessage;
|
|
531
854
|
|
|
532
855
|
(function(SameDeviceRequestCredentialsErrorMessage) {
|
|
@@ -535,65 +858,135 @@ var SameDeviceRequestCredentialsErrorMessage;
|
|
|
535
858
|
})(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
|
|
536
859
|
|
|
537
860
|
const requestCredentialsSameDevice = async options => {
|
|
538
|
-
const {challenge: challenge,
|
|
539
|
-
const
|
|
861
|
+
const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId} = options;
|
|
862
|
+
const abortController = setActiveSession({
|
|
863
|
+
sessionId: sessionId,
|
|
864
|
+
sessionKey: sessionKey
|
|
865
|
+
});
|
|
866
|
+
window.localStorage.setItem(LocalStorageKey.sessionId, sessionId);
|
|
540
867
|
window.localStorage.setItem(LocalStorageKey.challenge, challenge);
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
868
|
+
window.location.assign(sessionUrl);
|
|
869
|
+
await sleep(SESSION_STATUS_POLLING_INITIAL_DELAY_MS);
|
|
870
|
+
const checkResult = await withRetry((async () => {
|
|
871
|
+
const statusResult = await getSessionStatus({
|
|
872
|
+
apiBaseUrl: apiBaseUrl,
|
|
873
|
+
applicationId: applicationId,
|
|
874
|
+
sessionId: sessionId,
|
|
875
|
+
sessionKey: sessionKey
|
|
546
876
|
});
|
|
877
|
+
if (abortController.signal.aborted) {
|
|
878
|
+
return neverthrow.err({
|
|
879
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
880
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
if (statusResult.isErr()) {
|
|
884
|
+
if (statusResult.error.status === 404) {
|
|
885
|
+
return neverthrow.err({
|
|
886
|
+
type: exports.RequestCredentialsErrorType.Timeout,
|
|
887
|
+
message: RequestCredentialsErrorMessage.Timeout
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
throw Error("Unexpected status response. Retry");
|
|
891
|
+
}
|
|
892
|
+
if (statusResult.value.status !== PresentationStatusCode.ResultReady) {
|
|
893
|
+
throw Error("Result is not ready. Retry");
|
|
894
|
+
}
|
|
895
|
+
return neverthrow.ok(undefined);
|
|
896
|
+
}), {
|
|
897
|
+
retries: SESSION_STATUS_POLLING_MAX_RETRY,
|
|
898
|
+
retryDelay: SESSION_STATUS_POLLING_INTERVAL_MS
|
|
899
|
+
});
|
|
900
|
+
if (checkResult.isErr()) {
|
|
901
|
+
return neverthrow.err(checkResult.error);
|
|
902
|
+
}
|
|
903
|
+
window.close();
|
|
904
|
+
return neverthrow.ok({
|
|
905
|
+
sessionId: sessionId,
|
|
906
|
+
sessionCompletedInRedirect: true
|
|
907
|
+
});
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
const requestCredentials = async options => {
|
|
911
|
+
var _a;
|
|
912
|
+
const initializeOptions = getInitializeOptions();
|
|
913
|
+
if (!initializeOptions) {
|
|
914
|
+
throw new Exception(InitializeErrorMessage.SdkNotInitialized);
|
|
547
915
|
}
|
|
916
|
+
assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
|
|
917
|
+
const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initializeOptions;
|
|
918
|
+
const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration} = options;
|
|
919
|
+
const dcApiSupported = isDigitalCredentialsApiSupported();
|
|
920
|
+
const openId4VpRedirectUri = deriveOpenId4vpRedirectUri(openid4vpConfiguration);
|
|
548
921
|
const createSessionResult = await createSession({
|
|
549
922
|
credentialQuery: credentialQuery,
|
|
550
|
-
challenge:
|
|
551
|
-
redirectUri:
|
|
923
|
+
challenge: challenge,
|
|
924
|
+
redirectUri: openId4VpRedirectUri,
|
|
925
|
+
walletProviderId: (_a = openid4vpConfiguration === null || openid4vpConfiguration === void 0 ? void 0 : openid4vpConfiguration.walletProviderId) !== null && _a !== void 0 ? _a : undefined,
|
|
552
926
|
apiBaseUrl: apiBaseUrl,
|
|
553
927
|
applicationId: applicationId,
|
|
554
|
-
|
|
928
|
+
dcApiSupported: dcApiSupported
|
|
555
929
|
});
|
|
556
930
|
if (createSessionResult.isErr()) {
|
|
557
931
|
return neverthrow.err({
|
|
558
932
|
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
559
|
-
message:
|
|
933
|
+
message: RequestCredentialsErrorMessage.FailedToCreateSession,
|
|
560
934
|
cause: createSessionResult.error
|
|
561
935
|
});
|
|
562
936
|
}
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
937
|
+
const session = createSessionResult.value;
|
|
938
|
+
const {sessionKey: sessionKey, sessionId: sessionId} = session;
|
|
939
|
+
if (session.type === SessionType.DigitalCredentialsApi) {
|
|
940
|
+
const {request: request, sessionTtl: sessionTtl} = session;
|
|
941
|
+
return await requestCredentialsWithDigitalCredentialsApi({
|
|
942
|
+
apiBaseUrl: apiBaseUrl,
|
|
943
|
+
request: request,
|
|
944
|
+
sessionId: sessionId,
|
|
945
|
+
sessionKey: sessionKey,
|
|
946
|
+
challenge: challenge,
|
|
947
|
+
sessionTtl: sessionTtl
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
if (!openid4vpConfiguration) {
|
|
951
|
+
return neverthrow.err({
|
|
952
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
953
|
+
message: RequestCredentialsErrorMessage.MissingOpenId4vpConfig
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
const {sessionUrl: sessionUrl} = session;
|
|
957
|
+
if (openId4VpRedirectUri) {
|
|
958
|
+
return await requestCredentialsSameDevice({
|
|
959
|
+
challenge: challenge,
|
|
960
|
+
apiBaseUrl: apiBaseUrl,
|
|
961
|
+
applicationId: applicationId,
|
|
962
|
+
sessionUrl: sessionUrl,
|
|
963
|
+
sessionKey: sessionKey,
|
|
964
|
+
sessionId: sessionId
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
return await requestCredentialsWithCrossDevice({
|
|
968
|
+
challenge: challenge,
|
|
969
|
+
apiBaseUrl: apiBaseUrl,
|
|
970
|
+
sessionUrl: sessionUrl,
|
|
971
|
+
sessionKey: sessionKey,
|
|
567
972
|
sessionId: sessionId
|
|
568
973
|
});
|
|
569
974
|
};
|
|
570
975
|
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (!initialiseOptions) {
|
|
575
|
-
throw new Exception(InitialiseErrorMessage.SdkNotInitialised);
|
|
976
|
+
const deriveOpenId4vpRedirectUri = openid4vpConfiguration => {
|
|
977
|
+
if (!openid4vpConfiguration) {
|
|
978
|
+
return undefined;
|
|
576
979
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
initialiseOptions: initialiseOptions,
|
|
583
|
-
challenge: challenge,
|
|
584
|
-
mode: mode
|
|
585
|
-
}));
|
|
980
|
+
let detectedMode;
|
|
981
|
+
if (openid4vpConfiguration && openid4vpConfiguration.mode) {
|
|
982
|
+
detectedMode = openid4vpConfiguration.mode;
|
|
983
|
+
} else {
|
|
984
|
+
detectedMode = isMobileDetect(navigator.userAgent) ? exports.Mode.SameDevice : exports.Mode.CrossDevice;
|
|
586
985
|
}
|
|
587
|
-
if (
|
|
588
|
-
return
|
|
589
|
-
initialiseOptions: initialiseOptions,
|
|
590
|
-
challenge: challenge,
|
|
591
|
-
mode: mode
|
|
592
|
-
}));
|
|
986
|
+
if (detectedMode === exports.Mode.SameDevice && !isType(OpenId4vpConfigCrossDeviceOptionsValidator)(openid4vpConfiguration) && openid4vpConfiguration.redirectUri) {
|
|
987
|
+
return openid4vpConfiguration.redirectUri;
|
|
593
988
|
}
|
|
594
|
-
|
|
595
|
-
data: options
|
|
596
|
-
});
|
|
989
|
+
return undefined;
|
|
597
990
|
};
|
|
598
991
|
|
|
599
992
|
exports.HandleRedirectCallbackErrorType = void 0;
|
|
@@ -607,16 +1000,16 @@ var HandleRedirectCallbackErrorMessage;
|
|
|
607
1000
|
(function(HandleRedirectCallbackErrorMessage) {
|
|
608
1001
|
HandleRedirectCallbackErrorMessage["FailedToFindResponseCode"] = "Failed to find response code";
|
|
609
1002
|
HandleRedirectCallbackErrorMessage["FailedToFindChallenge"] = "Failed to find challenge";
|
|
610
|
-
HandleRedirectCallbackErrorMessage["
|
|
1003
|
+
HandleRedirectCallbackErrorMessage["FailedToFindActiveSession"] = "Failed to find active session";
|
|
611
1004
|
HandleRedirectCallbackErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
|
|
612
1005
|
})(HandleRedirectCallbackErrorMessage || (HandleRedirectCallbackErrorMessage = {}));
|
|
613
1006
|
|
|
614
1007
|
const handleRedirectCallback = async () => {
|
|
615
|
-
const
|
|
616
|
-
if (!
|
|
617
|
-
throw new Exception(
|
|
1008
|
+
const initializeOptions = getInitializeOptions();
|
|
1009
|
+
if (!initializeOptions) {
|
|
1010
|
+
throw new Exception(InitializeErrorMessage.SdkNotInitialized);
|
|
618
1011
|
}
|
|
619
|
-
const {apiBaseUrl: apiBaseUrl} =
|
|
1012
|
+
const {apiBaseUrl: apiBaseUrl} = initializeOptions;
|
|
620
1013
|
const responseCode = getHashParamValue(window.location.hash, "response_code");
|
|
621
1014
|
if (!responseCode) {
|
|
622
1015
|
return neverthrow.err({
|
|
@@ -624,18 +1017,12 @@ const handleRedirectCallback = async () => {
|
|
|
624
1017
|
message: HandleRedirectCallbackErrorMessage.FailedToFindResponseCode
|
|
625
1018
|
});
|
|
626
1019
|
}
|
|
627
|
-
const challenge = window.localStorage.getItem(LocalStorageKey.challenge);
|
|
628
|
-
if (!challenge) {
|
|
629
|
-
return neverthrow.err({
|
|
630
|
-
type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
|
|
631
|
-
message: HandleRedirectCallbackErrorMessage.FailedToFindChallenge
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
1020
|
const sessionId = window.localStorage.getItem(LocalStorageKey.sessionId);
|
|
635
|
-
|
|
1021
|
+
const challenge = window.localStorage.getItem(LocalStorageKey.challenge);
|
|
1022
|
+
if (!sessionId || !challenge) {
|
|
636
1023
|
return neverthrow.err({
|
|
637
1024
|
type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
|
|
638
|
-
message: HandleRedirectCallbackErrorMessage.
|
|
1025
|
+
message: HandleRedirectCallbackErrorMessage.FailedToFindActiveSession
|
|
639
1026
|
});
|
|
640
1027
|
}
|
|
641
1028
|
const result = await exchangeSessionResult({
|
|
@@ -652,19 +1039,24 @@ const handleRedirectCallback = async () => {
|
|
|
652
1039
|
});
|
|
653
1040
|
}
|
|
654
1041
|
return neverthrow.ok({
|
|
655
|
-
result: result.value,
|
|
1042
|
+
result: "challenge" in result.value ? result.value : undefined,
|
|
656
1043
|
sessionId: result.value.sessionId
|
|
657
1044
|
});
|
|
658
1045
|
};
|
|
659
1046
|
|
|
660
1047
|
const utils = {
|
|
661
1048
|
generateChallenge: generateChallenge,
|
|
1049
|
+
getVersion: getVersion,
|
|
662
1050
|
unwrap: unwrap
|
|
663
1051
|
};
|
|
664
1052
|
|
|
1053
|
+
exports.abortCredentialRequest = abortCredentialRequest;
|
|
1054
|
+
|
|
665
1055
|
exports.handleRedirectCallback = handleRedirectCallback;
|
|
666
1056
|
|
|
667
|
-
exports.
|
|
1057
|
+
exports.initialize = initialize;
|
|
1058
|
+
|
|
1059
|
+
exports.isDigitalCredentialsApiSupported = isDigitalCredentialsApiSupported;
|
|
668
1060
|
|
|
669
1061
|
exports.requestCredentials = requestCredentials;
|
|
670
1062
|
|