@pagopa/io-react-native-wallet 0.13.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. package/lib/commonjs/cie/component.js +180 -0
  2. package/lib/commonjs/cie/component.js.map +1 -0
  3. package/lib/commonjs/cie/error.js +44 -0
  4. package/lib/commonjs/cie/error.js.map +1 -0
  5. package/lib/commonjs/cie/index.js +32 -0
  6. package/lib/commonjs/cie/index.js.map +1 -0
  7. package/lib/commonjs/cie/manager.js +142 -0
  8. package/lib/commonjs/cie/manager.js.map +1 -0
  9. package/lib/commonjs/client/index.js +5 -2
  10. package/lib/commonjs/client/index.js.map +1 -1
  11. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js +144 -19
  12. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js.map +1 -1
  13. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +12 -4
  14. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  15. package/lib/commonjs/credential/issuance/index.js +18 -0
  16. package/lib/commonjs/credential/issuance/index.js.map +1 -1
  17. package/lib/commonjs/credential/issuance/types.js +9 -1
  18. package/lib/commonjs/credential/issuance/types.js.map +1 -1
  19. package/lib/commonjs/index.js +3 -1
  20. package/lib/commonjs/index.js.map +1 -1
  21. package/lib/commonjs/trust/types.js +5 -3
  22. package/lib/commonjs/trust/types.js.map +1 -1
  23. package/lib/commonjs/utils/decoder.js +28 -19
  24. package/lib/commonjs/utils/decoder.js.map +1 -1
  25. package/lib/module/cie/component.js +171 -0
  26. package/lib/module/cie/component.js.map +1 -0
  27. package/lib/module/cie/error.js +36 -0
  28. package/lib/module/cie/error.js.map +1 -0
  29. package/lib/module/cie/index.js +4 -0
  30. package/lib/module/cie/index.js.map +1 -0
  31. package/lib/module/cie/manager.js +133 -0
  32. package/lib/module/cie/manager.js.map +1 -0
  33. package/lib/module/client/index.js +5 -2
  34. package/lib/module/client/index.js.map +1 -1
  35. package/lib/module/credential/issuance/04-complete-user-authorization.js +141 -18
  36. package/lib/module/credential/issuance/04-complete-user-authorization.js.map +1 -1
  37. package/lib/module/credential/issuance/07-verify-and-parse-credential.js +12 -4
  38. package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  39. package/lib/module/credential/issuance/index.js +2 -2
  40. package/lib/module/credential/issuance/index.js.map +1 -1
  41. package/lib/module/credential/issuance/types.js +7 -0
  42. package/lib/module/credential/issuance/types.js.map +1 -1
  43. package/lib/module/index.js +2 -1
  44. package/lib/module/index.js.map +1 -1
  45. package/lib/module/trust/types.js +5 -3
  46. package/lib/module/trust/types.js.map +1 -1
  47. package/lib/module/utils/decoder.js +28 -19
  48. package/lib/module/utils/decoder.js.map +1 -1
  49. package/lib/typescript/cie/component.d.ts +46 -0
  50. package/lib/typescript/cie/component.d.ts.map +1 -0
  51. package/lib/typescript/cie/error.d.ts +31 -0
  52. package/lib/typescript/cie/error.d.ts.map +1 -0
  53. package/lib/typescript/cie/index.d.ts +4 -0
  54. package/lib/typescript/cie/index.d.ts.map +1 -0
  55. package/lib/typescript/cie/manager.d.ts +5 -0
  56. package/lib/typescript/cie/manager.d.ts.map +1 -0
  57. package/lib/typescript/client/index.d.ts.map +1 -1
  58. package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts +48 -1
  59. package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts.map +1 -1
  60. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts +1 -0
  61. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
  62. package/lib/typescript/credential/issuance/index.d.ts +3 -3
  63. package/lib/typescript/credential/issuance/index.d.ts.map +1 -1
  64. package/lib/typescript/credential/issuance/types.d.ts +10 -0
  65. package/lib/typescript/credential/issuance/types.d.ts.map +1 -1
  66. package/lib/typescript/index.d.ts +2 -1
  67. package/lib/typescript/index.d.ts.map +1 -1
  68. package/lib/typescript/trust/index.d.ts +14 -14
  69. package/lib/typescript/trust/types.d.ts +142 -142
  70. package/lib/typescript/trust/types.d.ts.map +1 -1
  71. package/lib/typescript/utils/decoder.d.ts.map +1 -1
  72. package/package.json +6 -2
  73. package/src/cie/component.tsx +216 -0
  74. package/src/cie/error.ts +58 -0
  75. package/src/cie/index.ts +4 -0
  76. package/src/cie/manager.ts +183 -0
  77. package/src/client/index.ts +4 -1
  78. package/src/credential/issuance/04-complete-user-authorization.ts +216 -21
  79. package/src/credential/issuance/07-verify-and-parse-credential.ts +14 -6
  80. package/src/credential/issuance/index.ts +10 -0
  81. package/src/credential/issuance/types.ts +7 -0
  82. package/src/index.ts +2 -0
  83. package/src/trust/types.ts +8 -6
  84. package/src/utils/decoder.ts +28 -19
  85. package/lib/commonjs/credential/issuance/03-start-credential-issuance.js +0 -287
  86. package/lib/commonjs/credential/issuance/03-start-credential-issuance.js.map +0 -1
  87. package/lib/module/credential/issuance/03-start-credential-issuance.js +0 -276
  88. package/lib/module/credential/issuance/03-start-credential-issuance.js.map +0 -1
  89. package/lib/typescript/credential/issuance/03-start-credential-issuance.d.ts +0 -41
  90. package/lib/typescript/credential/issuance/03-start-credential-issuance.d.ts.map +0 -1
  91. package/src/credential/issuance/03-start-credential-issuance.ts +0 -407
