@mattrglobal/verifier-sdk-web 1.1.1-unstable.15 → 1.1.1-unstable.153
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 +39 -24
- package/dist/lib/verifier-js-no-deps.cjs.js +563 -185
- package/dist/lib/verifier-js-no-deps.cjs.js.map +1 -1
- package/dist/lib/verifier-js.cjs.js +689 -299
- 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 +2 -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 +127 -20
- package/dist/typings/verifier/types/verifier-web-sdk.d.ts +124 -183
- package/dist/typings/verifier/utils.d.ts +25 -5
- package/dist/verifier-js.development.js +635 -281
- 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
|
@@ -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-16
|
|
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,50 +250,106 @@ 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
|
|
|
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
|
+
|
|
267
310
|
const InitialiseOptionsValidator = v__namespace.object({
|
|
268
|
-
apiBaseUrl: v__namespace.string(),
|
|
269
|
-
applicationId: v__namespace.
|
|
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
|
|
|
315
|
+
var SafeFetchCommonResponseErrorType;
|
|
316
|
+
|
|
317
|
+
(function(SafeFetchCommonResponseErrorType) {
|
|
318
|
+
SafeFetchCommonResponseErrorType["UnexpectedResponse"] = "UnexpectedResponse";
|
|
319
|
+
})(SafeFetchCommonResponseErrorType || (SafeFetchCommonResponseErrorType = {}));
|
|
320
|
+
|
|
321
|
+
var SafeFetchErrorType;
|
|
322
|
+
|
|
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
|
+
|
|
272
353
|
let initialiseOptions = undefined;
|
|
273
354
|
|
|
274
355
|
var InitialiseErrorMessage;
|
|
@@ -284,10 +365,62 @@ const initialise = options => {
|
|
|
284
365
|
|
|
285
366
|
const getInitialiseOptions = () => initialiseOptions;
|
|
286
367
|
|
|
368
|
+
let sessionAbortController = undefined;
|
|
369
|
+
|
|
370
|
+
let _sessionId = undefined;
|
|
371
|
+
|
|
372
|
+
let _sessionKey = undefined;
|
|
373
|
+
|
|
374
|
+
const getActiveSession = () => {
|
|
375
|
+
const sessionId = _sessionId;
|
|
376
|
+
const sessionKey = _sessionKey;
|
|
377
|
+
if (sessionId) {
|
|
378
|
+
return {
|
|
379
|
+
sessionId: sessionId,
|
|
380
|
+
sessionKey: sessionKey
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
return undefined;
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const setActiveSession = session => {
|
|
387
|
+
const {sessionId: sessionId, sessionKey: sessionKey} = session;
|
|
388
|
+
_sessionId = sessionId;
|
|
389
|
+
_sessionKey = sessionKey;
|
|
390
|
+
const abortController = new AbortController;
|
|
391
|
+
sessionAbortController = abortController;
|
|
392
|
+
return abortController;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
const removeActiveSession = () => {
|
|
396
|
+
sessionAbortController === null || sessionAbortController === void 0 ? void 0 : sessionAbortController.abort();
|
|
397
|
+
sessionAbortController = undefined;
|
|
398
|
+
_sessionKey = undefined;
|
|
399
|
+
_sessionId = undefined;
|
|
400
|
+
};
|
|
401
|
+
|
|
287
402
|
const defaultRetryDelay = attempt => Math.pow(2, attempt) * 1e3;
|
|
288
403
|
|
|
289
404
|
const defaultRetry = 2;
|
|
290
405
|
|
|
406
|
+
const withRetry = async (fn, options) => {
|
|
407
|
+
const {retries: retries = defaultRetry, retryDelay: retryDelay = defaultRetryDelay, attempt: attempt = 0} = options;
|
|
408
|
+
try {
|
|
409
|
+
return await fn();
|
|
410
|
+
} catch (err) {
|
|
411
|
+
if (retries > 0) {
|
|
412
|
+
const delay = typeof retryDelay === "function" ? retryDelay(attempt) : retryDelay;
|
|
413
|
+
await new Promise((resolve => setTimeout(resolve, delay)));
|
|
414
|
+
return await withRetry(fn, Object.assign(Object.assign({}, options), {
|
|
415
|
+
retries: retries - 1,
|
|
416
|
+
retryDelay: retryDelay,
|
|
417
|
+
attempt: attempt + 1
|
|
418
|
+
}));
|
|
419
|
+
}
|
|
420
|
+
throw err;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
291
424
|
const withRetrySafeFetch = async (fn, options) => {
|
|
292
425
|
const {retries: retries = defaultRetry, retryDelay: retryDelay = defaultRetryDelay, attempt: attempt = 0, retryHttpStatus: retryHttpStatus} = options;
|
|
293
426
|
const result = await fn();
|
|
@@ -316,17 +449,15 @@ const getHashParamValue = (hash, param) => {
|
|
|
316
449
|
return urlParams.get(param);
|
|
317
450
|
};
|
|
318
451
|
|
|
319
|
-
const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl,
|
|
320
|
-
const postData =
|
|
452
|
+
const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId, dcApiSupported: dcApiSupported, applicationId: applicationId}) => {
|
|
453
|
+
const postData = {
|
|
321
454
|
credentialQuery: credentialQuery,
|
|
322
|
-
challenge: challenge
|
|
323
|
-
|
|
324
|
-
redirectUri: redirectUri
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
walletProviderId: walletProviderId
|
|
329
|
-
} : {});
|
|
455
|
+
challenge: challenge,
|
|
456
|
+
applicationId: applicationId,
|
|
457
|
+
redirectUri: redirectUri,
|
|
458
|
+
walletProviderId: walletProviderId,
|
|
459
|
+
dcApiSupported: dcApiSupported
|
|
460
|
+
};
|
|
330
461
|
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions`, {
|
|
331
462
|
method: "POST",
|
|
332
463
|
headers: {
|
|
@@ -340,8 +471,42 @@ const createSession = async ({credentialQuery: credentialQuery, challenge: chall
|
|
|
340
471
|
const data = await responseResult.value.json();
|
|
341
472
|
if (!isType(CreateSessionResponseValidator)(data)) {
|
|
342
473
|
return neverthrow.err({
|
|
343
|
-
type:
|
|
344
|
-
message: "Create session
|
|
474
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
475
|
+
message: "Create session returned unsupported response"
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
return neverthrow.ok(data);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
const abortSession = async ({apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey}) => {
|
|
482
|
+
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/abort`, {
|
|
483
|
+
method: "POST",
|
|
484
|
+
headers: {
|
|
485
|
+
"Content-Type": "application/json",
|
|
486
|
+
Authorization: `Bearer ${sessionKey}`
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
if (responseResult.isErr()) {
|
|
490
|
+
return neverthrow.err(responseResult.error);
|
|
491
|
+
}
|
|
492
|
+
return neverthrow.ok(undefined);
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const getSessionStatus = async ({apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey}) => {
|
|
496
|
+
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/status`, {
|
|
497
|
+
method: "GET",
|
|
498
|
+
headers: {
|
|
499
|
+
Authorization: `Bearer ${sessionKey}`
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
if (responseResult.isErr()) {
|
|
503
|
+
return neverthrow.err(responseResult.error);
|
|
504
|
+
}
|
|
505
|
+
const data = await responseResult.value.json();
|
|
506
|
+
if (!isType(GetSessionStatusResponseValidator)(data)) {
|
|
507
|
+
return neverthrow.err({
|
|
508
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
509
|
+
message: "Get session status return unsupported response"
|
|
345
510
|
});
|
|
346
511
|
}
|
|
347
512
|
return neverthrow.ok(data);
|
|
@@ -369,7 +534,7 @@ const exchangeSessionResult = async ({challenge: challenge, responseCode: respon
|
|
|
369
534
|
const data = await responseResult.value.json();
|
|
370
535
|
if (!isType(PresentationResultRelaxValidator)(data)) {
|
|
371
536
|
return neverthrow.err({
|
|
372
|
-
type:
|
|
537
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
373
538
|
message: "Exchange session result return unsupported response",
|
|
374
539
|
details: {
|
|
375
540
|
data: data
|
|
@@ -384,22 +549,7 @@ const isMobileDetect = userAgent => isMobile.isMobile({
|
|
|
384
549
|
tablet: false
|
|
385
550
|
});
|
|
386
551
|
|
|
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 = {}));
|
|
552
|
+
const getVersion = () => MATTR_SDK_VERSION_VALUE;
|
|
403
553
|
|
|
404
554
|
var WindowEventListenerType;
|
|
405
555
|
|
|
@@ -407,10 +557,13 @@ var WindowEventListenerType;
|
|
|
407
557
|
WindowEventListenerType["message"] = "message";
|
|
408
558
|
})(WindowEventListenerType || (WindowEventListenerType = {}));
|
|
409
559
|
|
|
410
|
-
let listener;
|
|
560
|
+
let listener = undefined;
|
|
411
561
|
|
|
412
562
|
const removeWindowMessageEventListener = () => {
|
|
413
|
-
|
|
563
|
+
if (listener) {
|
|
564
|
+
window.removeEventListener(WindowEventListenerType.message, listener, false);
|
|
565
|
+
}
|
|
566
|
+
listener = undefined;
|
|
414
567
|
};
|
|
415
568
|
|
|
416
569
|
const closeCrossDeviceModal = options => {
|
|
@@ -422,8 +575,7 @@ const closeCrossDeviceModal = options => {
|
|
|
422
575
|
};
|
|
423
576
|
|
|
424
577
|
const receiveMessageHandler = options => async event => {
|
|
425
|
-
const {
|
|
426
|
-
const {onComplete: onComplete, onFailure: onFailure} = crossDeviceCallback;
|
|
578
|
+
const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge} = options;
|
|
427
579
|
if (event.origin !== apiBaseUrl) {
|
|
428
580
|
return;
|
|
429
581
|
}
|
|
@@ -437,8 +589,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
437
589
|
});
|
|
438
590
|
if (result.isErr()) {
|
|
439
591
|
onFailure({
|
|
440
|
-
type: exports.
|
|
441
|
-
message:
|
|
592
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
593
|
+
message: RequestCredentialsErrorMessage.FailedToGetSessionResult
|
|
442
594
|
});
|
|
443
595
|
closeCrossDeviceModal({
|
|
444
596
|
container: container
|
|
@@ -446,8 +598,9 @@ const receiveMessageHandler = options => async event => {
|
|
|
446
598
|
return;
|
|
447
599
|
}
|
|
448
600
|
onComplete({
|
|
449
|
-
result: result.value,
|
|
450
|
-
sessionId: result.value.sessionId
|
|
601
|
+
result: "challenge" in result.value ? result.value : undefined,
|
|
602
|
+
sessionId: result.value.sessionId,
|
|
603
|
+
sessionCompletedInRedirect: false
|
|
451
604
|
});
|
|
452
605
|
closeCrossDeviceModal({
|
|
453
606
|
container: container
|
|
@@ -456,8 +609,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
456
609
|
}
|
|
457
610
|
if (event.data.type === MessageEventDataType.PresentationTimeout) {
|
|
458
611
|
onFailure({
|
|
459
|
-
type: exports.
|
|
460
|
-
message:
|
|
612
|
+
type: exports.RequestCredentialsErrorType.Timeout,
|
|
613
|
+
message: RequestCredentialsErrorMessage.Timeout
|
|
461
614
|
});
|
|
462
615
|
closeCrossDeviceModal({
|
|
463
616
|
container: container
|
|
@@ -466,8 +619,8 @@ const receiveMessageHandler = options => async event => {
|
|
|
466
619
|
}
|
|
467
620
|
if (event.data.type === MessageEventDataType.PresentationAbort) {
|
|
468
621
|
onFailure({
|
|
469
|
-
type: exports.
|
|
470
|
-
message:
|
|
622
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
623
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
471
624
|
});
|
|
472
625
|
closeCrossDeviceModal({
|
|
473
626
|
container: container
|
|
@@ -492,41 +645,171 @@ const openCrossDeviceModal = options => {
|
|
|
492
645
|
return modalContainer;
|
|
493
646
|
};
|
|
494
647
|
|
|
495
|
-
const
|
|
496
|
-
const {challenge: challenge,
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
648
|
+
const requestCredentialsWithCrossDevice = async options => {
|
|
649
|
+
const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey} = options;
|
|
650
|
+
const container = openCrossDeviceModal({
|
|
651
|
+
sessionUrl: sessionUrl
|
|
652
|
+
});
|
|
653
|
+
return await new Promise((resolve => {
|
|
654
|
+
const abortController = setActiveSession({
|
|
655
|
+
sessionId: sessionId,
|
|
656
|
+
sessionKey: sessionKey
|
|
657
|
+
});
|
|
658
|
+
abortController.signal.addEventListener("abort", (() => {
|
|
659
|
+
closeCrossDeviceModal({
|
|
660
|
+
container: container
|
|
661
|
+
});
|
|
662
|
+
resolve(neverthrow.err({
|
|
663
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
664
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
665
|
+
}));
|
|
666
|
+
}));
|
|
667
|
+
removeWindowMessageEventListener();
|
|
668
|
+
listener = receiveMessageHandler({
|
|
669
|
+
container: container,
|
|
670
|
+
sessionId: sessionId,
|
|
671
|
+
apiBaseUrl: apiBaseUrl,
|
|
672
|
+
challenge: challenge,
|
|
673
|
+
onComplete: data => resolve(neverthrow.ok(data)),
|
|
674
|
+
onFailure: error => resolve(neverthrow.err(error))
|
|
675
|
+
});
|
|
676
|
+
window.addEventListener(WindowEventListenerType.message, listener, false);
|
|
677
|
+
}));
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
const requestCredentialsWithDigitalCredentialsApi = async options => {
|
|
681
|
+
const {apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey, challenge: challenge, request: request} = options;
|
|
682
|
+
const credentialResponseResult = await getCredentials(request);
|
|
683
|
+
if (credentialResponseResult.isErr()) {
|
|
684
|
+
await abortSession({
|
|
685
|
+
apiBaseUrl: apiBaseUrl,
|
|
686
|
+
sessionId: sessionId,
|
|
687
|
+
sessionKey: sessionKey
|
|
688
|
+
});
|
|
689
|
+
return neverthrow.err(credentialResponseResult.error);
|
|
690
|
+
}
|
|
691
|
+
const credentialResponse = credentialResponseResult.value;
|
|
692
|
+
const parsedCredentialResponseResult = parseCredentialResponse(credentialResponse);
|
|
693
|
+
if (parsedCredentialResponseResult.isErr()) {
|
|
694
|
+
await abortSession({
|
|
695
|
+
apiBaseUrl: apiBaseUrl,
|
|
696
|
+
sessionId: sessionId,
|
|
697
|
+
sessionKey: sessionKey
|
|
698
|
+
});
|
|
699
|
+
return neverthrow.err(parsedCredentialResponseResult.error);
|
|
700
|
+
}
|
|
701
|
+
const parsedCredentialResponse = parsedCredentialResponseResult.value;
|
|
702
|
+
const credentialVerificationResult = await verifyCredentialResponse({
|
|
501
703
|
apiBaseUrl: apiBaseUrl,
|
|
502
|
-
|
|
503
|
-
|
|
704
|
+
sessionId: sessionId,
|
|
705
|
+
sessionKey: sessionKey,
|
|
706
|
+
challenge: challenge,
|
|
707
|
+
protocol: parsedCredentialResponse.protocol,
|
|
708
|
+
data: parsedCredentialResponse.data
|
|
504
709
|
});
|
|
505
|
-
if (
|
|
710
|
+
if (credentialVerificationResult.isErr()) {
|
|
506
711
|
return neverthrow.err({
|
|
507
712
|
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
508
|
-
message:
|
|
509
|
-
cause:
|
|
713
|
+
message: RequestCredentialsErrorMessage.FailedToVerifyCredentialResponse,
|
|
714
|
+
cause: credentialVerificationResult.error
|
|
510
715
|
});
|
|
511
716
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
717
|
+
return neverthrow.ok(credentialVerificationResult.value);
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
const getCredentials = async request => {
|
|
721
|
+
try {
|
|
722
|
+
const credentialResponse = await navigator.credentials.get(request);
|
|
723
|
+
return neverthrow.ok(credentialResponse);
|
|
724
|
+
} catch (exception) {
|
|
725
|
+
return neverthrow.err({
|
|
726
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
727
|
+
message: RequestCredentialsErrorMessage.DcApiError,
|
|
728
|
+
cause: exception
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
const parseCredentialResponse = credentialResponse => {
|
|
734
|
+
if (!credentialResponse) {
|
|
735
|
+
return neverthrow.err({
|
|
736
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
737
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
738
|
+
details: {
|
|
739
|
+
response: credentialResponse
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
if (typeof credentialResponse === "object") {
|
|
744
|
+
return neverthrow.ok(credentialResponse);
|
|
745
|
+
}
|
|
746
|
+
if (typeof credentialResponse === "string") {
|
|
747
|
+
try {
|
|
748
|
+
const parsed = JSON.parse(credentialResponse);
|
|
749
|
+
return neverthrow.ok(parsed);
|
|
750
|
+
} catch (_a) {
|
|
751
|
+
return neverthrow.err({
|
|
752
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
753
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
754
|
+
details: {
|
|
755
|
+
response: credentialResponse
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
return neverthrow.err({
|
|
761
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
762
|
+
message: RequestCredentialsErrorMessage.DcApiResponseParseError,
|
|
763
|
+
details: {
|
|
764
|
+
response: credentialResponse
|
|
765
|
+
}
|
|
516
766
|
});
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
const verifyCredentialResponse = async options => {
|
|
770
|
+
const {apiBaseUrl: apiBaseUrl, sessionId: sessionId, sessionKey: sessionKey, challenge: challenge, protocol: protocol, data: data} = options;
|
|
771
|
+
const requestBody = {
|
|
772
|
+
protocol: protocol,
|
|
773
|
+
data: data,
|
|
522
774
|
challenge: challenge
|
|
775
|
+
};
|
|
776
|
+
const credentialVerificationResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/${sessionId}/dc-api/response`, {
|
|
777
|
+
method: "POST",
|
|
778
|
+
headers: {
|
|
779
|
+
"Content-Type": "application/json",
|
|
780
|
+
Authorization: `Bearer ${sessionKey}`
|
|
781
|
+
},
|
|
782
|
+
body: JSON.stringify(requestBody)
|
|
523
783
|
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
784
|
+
if (credentialVerificationResult.isErr()) {
|
|
785
|
+
return neverthrow.err(credentialVerificationResult.error);
|
|
786
|
+
}
|
|
787
|
+
const credentialVerificationResponse = await credentialVerificationResult.value.json();
|
|
788
|
+
if (!isType(PresentationResultRelaxValidator)(credentialVerificationResponse)) {
|
|
789
|
+
return neverthrow.err({
|
|
790
|
+
type: SafeFetchCommonResponseErrorType.UnexpectedResponse,
|
|
791
|
+
message: "Verify credential returned unsupported response",
|
|
792
|
+
details: {
|
|
793
|
+
response: credentialVerificationResponse
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
return neverthrow.ok(credentialVerificationResponse);
|
|
528
798
|
};
|
|
529
799
|
|
|
800
|
+
const isDigitalCredentialsApiSupported = () => {
|
|
801
|
+
var _a;
|
|
802
|
+
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";
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
const sleep = ms => new Promise((resolve => setTimeout(resolve, ms)));
|
|
806
|
+
|
|
807
|
+
const SESSION_STATUS_POLLING_MAX_RETRY = 1e3;
|
|
808
|
+
|
|
809
|
+
const SESSION_STATUS_POLLING_INTERVAL_MS = 3e3;
|
|
810
|
+
|
|
811
|
+
const SESSION_STATUS_POLLING_INITIAL_DELAY_MS = 3e3;
|
|
812
|
+
|
|
530
813
|
var SameDeviceRequestCredentialsErrorMessage;
|
|
531
814
|
|
|
532
815
|
(function(SameDeviceRequestCredentialsErrorMessage) {
|
|
@@ -535,65 +818,134 @@ var SameDeviceRequestCredentialsErrorMessage;
|
|
|
535
818
|
})(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
|
|
536
819
|
|
|
537
820
|
const requestCredentialsSameDevice = async options => {
|
|
538
|
-
const {challenge: challenge,
|
|
539
|
-
const
|
|
821
|
+
const {challenge: challenge, apiBaseUrl: apiBaseUrl, applicationId: applicationId, sessionUrl: sessionUrl, sessionKey: sessionKey, sessionId: sessionId} = options;
|
|
822
|
+
const abortController = setActiveSession({
|
|
823
|
+
sessionId: sessionId,
|
|
824
|
+
sessionKey: sessionKey
|
|
825
|
+
});
|
|
826
|
+
window.localStorage.setItem(LocalStorageKey.sessionId, sessionId);
|
|
540
827
|
window.localStorage.setItem(LocalStorageKey.challenge, challenge);
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
828
|
+
window.location.assign(sessionUrl);
|
|
829
|
+
await sleep(SESSION_STATUS_POLLING_INITIAL_DELAY_MS);
|
|
830
|
+
const checkResult = await withRetry((async () => {
|
|
831
|
+
const statusResult = await getSessionStatus({
|
|
832
|
+
apiBaseUrl: apiBaseUrl,
|
|
833
|
+
applicationId: applicationId,
|
|
834
|
+
sessionId: sessionId,
|
|
835
|
+
sessionKey: sessionKey
|
|
546
836
|
});
|
|
837
|
+
if (abortController.signal.aborted) {
|
|
838
|
+
return neverthrow.err({
|
|
839
|
+
type: exports.RequestCredentialsErrorType.Abort,
|
|
840
|
+
message: RequestCredentialsErrorMessage.Abort
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
if (statusResult.isErr()) {
|
|
844
|
+
if (statusResult.error.status === 404) {
|
|
845
|
+
return neverthrow.err({
|
|
846
|
+
type: exports.RequestCredentialsErrorType.Timeout,
|
|
847
|
+
message: RequestCredentialsErrorMessage.Timeout
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
throw Error("Unexpected status response. Retry");
|
|
851
|
+
}
|
|
852
|
+
if (statusResult.value.status !== PresentationStatusCode.ResultReady) {
|
|
853
|
+
throw Error("Result is not ready. Retry");
|
|
854
|
+
}
|
|
855
|
+
return neverthrow.ok(undefined);
|
|
856
|
+
}), {
|
|
857
|
+
retries: SESSION_STATUS_POLLING_MAX_RETRY,
|
|
858
|
+
retryDelay: SESSION_STATUS_POLLING_INTERVAL_MS
|
|
859
|
+
});
|
|
860
|
+
if (checkResult.isErr()) {
|
|
861
|
+
return neverthrow.err(checkResult.error);
|
|
862
|
+
}
|
|
863
|
+
window.close();
|
|
864
|
+
return neverthrow.ok({
|
|
865
|
+
sessionId: sessionId,
|
|
866
|
+
sessionCompletedInRedirect: true
|
|
867
|
+
});
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
const requestCredentials = async options => {
|
|
871
|
+
var _a;
|
|
872
|
+
const initialiseOptions = getInitialiseOptions();
|
|
873
|
+
if (!initialiseOptions) {
|
|
874
|
+
throw new Exception(InitialiseErrorMessage.SdkNotInitialised);
|
|
547
875
|
}
|
|
876
|
+
assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
|
|
877
|
+
const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initialiseOptions;
|
|
878
|
+
const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration} = options;
|
|
879
|
+
const dcApiSupported = isDigitalCredentialsApiSupported();
|
|
880
|
+
const openId4VpRedirectUri = deriveOpenId4vpRedirectUri(openid4vpConfiguration);
|
|
548
881
|
const createSessionResult = await createSession({
|
|
549
882
|
credentialQuery: credentialQuery,
|
|
550
|
-
challenge:
|
|
551
|
-
redirectUri:
|
|
883
|
+
challenge: challenge,
|
|
884
|
+
redirectUri: openId4VpRedirectUri,
|
|
885
|
+
walletProviderId: (_a = openid4vpConfiguration === null || openid4vpConfiguration === void 0 ? void 0 : openid4vpConfiguration.walletProviderId) !== null && _a !== void 0 ? _a : undefined,
|
|
552
886
|
apiBaseUrl: apiBaseUrl,
|
|
553
887
|
applicationId: applicationId,
|
|
554
|
-
|
|
888
|
+
dcApiSupported: dcApiSupported
|
|
555
889
|
});
|
|
556
890
|
if (createSessionResult.isErr()) {
|
|
557
891
|
return neverthrow.err({
|
|
558
892
|
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
559
|
-
message:
|
|
893
|
+
message: RequestCredentialsErrorMessage.FailedToCreateSession,
|
|
560
894
|
cause: createSessionResult.error
|
|
561
895
|
});
|
|
562
896
|
}
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
897
|
+
const session = createSessionResult.value;
|
|
898
|
+
const {sessionKey: sessionKey, sessionId: sessionId} = session;
|
|
899
|
+
if (session.type === SessionType.DigitalCredentialsApi) {
|
|
900
|
+
const {request: request} = session;
|
|
901
|
+
return await requestCredentialsWithDigitalCredentialsApi({
|
|
902
|
+
apiBaseUrl: apiBaseUrl,
|
|
903
|
+
request: request,
|
|
904
|
+
sessionId: sessionId,
|
|
905
|
+
sessionKey: sessionKey,
|
|
906
|
+
challenge: challenge
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
if (!openid4vpConfiguration) {
|
|
910
|
+
return neverthrow.err({
|
|
911
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
912
|
+
message: RequestCredentialsErrorMessage.MissingOpenId4vpConfig
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
const {sessionUrl: sessionUrl} = session;
|
|
916
|
+
if (openId4VpRedirectUri) {
|
|
917
|
+
return await requestCredentialsSameDevice({
|
|
918
|
+
challenge: challenge,
|
|
919
|
+
apiBaseUrl: apiBaseUrl,
|
|
920
|
+
applicationId: applicationId,
|
|
921
|
+
sessionUrl: sessionUrl,
|
|
922
|
+
sessionKey: sessionKey,
|
|
923
|
+
sessionId: sessionId
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
return await requestCredentialsWithCrossDevice({
|
|
927
|
+
challenge: challenge,
|
|
928
|
+
apiBaseUrl: apiBaseUrl,
|
|
929
|
+
sessionUrl: sessionUrl,
|
|
930
|
+
sessionKey: sessionKey,
|
|
567
931
|
sessionId: sessionId
|
|
568
932
|
});
|
|
569
933
|
};
|
|
570
934
|
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (!initialiseOptions) {
|
|
575
|
-
throw new Exception(InitialiseErrorMessage.SdkNotInitialised);
|
|
935
|
+
const deriveOpenId4vpRedirectUri = openid4vpConfiguration => {
|
|
936
|
+
if (!openid4vpConfiguration) {
|
|
937
|
+
return undefined;
|
|
576
938
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
initialiseOptions: initialiseOptions,
|
|
583
|
-
challenge: challenge,
|
|
584
|
-
mode: mode
|
|
585
|
-
}));
|
|
939
|
+
let detectedMode;
|
|
940
|
+
if (openid4vpConfiguration && openid4vpConfiguration.mode) {
|
|
941
|
+
detectedMode = openid4vpConfiguration.mode;
|
|
942
|
+
} else {
|
|
943
|
+
detectedMode = isMobileDetect(navigator.userAgent) ? exports.Mode.SameDevice : exports.Mode.CrossDevice;
|
|
586
944
|
}
|
|
587
|
-
if (
|
|
588
|
-
return
|
|
589
|
-
initialiseOptions: initialiseOptions,
|
|
590
|
-
challenge: challenge,
|
|
591
|
-
mode: mode
|
|
592
|
-
}));
|
|
945
|
+
if (detectedMode === exports.Mode.SameDevice && !isType(OpenId4vpConfigCrossDeviceOptionsValidator)(openid4vpConfiguration) && openid4vpConfiguration.redirectUri) {
|
|
946
|
+
return openid4vpConfiguration.redirectUri;
|
|
593
947
|
}
|
|
594
|
-
|
|
595
|
-
data: options
|
|
596
|
-
});
|
|
948
|
+
return undefined;
|
|
597
949
|
};
|
|
598
950
|
|
|
599
951
|
exports.HandleRedirectCallbackErrorType = void 0;
|
|
@@ -607,7 +959,7 @@ var HandleRedirectCallbackErrorMessage;
|
|
|
607
959
|
(function(HandleRedirectCallbackErrorMessage) {
|
|
608
960
|
HandleRedirectCallbackErrorMessage["FailedToFindResponseCode"] = "Failed to find response code";
|
|
609
961
|
HandleRedirectCallbackErrorMessage["FailedToFindChallenge"] = "Failed to find challenge";
|
|
610
|
-
HandleRedirectCallbackErrorMessage["
|
|
962
|
+
HandleRedirectCallbackErrorMessage["FailedToFindActiveSession"] = "Failed to find active session";
|
|
611
963
|
HandleRedirectCallbackErrorMessage["FailedToGetSessionResult"] = "Failed to get session result";
|
|
612
964
|
})(HandleRedirectCallbackErrorMessage || (HandleRedirectCallbackErrorMessage = {}));
|
|
613
965
|
|
|
@@ -624,18 +976,12 @@ const handleRedirectCallback = async () => {
|
|
|
624
976
|
message: HandleRedirectCallbackErrorMessage.FailedToFindResponseCode
|
|
625
977
|
});
|
|
626
978
|
}
|
|
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
979
|
const sessionId = window.localStorage.getItem(LocalStorageKey.sessionId);
|
|
635
|
-
|
|
980
|
+
const challenge = window.localStorage.getItem(LocalStorageKey.challenge);
|
|
981
|
+
if (!sessionId || !challenge) {
|
|
636
982
|
return neverthrow.err({
|
|
637
983
|
type: exports.HandleRedirectCallbackErrorType.HandleRedirectCallbackFailed,
|
|
638
|
-
message: HandleRedirectCallbackErrorMessage.
|
|
984
|
+
message: HandleRedirectCallbackErrorMessage.FailedToFindActiveSession
|
|
639
985
|
});
|
|
640
986
|
}
|
|
641
987
|
const result = await exchangeSessionResult({
|
|
@@ -652,20 +998,52 @@ const handleRedirectCallback = async () => {
|
|
|
652
998
|
});
|
|
653
999
|
}
|
|
654
1000
|
return neverthrow.ok({
|
|
655
|
-
result: result.value,
|
|
1001
|
+
result: "challenge" in result.value ? result.value : undefined,
|
|
656
1002
|
sessionId: result.value.sessionId
|
|
657
1003
|
});
|
|
658
1004
|
};
|
|
659
1005
|
|
|
1006
|
+
const abortCredentialRequest = async () => {
|
|
1007
|
+
const initialiseOptions = getInitialiseOptions();
|
|
1008
|
+
if (!initialiseOptions) {
|
|
1009
|
+
throw new Exception(InitialiseErrorMessage.SdkNotInitialised);
|
|
1010
|
+
}
|
|
1011
|
+
const {apiBaseUrl: apiBaseUrl} = initialiseOptions;
|
|
1012
|
+
const session = getActiveSession();
|
|
1013
|
+
if (!session || !session.sessionKey) {
|
|
1014
|
+
return neverthrow.ok(undefined);
|
|
1015
|
+
}
|
|
1016
|
+
const {sessionId: sessionId, sessionKey: sessionKey} = session;
|
|
1017
|
+
removeActiveSession();
|
|
1018
|
+
const abortSessionResult = await abortSession({
|
|
1019
|
+
apiBaseUrl: apiBaseUrl,
|
|
1020
|
+
sessionId: sessionId,
|
|
1021
|
+
sessionKey: sessionKey
|
|
1022
|
+
});
|
|
1023
|
+
if (abortSessionResult.isErr()) {
|
|
1024
|
+
return neverthrow.err({
|
|
1025
|
+
type: exports.AbortSessionErrorType.AbortSessionFailed,
|
|
1026
|
+
message: AbortSessionErrorMessage.FailedToAbortSession,
|
|
1027
|
+
cause: abortSessionResult.error
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
return neverthrow.ok(undefined);
|
|
1031
|
+
};
|
|
1032
|
+
|
|
660
1033
|
const utils = {
|
|
661
1034
|
generateChallenge: generateChallenge,
|
|
1035
|
+
getVersion: getVersion,
|
|
662
1036
|
unwrap: unwrap
|
|
663
1037
|
};
|
|
664
1038
|
|
|
1039
|
+
exports.abortCredentialRequest = abortCredentialRequest;
|
|
1040
|
+
|
|
665
1041
|
exports.handleRedirectCallback = handleRedirectCallback;
|
|
666
1042
|
|
|
667
1043
|
exports.initialise = initialise;
|
|
668
1044
|
|
|
1045
|
+
exports.isDigitalCredentialsApiSupported = isDigitalCredentialsApiSupported;
|
|
1046
|
+
|
|
669
1047
|
exports.requestCredentials = requestCredentials;
|
|
670
1048
|
|
|
671
1049
|
exports.utils = utils;
|