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