@@ -1,41 +0,0 @@
1
- import { type CryptoContext } from "@pagopa/io-react-native-jwt";
2
- import { type Out } from "../../utils/misc";
3
- import type { StartFlow } from "./01-start-flow";
4
- import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
5
- import { type AuthorizationContext, type AuthorizationResult } from "../../utils/auth";
6
- import { CredentialResponse } from "./types";
7
- export type StartCredentialIssuance = (issuerConf: Out<EvaluateIssuerTrust>["issuerConf"], credentialType: Out<StartFlow>["credentialType"], context: {
8
- wiaCryptoContext: CryptoContext;
9
- credentialCryptoContext: CryptoContext;
10
- authorizationContext?: AuthorizationContext;
11
- walletInstanceAttestation: string;
12
- redirectUri: string;
13
- idphint: string;
14
- appFetch?: GlobalFetch["fetch"];
15
- }) => Promise<CredentialResponse>;
16
- /**
17
- * Starts the credential issuance flow to obtain a credential from the issuer.
18
- * @param issuerConf The Issuer configuration
19
- * @param credentialType The type of the credential to be requested
20
- * @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
21
- * @param context.credentialCryptoContext The context to access the key to associat with credential
22
- * @param context.walletInstanceAttestation The Wallet Instance Attestation token
23
- * @param context.authorizationContext The context to identify the user which will be used to start the authorization. It's needed only when requesting a PersonalIdentificationData credential. The implementantion should open an in-app browser capable of catching the redirectSchema. If not specified, the default browser is used.
24
- * @param context.redirectUri The internal URL to which to redirect has passed the in-app browser login phase. If you don't use authorizationContext remember to register this URL as customUrl or deepLink. See https://reactnative.dev/docs/linking
25
- * @param context.idphint Unique identifier of the SPID IDP
26
- * @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
27
- * @throws {AuthorizationError} When the response from the authorization response is not parsable
28
- * @returns The credential obtained
29
- */
30
- export declare const startCredentialIssuance: StartCredentialIssuance;
31
- /**
32
- * Authorizes the user using the query mode and the authorization context.
33
- * @param authzRequestEndpoint The authorization endpoint of the authorization server
34
- * @param params The query parameters to be used in the request
35
- * @param redirectUri The URL to which the redirect is made is usually a custom URL or deeplink
36
- * @param authorizationContext The AuthorizationContext to manage the internal webview. If not specified, the default browser is used
37
- * @returns The authrozation result containing the authorization code, state and issuer
38
- */
39
- export declare const authorizeUserWithQueryMode: (authzRequestEndpoint: string, params: URLSearchParams, redirectUri: string, authorizationContext?: AuthorizationContext) => Promise<AuthorizationResult>;
40
- export declare const createNonceProof: (nonce: string, issuer: string, audience: string, ctx: CryptoContext) => Promise<string>;
41
- //# sourceMappingURL=03-start-credential-issuance.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"03-start-credential-issuance.d.ts","sourceRoot":"","sources":["../../../../src/credential/issuance/03-start-credential-issuance.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAIL,KAAK,GAAG,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAQtE,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,kBAAkB,EAAoC,MAAM,SAAS,CAAC;AAuD/E,MAAM,MAAM,uBAAuB,GAAG,CACpC,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAClD,cAAc,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,EAChD,OAAO,EAAE;IACP,gBAAgB,EAAE,aAAa,CAAC;IAChC,uBAAuB,EAAE,aAAa,CAAC;IACvC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,yBAAyB,EAAE,MAAM,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CACjC,KACE,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,uBAAuB,EAAE,uBAgNrC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,yBACf,MAAM,UACpB,eAAe,eACV,MAAM,yBACI,oBAAoB,KAC1C,QAAQ,mBAAmB,CAkD7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,UACpB,MAAM,UACL,MAAM,YACJ,MAAM,OACX,aAAa,KACjB,QAAQ,MAAM,CAehB,CAAC"}
@@ -1,407 +0,0 @@
1
- import uuid from "react-native-uuid";
2
- import { AuthorizationDetail, makeParRequest } from "../../utils/par";
3
- import { SignJWT, type CryptoContext } from "@pagopa/io-react-native-jwt";
4
- import {
5
- generateRandomAlphaNumericString,
6
- hasStatus,
7
- until,
8
- type Out,
9
- } from "../../utils/misc";
10
- import type { StartFlow } from "./01-start-flow";
11
- import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
12
- import { ASSERTION_TYPE } from "./const";
13
- import parseUrl from "parse-url";
14
- import {
15
- AuthorizationError,
16
- AuthorizationIdpError,
17
- ValidationFailed,
18
- } from "../../utils/errors";
19
- import {
20
- AuthorizationErrorShape,
21
- AuthorizationResultShape,
22
- type AuthorizationContext,
23
- type AuthorizationResult,
24
- } from "../../utils/auth";
25
- import { withEphemeralKey } from "../../utils/crypto";
26
- import { createDPopToken } from "../../utils/dpop";
27
- import { createPopToken } from "../../utils/pop";
28
- import { CredentialResponse, TokenResponse, type ResponseMode } from "./types";
29
- import * as WalletInstanceAttestation from "../../wallet-instance-attestation";
30
- import { Linking } from "react-native";
31
-
32
- /**
33
- * Ensures that the credential type requested is supported by the issuer and contained in the
34
- * issuer configuration.
35
- * @param issuerConf The issuer configuration
36
- * @param credentialType The type of the credential to be requested
37
- * @returns The credential definition to be used in the request which includes the format and the type and its type
38
- */
39
- const selectCredentialDefinition = (
40
- issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
41
- credentialType: Out<StartFlow>["credentialType"]
42
- ): AuthorizationDetail => {
43
- const credential_configurations_supported =
44
- issuerConf.openid_credential_issuer.credential_configurations_supported;
45
-
46
- const [result] = Object.keys(credential_configurations_supported)
47
- .filter((e) => e.includes(credentialType))
48
- .map((e) => ({
49
- credential_configuration_id: credentialType,
50
- format: credential_configurations_supported[e]!.format,
51
- type: "openid_credential" as const,
52
- }));
53
-
54
- if (!result) {
55
- throw new Error(`No credential support the type '${credentialType}'`);
56
- }
57
- return result;
58
- };
59
-
60
- /**
61
- * Ensures that the response mode requested is supported by the issuer and contained in the issuer configuration.
62
- * @param issuerConf The issuer configuration
63
- * @param credentialType The type of the credential to be requested
64
- * @returns The response mode to be used in the request, "query" for PersonIdentificationData and "form_post.jwt" for all other types.
65
- */
66
- const selectResponseMode = (
67
- issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
68
- credentialType: Out<StartFlow>["credentialType"]
69
- ): ResponseMode => {
70
- const responseModeSupported =
71
- issuerConf.oauth_authorization_server.response_modes_supported;
72
-
73
- const responseMode =
74
- credentialType === "PersonIdentificationData" ? "query" : "form_post.jwt";
75
-
76
- if (!responseModeSupported.includes(responseMode)) {
77
- throw new Error(`No response mode support the type '${credentialType}'`);
78
- }
79
-
80
- return responseMode;
81
- };
82
-
83
- export type StartCredentialIssuance = (
84
- issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
85
- credentialType: Out<StartFlow>["credentialType"],
86
- context: {
87
- wiaCryptoContext: CryptoContext;
88
- credentialCryptoContext: CryptoContext;
89
- authorizationContext?: AuthorizationContext;
90
- walletInstanceAttestation: string;
91
- redirectUri: string;
92
- idphint: string;
93
- appFetch?: GlobalFetch["fetch"];
94
- }
95
- ) => Promise<CredentialResponse>;
96
-
97
- /**
98
- * Starts the credential issuance flow to obtain a credential from the issuer.
99
- * @param issuerConf The Issuer configuration
100
- * @param credentialType The type of the credential to be requested
101
- * @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
102
- * @param context.credentialCryptoContext The context to access the key to associat with credential
103
- * @param context.walletInstanceAttestation The Wallet Instance Attestation token
104
- * @param context.authorizationContext The context to identify the user which will be used to start the authorization. It's needed only when requesting a PersonalIdentificationData credential. The implementantion should open an in-app browser capable of catching the redirectSchema. If not specified, the default browser is used.
105
- * @param context.redirectUri The internal URL to which to redirect has passed the in-app browser login phase. If you don't use authorizationContext remember to register this URL as customUrl or deepLink. See https://reactnative.dev/docs/linking
106
- * @param context.idphint Unique identifier of the SPID IDP
107
- * @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
108
- * @throws {AuthorizationError} When the response from the authorization response is not parsable
109
- * @returns The credential obtained
110
- */
111
-
112
- export const startCredentialIssuance: StartCredentialIssuance = async (
113
- issuerConf,
114
- credentialType,
115
- ctx
116
- ) => {
117
- const {
118
- wiaCryptoContext,
119
- credentialCryptoContext,
120
- walletInstanceAttestation,
121
- authorizationContext,
122
- redirectUri,
123
- idphint,
124
- appFetch = fetch,
125
- } = ctx;
126
-
127
- /**
128
- * Creates and sends a PAR request to the /as/par endpoint of the authroization server.
129
- * This starts the authentication flow to obtain an access token.
130
- * This token enables the Wallet Instance to request a digital credential from the Credential Endpoint of the Credential Issuer.
131
- * This is an HTTP POST request containing the Wallet Instance identifier (client id), the code challenge and challenge method as specified by PKCE according to RFC 9126
132
- * along with the WTE and its proof of possession (WTE-PoP).
133
- * Additionally, it includes a request object, which is a signed JWT encapsulating the type of digital credential requested (authorization_details),
134
- * the application session identifier on the Wallet Instance side (state),
135
- * the method (query or form_post.jwt) by which the Authorization Server
136
- * should transmit the Authorization Response containing the authorization code issued upon the end user's authentication (response_mode)
137
- * to the Wallet Instance's Token Endpoint to obtain the Access Token, and the redirect_uri of the Wallet Instance where the Authorization Response
138
- * should be delivered. The redirect is achived by using a custom URL scheme that the Wallet Instance is registered to handle.
139
- */
140
- const clientId = await wiaCryptoContext.getPublicKey().then((_) => _.kid);
141
- const codeVerifier = generateRandomAlphaNumericString(64);
142
- const parEndpoint =
143
- issuerConf.oauth_authorization_server.pushed_authorization_request_endpoint;
144
- const parUrl = new URL(parEndpoint);
145
- const aud = `${parUrl.protocol}//${parUrl.hostname}`;
146
- const iss = WalletInstanceAttestation.decode(walletInstanceAttestation)
147
- .payload.cnf.jwk.kid;
148
- const credentialDefinition = selectCredentialDefinition(
149
- issuerConf,
150
- credentialType
151
- );
152
- const responseMode = selectResponseMode(issuerConf, credentialType);
153
-
154
- const getPar = makeParRequest({ wiaCryptoContext, appFetch });
155
- const issuerRequestUri = await getPar(
156
- clientId,
157
- codeVerifier,
158
- redirectUri,
159
- responseMode,
160
- parEndpoint,
161
- walletInstanceAttestation,
162
- [credentialDefinition],
163
- ASSERTION_TYPE
164
- );
165
-
166
- /**
167
- * Starts the authorization flow which dependes on the response mode and the request credential.
168
- * If the response mode is "query" the authorization flow is handled differently via the authorization context which opens an in-app browser capable of catching the redirectSchema.
169
- * The form_post.jwt mode is not currently supported.
170
- */
171
- const authorizeFlowResult = await (async () => {
172
- const authzRequestEndpoint =
173
- issuerConf.oauth_authorization_server.authorization_endpoint;
174
- if (responseMode === "query") {
175
- const params = new URLSearchParams({
176
- client_id: clientId,
177
- request_uri: issuerRequestUri,
178
- idphint,
179
- });
180
-
181
- /**
182
- * Starts the authorization flow to obtain an authorization code by performing a GET request to the /authorize endpoint of the authorization server.
183
- */
184
- return await authorizeUserWithQueryMode(
185
- authzRequestEndpoint,
186
- params,
187
- redirectUri,
188
- authorizationContext
189
- );
190
- } else {
191
- throw new AuthorizationError(
192
- "Response mode not supported for this type of credential"
193
- );
194
- }
195
- })();
196
-
197
- /**
198
- * Creates and sends the DPoP Proof JWT to be presented with the authorization code to the /token endpoint of the authorization server
199
- * for requesting the issuance of an access token bound to the public key of the Wallet Instance contained within the DPoP.
200
- * This enables the Wallet Instance to request a digital credential.
201
- * The DPoP Proof JWT is generated according to the section 4.3 of the DPoP RFC 9449 specification.
202
- */
203
-
204
- const { code } = authorizeFlowResult;
205
- const tokenUrl = issuerConf.oauth_authorization_server.token_endpoint;
206
- // Use an ephemeral key to be destroyed after use
207
- const tokenRequestSignedDPop = await withEphemeralKey(
208
- async (ephimeralContext) => {
209
- return await createDPopToken(
210
- {
211
- htm: "POST",
212
- htu: tokenUrl,
213
- jti: `${uuid.v4()}`,
214
- },
215
- ephimeralContext
216
- );
217
- }
218
- );
219
-
220
- const signedWiaPoP = await createPopToken(
221
- {
222
- jti: `${uuid.v4()}`,
223
- aud,
224
- iss,
225
- },
226
- wiaCryptoContext
227
- );
228
-
229
- const requestBody = {
230
- grant_type: "authorization_code",
231
- client_id: clientId,
232
- code,
233
- redirect_uri: redirectUri,
234
- code_verifier: codeVerifier,
235
- client_assertion_type: ASSERTION_TYPE,
236
- client_assertion: walletInstanceAttestation + "~" + signedWiaPoP,
237
- };
238
-
239
- const authorizationRequestFormBody = new URLSearchParams(requestBody);
240
- const tokenRes = await appFetch(tokenUrl, {
241
- method: "POST",
242
- headers: {
243
- "Content-Type": "application/x-www-form-urlencoded",
244
- DPoP: tokenRequestSignedDPop,
245
- },
246
- body: authorizationRequestFormBody.toString(),
247
- })
248
- .then(hasStatus(200))
249
- .then((res) => res.json())
250
- .then((body) => TokenResponse.safeParse(body));
251
-
252
- if (!tokenRes.success) {
253
- throw new ValidationFailed(tokenRes.error.message);
254
- }
255
-
256
- /**
257
- * Validates the token response and extracts the access token, c_nonce and c_nonce_expires_in.
258
- */
259
- const accessTokenResponse = tokenRes.data;
260
- const credentialUrl = issuerConf.openid_credential_issuer.credential_endpoint;
261
-
262
- /**
263
- * JWT proof token to bind the request nonce to the key that will bind the holder User with the Credential
264
- * This is presented along with the access token to the Credential Endpoint as proof of possession of the private key used to sign the Access Token.
265
- * @see https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-proof-types
266
- */
267
- const signedNonceProof = await createNonceProof(
268
- accessTokenResponse.c_nonce,
269
- clientId,
270
- credentialUrl,
271
- credentialCryptoContext
272
- );
273
-
274
- // Validation of accessTokenResponse.authorization_details if contain credentialDefinition
275
- const constainsCredentialDefinition =
276
- accessTokenResponse.authorization_details.some(
277
- (c) =>
278
- c.credential_configuration_id ===
279
- credentialDefinition.credential_configuration_id &&
280
- c.format === credentialDefinition.format &&
281
- c.type === credentialDefinition.type
282
- );
283
-
284
- if (!constainsCredentialDefinition) {
285
- throw new ValidationFailed(
286
- "The access token response does not contain the requested credential"
287
- );
288
- }
289
-
290
- /** The credential request body */
291
- const credentialRequestFormBody = {
292
- credential_definition: {
293
- type: [credentialDefinition.credential_configuration_id],
294
- },
295
- format: credentialDefinition.format,
296
- proof: {
297
- jwt: signedNonceProof,
298
- proof_type: "jwt",
299
- },
300
- };
301
-
302
- const credentialRes = await appFetch(credentialUrl, {
303
- method: "POST",
304
- headers: {
305
- "Content-Type": "application/json",
306
- DPoP: tokenRequestSignedDPop,
307
- Authorization: `${accessTokenResponse.token_type} ${accessTokenResponse.access_token}`,
308
- },
309
- body: JSON.stringify(credentialRequestFormBody),
310
- })
311
- .then(hasStatus(200))
312
- .then((res) => res.json())
313
- .then((body) => CredentialResponse.safeParse(body));
314
-
315
- if (!credentialRes.success) {
316
- throw new ValidationFailed(credentialRes.error.message);
317
- }
318
-
319
- return credentialRes.data;
320
- };
321
-
322
- /**
323
- * Authorizes the user using the query mode and the authorization context.
324
- * @param authzRequestEndpoint The authorization endpoint of the authorization server
325
- * @param params The query parameters to be used in the request
326
- * @param redirectUri The URL to which the redirect is made is usually a custom URL or deeplink
327
- * @param authorizationContext The AuthorizationContext to manage the internal webview. If not specified, the default browser is used
328
- * @returns The authrozation result containing the authorization code, state and issuer
329
- */
330
- export const authorizeUserWithQueryMode = async (
331
- authzRequestEndpoint: string,
332
- params: URLSearchParams,
333
- redirectUri: string,
334
- authorizationContext?: AuthorizationContext
335
- ): Promise<AuthorizationResult> => {
336
- const authUrl = `${authzRequestEndpoint}?${params}`;
337
- var authRedirectUrl: string | undefined;
338
-
339
- if (authorizationContext) {
340
- const redirectSchema = new URL(redirectUri).protocol.replace(":", "");
341
- authRedirectUrl = await authorizationContext
342
- .authorize(authUrl, redirectSchema)
343
- .catch((e) => {
344
- throw new AuthorizationError(e.message);
345
- });
346
- } else {
347
- // handler for redirectUri
348
- Linking.addEventListener("url", ({ url }) => {
349
- if (url.includes(redirectUri)) {
350
- authRedirectUrl = url;
351
- }
352
- });
353
-
354
- const openAuthUrlInBrowser = Linking.openURL(authUrl);
355
-
356
- /*
357
- * Waits for 120 seconds for the identificationRedirectUrl variable to be set
358
- * by the custom url handler. If the timeout is exceeded, throw an exception
359
- */
360
- const unitAuthRedirectIsNotUndefined = until(
361
- () => authRedirectUrl !== undefined,
362
- 120
363
- );
364
-
365
- await Promise.all([openAuthUrlInBrowser, unitAuthRedirectIsNotUndefined]);
366
-
367
- if (authRedirectUrl === undefined) {
368
- throw new AuthorizationError("Invalid authentication redirect url");
369
- }
370
- }
371
-
372
- const urlParse = parseUrl(authRedirectUrl);
373
- const authRes = AuthorizationResultShape.safeParse(urlParse.query);
374
- if (!authRes.success) {
375
- const authErr = AuthorizationErrorShape.safeParse(urlParse.query);
376
- if (!authErr.success) {
377
- throw new AuthorizationError(authRes.error.message); // an error occured while parsing the result and the error
378
- }
379
- throw new AuthorizationIdpError(
380
- authErr.data.error,
381
- authErr.data.error_description
382
- );
383
- }
384
- return authRes.data;
385
- };
386
-
387
- export const createNonceProof = async (
388
- nonce: string,
389
- issuer: string,
390
- audience: string,
391
- ctx: CryptoContext
392
- ): Promise<string> => {
393
- const jwk = await ctx.getPublicKey();
394
- return new SignJWT(ctx)
395
- .setPayload({
396
- nonce,
397
- })
398
- .setProtectedHeader({
399
- typ: "openid4vci-proof+jwt",
400
- jwk,
401
- })
402
- .setAudience(audience)
403
- .setIssuer(issuer)
404
- .setIssuedAt()
405
- .setExpirationTime("5min")
406
- .sign();
407
- };