@pagopa/io-react-native-wallet 0.27.0 → 0.28.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.
Files changed (90) hide show
  1. package/lib/commonjs/client/generated/wallet-provider.js +27 -19
  2. package/lib/commonjs/client/generated/wallet-provider.js.map +1 -1
  3. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js +5 -5
  4. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js.map +1 -1
  5. package/lib/commonjs/credential/issuance/05-authorize-access.js +3 -4
  6. package/lib/commonjs/credential/issuance/05-authorize-access.js.map +1 -1
  7. package/lib/commonjs/credential/issuance/06-obtain-credential.js +2 -3
  8. package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
  9. package/lib/commonjs/credential/issuance/README.md +2 -2
  10. package/lib/commonjs/credential/presentation/03-get-request-object.js +2 -3
  11. package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
  12. package/lib/commonjs/credential/presentation/04-send-authorization-response.js +4 -5
  13. package/lib/commonjs/credential/presentation/04-send-authorization-response.js.map +1 -1
  14. package/lib/commonjs/credential/status/02-status-attestation.js +2 -3
  15. package/lib/commonjs/credential/status/02-status-attestation.js.map +1 -1
  16. package/lib/commonjs/trust/chain.js +35 -50
  17. package/lib/commonjs/trust/chain.js.map +1 -1
  18. package/lib/commonjs/trust/index.js +139 -16
  19. package/lib/commonjs/trust/index.js.map +1 -1
  20. package/lib/commonjs/trust/types.js +13 -37
  21. package/lib/commonjs/trust/types.js.map +1 -1
  22. package/lib/commonjs/trust/utils.js +36 -0
  23. package/lib/commonjs/trust/utils.js.map +1 -0
  24. package/lib/commonjs/utils/crypto.js +2 -3
  25. package/lib/commonjs/utils/crypto.js.map +1 -1
  26. package/lib/commonjs/utils/par.js +3 -4
  27. package/lib/commonjs/utils/par.js.map +1 -1
  28. package/lib/commonjs/wallet-instance/index.js +10 -0
  29. package/lib/commonjs/wallet-instance/index.js.map +1 -1
  30. package/lib/module/client/generated/wallet-provider.js +22 -15
  31. package/lib/module/client/generated/wallet-provider.js.map +1 -1
  32. package/lib/module/credential/issuance/04-complete-user-authorization.js +5 -5
  33. package/lib/module/credential/issuance/04-complete-user-authorization.js.map +1 -1
  34. package/lib/module/credential/issuance/05-authorize-access.js +3 -3
  35. package/lib/module/credential/issuance/05-authorize-access.js.map +1 -1
  36. package/lib/module/credential/issuance/06-obtain-credential.js +2 -2
  37. package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
  38. package/lib/module/credential/issuance/README.md +2 -2
  39. package/lib/module/credential/presentation/03-get-request-object.js +2 -2
  40. package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
  41. package/lib/module/credential/presentation/04-send-authorization-response.js +4 -4
  42. package/lib/module/credential/presentation/04-send-authorization-response.js.map +1 -1
  43. package/lib/module/credential/status/02-status-attestation.js +2 -2
  44. package/lib/module/credential/status/02-status-attestation.js.map +1 -1
  45. package/lib/module/trust/chain.js +32 -46
  46. package/lib/module/trust/chain.js.map +1 -1
  47. package/lib/module/trust/index.js +139 -18
  48. package/lib/module/trust/index.js.map +1 -1
  49. package/lib/module/trust/types.js +11 -36
  50. package/lib/module/trust/types.js.map +1 -1
  51. package/lib/module/trust/utils.js +28 -0
  52. package/lib/module/trust/utils.js.map +1 -0
  53. package/lib/module/utils/crypto.js +2 -2
  54. package/lib/module/utils/crypto.js.map +1 -1
  55. package/lib/module/utils/par.js +3 -3
  56. package/lib/module/utils/par.js.map +1 -1
  57. package/lib/module/wallet-instance/index.js +9 -0
  58. package/lib/module/wallet-instance/index.js.map +1 -1
  59. package/lib/typescript/client/generated/wallet-provider.d.ts +91 -54
  60. package/lib/typescript/client/generated/wallet-provider.d.ts.map +1 -1
  61. package/lib/typescript/credential/status/types.d.ts +6 -6
  62. package/lib/typescript/sd-jwt/index.d.ts +12 -12
  63. package/lib/typescript/sd-jwt/types.d.ts +6 -6
  64. package/lib/typescript/trust/chain.d.ts +4 -9
  65. package/lib/typescript/trust/chain.d.ts.map +1 -1
  66. package/lib/typescript/trust/index.d.ts +109 -95
  67. package/lib/typescript/trust/index.d.ts.map +1 -1
  68. package/lib/typescript/trust/types.d.ts +845 -542
  69. package/lib/typescript/trust/types.d.ts.map +1 -1
  70. package/lib/typescript/trust/utils.d.ts +12 -0
  71. package/lib/typescript/trust/utils.d.ts.map +1 -0
  72. package/lib/typescript/wallet-instance/index.d.ts +8 -0
  73. package/lib/typescript/wallet-instance/index.d.ts.map +1 -1
  74. package/lib/typescript/wallet-instance-attestation/types.d.ts +24 -24
  75. package/package.json +9 -3
  76. package/src/client/generated/wallet-provider.ts +28 -19
  77. package/src/credential/issuance/04-complete-user-authorization.ts +5 -5
  78. package/src/credential/issuance/05-authorize-access.ts +3 -3
  79. package/src/credential/issuance/06-obtain-credential.ts +2 -2
  80. package/src/credential/issuance/README.md +2 -2
  81. package/src/credential/presentation/03-get-request-object.ts +2 -2
  82. package/src/credential/presentation/04-send-authorization-response.ts +4 -4
  83. package/src/credential/status/02-status-attestation.ts +2 -2
  84. package/src/trust/chain.ts +46 -62
  85. package/src/trust/index.ts +185 -20
  86. package/src/trust/types.ts +10 -27
  87. package/src/trust/utils.ts +32 -0
  88. package/src/utils/crypto.ts +2 -2
  89. package/src/utils/par.ts +3 -3
  90. package/src/wallet-instance/index.ts +13 -0
@@ -1,14 +1,18 @@
1
+ import { decode, verify } from "./utils";
1
2
  import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
2
3
  import {
3
- WalletProviderEntityConfiguration,
4
- TrustAnchorEntityConfiguration,
5
4
  CredentialIssuerEntityConfiguration,
6
- RelyingPartyEntityConfiguration,
7
5
  EntityConfiguration,
8
6
  EntityStatement,
7
+ FederationListResponse,
8
+ RelyingPartyEntityConfiguration,
9
+ TrustAnchorEntityConfiguration,
10
+ WalletProviderEntityConfiguration,
9
11
  } from "./types";
10
- import { validateTrustChain, renewTrustChain } from "./chain";
12
+ import { renewTrustChain, validateTrustChain } from "./chain";
11
13
  import { hasStatusOrThrow } from "../utils/misc";
14
+ import { IoWalletError } from "../utils/errors";
15
+ import type { JWK } from "../utils/jwk";
12
16
 
13
17
  export type {
14
18
  WalletProviderEntityConfiguration,
@@ -24,9 +28,9 @@ export type {
24
28
  * It can handle fast chain renewal, which means we try to fetch a fresh version of each statement.
25
29
  *
26
30
  * @param trustAnchorEntity The entity configuration of the known trust anchor
27
- * @param chain The chain of statements to be validate
28
- * @param options.renewOnFail Whether to renew the provided chain if the validation fails at first. Default: true
29
- * @param options.appFetch Fetch api implementation. Default: the built-in implementation
31
+ * @param chain The chain of statements to be validated
32
+ * @param renewOnFail Whether to renew the provided chain if the validation fails at first. Default: true
33
+ * @param appFetch Fetch api implementation. Default: the built-in implementation
30
34
  * @returns The result of the chain validation
31
35
  * @throws {IoWalletError} When either validation or renewal fail
32
36
  */
@@ -54,7 +58,7 @@ export async function verifyTrustChain(
54
58
  * Fetch the signed entity configuration token for an entity
55
59
  *
56
60
  * @param entityBaseUrl The url of the entity to fetch
57
- * @param param.appFetch (optional) fetch api implemention
61
+ * @param appFetch (optional) fetch api implementation
58
62
  * @returns The signed Entity Configuration token
59
63
  */
60
64
  export async function getSignedEntityConfiguration(
@@ -86,6 +90,7 @@ export async function getSignedEntityConfiguration(
86
90
  *
87
91
  * @param entityBaseUrl The base url of the entity.
88
92
  * @param schema The expected schema of the entity configuration, according to the kind of entity we are fetching from.
93
+ * @param options An optional object with additional options.
89
94
  * @param options.appFetch An optional instance of the http client to be used.
90
95
  * @returns The parsed entity configuration object
91
96
  * @throws {IoWalletError} If the http request fails
@@ -200,9 +205,9 @@ export const getEntityConfiguration = (
200
205
  /**
201
206
  * Fetch and parse the entity statement document for a given federation entity.
202
207
  *
203
- * @param accreditationBodyBaseUrl The base url of the accreditaion body which holds and signs the required entity statement
208
+ * @param accreditationBodyBaseUrl The base url of the accreditation body which holds and signs the required entity statement
204
209
  * @param subordinatedEntityBaseUrl The url that identifies the subordinate entity
205
- * @param options.appFetch An optional instance of the http client to be used.
210
+ * @param appFetch An optional instance of the http client to be used.
206
211
  * @returns The parsed entity configuration object
207
212
  * @throws {IoWalletError} If the http request fails
208
213
  * @throws Parse error if the document is not in the expected shape.
@@ -234,14 +239,14 @@ export async function getEntityStatement(
234
239
  /**
235
240
  * Fetch the entity statement document for a given federation entity.
236
241
  *
237
- * @param accreditationBodyBaseUrl The base url of the accreditaion body which holds and signs the required entity statement
238
- * @param subordinatedEntityBaseUrl The url that identifies the subordinate entity
239
- * @param options.appFetch An optional instance of the http client to be used.
240
- * @returns The signed entity statement token
241
- * @throws {IoWalletError} If the http request fails
242
+ * @param federationFetchEndpoint The exact endpoint provided by the parent EC's metadata.
243
+ * @param subordinatedEntityBaseUrl The url that identifies the subordinate entity.
244
+ * @param appFetch An optional instance of the http client to be used.
245
+ * @returns The signed entity statement token.
246
+ * @throws {IoWalletError} If the http request fails.
242
247
  */
243
248
  export async function getSignedEntityStatement(
244
- accreditationBodyBaseUrl: string,
249
+ federationFetchEndpoint: string,
245
250
  subordinatedEntityBaseUrl: string,
246
251
  {
247
252
  appFetch = fetch,
@@ -249,13 +254,173 @@ export async function getSignedEntityStatement(
249
254
  appFetch?: GlobalFetch["fetch"];
250
255
  } = {}
251
256
  ) {
252
- const url = `${accreditationBodyBaseUrl}/fetch?${new URLSearchParams({
253
- sub: subordinatedEntityBaseUrl,
254
- })}`;
257
+ const url = new URL(federationFetchEndpoint);
258
+ url.searchParams.set("sub", subordinatedEntityBaseUrl);
255
259
 
256
- return await appFetch(url, {
260
+ return await appFetch(url.toString(), {
257
261
  method: "GET",
258
262
  })
259
263
  .then(hasStatusOrThrow(200))
260
264
  .then((res) => res.text());
261
265
  }
266
+
267
+ /**
268
+ * Fetch the federation list document from a given endpoint.
269
+ *
270
+ * @param federationListEndpoint The URL of the federation list endpoint.
271
+ * @param appFetch An optional instance of the http client to be used.
272
+ * @returns The federation list as an array of strings.
273
+ * @throws {IoWalletError} If the HTTP request fails or the response cannot be parsed.
274
+ */
275
+ export async function getFederationList(
276
+ federationListEndpoint: string,
277
+ {
278
+ appFetch = fetch,
279
+ }: {
280
+ appFetch?: GlobalFetch["fetch"];
281
+ } = {}
282
+ ): Promise<string[]> {
283
+ return await appFetch(federationListEndpoint, {
284
+ method: "GET",
285
+ })
286
+ .then(hasStatusOrThrow(200))
287
+ .then((res) => res.json())
288
+ .then((json) => {
289
+ const result = FederationListResponse.safeParse(json);
290
+ if (!result.success) {
291
+ throw new IoWalletError(
292
+ `Invalid federation list format received from Trust Anchor: ${result.error.message}`
293
+ );
294
+ }
295
+ return result.data;
296
+ });
297
+ }
298
+
299
+ /**
300
+ * Build a not-verified trust chain for a given Relying Party (RP) entity.
301
+ *
302
+ * @param relyingPartyEntityBaseUrl The base URL of the RP entity
303
+ * @param trustAnchorKey The public key of the Trust Anchor (TA) entity
304
+ * @param appFetch An optional instance of the http client to be used.
305
+ * @returns A list of signed tokens that represent the trust chain, in the order of the chain (from the RP to the Trust Anchor)
306
+ * @throws {IoWalletError} When an element of the chain fails to parse
307
+ * The result of this function can be used to validate the trust chain with {@link verifyTrustChain}
308
+ */
309
+ export async function buildTrustChain(
310
+ relyingPartyEntityBaseUrl: string,
311
+ trustAnchorKey: JWK,
312
+ appFetch: GlobalFetch["fetch"] = fetch
313
+ ): Promise<string[]> {
314
+ // 1: Recursively gather the trust chain from the RP up to the Trust Anchor
315
+ const trustChain = await gatherTrustChain(
316
+ relyingPartyEntityBaseUrl,
317
+ appFetch
318
+ );
319
+
320
+ // 2: Trust Anchor signature verification
321
+ const trustAnchorJwt = trustChain[trustChain.length - 1];
322
+ if (!trustAnchorJwt) {
323
+ throw new IoWalletError(
324
+ "Cannot verify trust anchor: missing entity configuration."
325
+ );
326
+ }
327
+
328
+ if (!trustAnchorKey.kid) {
329
+ throw new IoWalletError("Missing 'kid' in provided Trust Anchor key.");
330
+ }
331
+
332
+ await verify(trustAnchorJwt, trustAnchorKey.kid, [trustAnchorKey]);
333
+
334
+ // 3: Check the federation list
335
+ const trustAnchorConfig = EntityConfiguration.parse(decode(trustAnchorJwt));
336
+ const federationListEndpoint =
337
+ trustAnchorConfig.payload.metadata.federation_entity
338
+ .federation_list_endpoint;
339
+
340
+ if (federationListEndpoint) {
341
+ const federationList = await getFederationList(federationListEndpoint, {
342
+ appFetch,
343
+ });
344
+
345
+ if (!federationList.includes(relyingPartyEntityBaseUrl)) {
346
+ throw new IoWalletError(
347
+ "Relying Party entity base URL is not authorized by the Trust Anchor's federation list."
348
+ );
349
+ }
350
+ }
351
+
352
+ return trustChain;
353
+ }
354
+
355
+ /**
356
+ * Recursively gather the trust chain for an entity and all its superiors.
357
+ * @param entityBaseUrl The base URL of the entity for which to gather the chain.
358
+ * @param appFetch An optional instance of the http client to be used.
359
+ * @param isLeaf Whether the current entity is the leaf of the chain.
360
+ * @returns A full ordered list of JWTs (ECs and ESs) forming the trust chain.
361
+ */
362
+ async function gatherTrustChain(
363
+ entityBaseUrl: string,
364
+ appFetch: GlobalFetch["fetch"],
365
+ isLeaf: boolean = true
366
+ ): Promise<string[]> {
367
+ const chain: string[] = [];
368
+
369
+ // Fetch self-signed EC (only needed for the leaf)
370
+ const entityECJwt = await getSignedEntityConfiguration(entityBaseUrl, {
371
+ appFetch,
372
+ });
373
+ const entityEC = EntityConfiguration.parse(decode(entityECJwt));
374
+
375
+ if (isLeaf) {
376
+ // Only push EC for the leaf
377
+ chain.push(entityECJwt);
378
+ }
379
+
380
+ // Find authority_hints (parent, if any)
381
+ const authorityHints = entityEC.payload.authority_hints ?? [];
382
+ if (authorityHints.length === 0) {
383
+ // This is the Trust Anchor (no parent)
384
+ if (!isLeaf) {
385
+ chain.push(entityECJwt);
386
+ }
387
+ return chain;
388
+ }
389
+
390
+ const parentEntityBaseUrl = authorityHints[0]!;
391
+
392
+ // Fetch parent EC
393
+ const parentECJwt = await getSignedEntityConfiguration(parentEntityBaseUrl, {
394
+ appFetch,
395
+ });
396
+ const parentEC = EntityConfiguration.parse(decode(parentECJwt));
397
+
398
+ // Fetch ES
399
+ const federationFetchEndpoint =
400
+ parentEC.payload.metadata.federation_entity.federation_fetch_endpoint;
401
+ if (!federationFetchEndpoint) {
402
+ throw new IoWalletError(
403
+ "Missing federation_fetch_endpoint in parent's configuration."
404
+ );
405
+ }
406
+
407
+ const entityStatementJwt = await getSignedEntityStatement(
408
+ federationFetchEndpoint,
409
+ entityBaseUrl,
410
+ { appFetch }
411
+ );
412
+ // Validate the ES
413
+ EntityStatement.parse(decode(entityStatementJwt));
414
+
415
+ // Push this ES into the chain
416
+ chain.push(entityStatementJwt);
417
+
418
+ // Recurse into the parent
419
+ const parentChain = await gatherTrustChain(
420
+ parentEntityBaseUrl,
421
+ appFetch,
422
+ false
423
+ );
424
+
425
+ return chain.concat(parentChain);
426
+ }
@@ -12,7 +12,6 @@ const RelyingPartyMetadata = z.object({
12
12
  jwks: z.object({ keys: z.array(JWK) }),
13
13
  contacts: z.array(z.string()).optional(),
14
14
  });
15
- //.passthrough();
16
15
 
17
16
  // Display metadata for a credential, used by the issuer to
18
17
  // instruct the Wallet Solution on how to render the credential correctly
@@ -20,14 +19,6 @@ type CredentialDisplayMetadata = z.infer<typeof CredentialDisplayMetadata>;
20
19
  const CredentialDisplayMetadata = z.object({
21
20
  name: z.string(),
22
21
  locale: z.string(),
23
- logo: z
24
- .object({
25
- url: z.string(),
26
- alt_text: z.string(),
27
- })
28
- .optional(), // TODO [SIW-1268]: should not be optional
29
- background_color: z.string().optional(), // TODO [SIW-1268]: should not be optional
30
- text_color: z.string().optional(), // TODO [SIW-1268]: should not be optional
31
22
  });
32
23
 
33
24
  // Metadata for displaying issuer information
@@ -37,12 +28,6 @@ type CredentialIssuerDisplayMetadata = z.infer<
37
28
  const CredentialIssuerDisplayMetadata = z.object({
38
29
  name: z.string(),
39
30
  locale: z.string(),
40
- logo: z
41
- .object({
42
- url: z.string(),
43
- alt_text: z.string(),
44
- })
45
- .optional(), // TODO [SIW-1268]: should not be optional
46
31
  });
47
32
 
48
33
  type ClaimsMetadata = z.infer<typeof ClaimsMetadata>;
@@ -64,13 +49,13 @@ const IssuanceErrorSupported = z.object({
64
49
  ),
65
50
  });
66
51
 
67
- // Metadata for a credentia which is supported by a Issuer
52
+ // Metadata for a credential which is supported by an Issuer
68
53
  type SupportedCredentialMetadata = z.infer<typeof SupportedCredentialMetadata>;
69
54
  const SupportedCredentialMetadata = z.object({
70
55
  format: z.union([z.literal("vc+sd-jwt"), z.literal("vc+mdoc-cbor")]),
71
56
  scope: z.string(),
72
57
  display: z.array(CredentialDisplayMetadata),
73
- claims: ClaimsMetadata.optional(), // TODO [SIW-1268]: should not be optional
58
+ claims: ClaimsMetadata,
74
59
  cryptographic_binding_methods_supported: z.array(z.string()),
75
60
  credential_signing_alg_values_supported: z.array(z.string()),
76
61
  authentic_source: z.string().optional(),
@@ -88,7 +73,7 @@ export const EntityStatement = z.object({
88
73
  iss: z.string(),
89
74
  sub: z.string(),
90
75
  jwks: z.object({ keys: z.array(JWK) }),
91
- trust_marks: z.array(TrustMark),
76
+ trust_marks: z.array(TrustMark).optional(),
92
77
  iat: z.number(),
93
78
  exp: z.number(),
94
79
  }),
@@ -104,7 +89,7 @@ export const EntityConfigurationHeader = z.object({
104
89
  });
105
90
 
106
91
  /**
107
- * @see https://openid.net/specs/openid-connect-federation-1_0-29.html#name-federation-entity
92
+ * @see https://openid.net/specs/openid-federation-1_0-41.html
108
93
  */
109
94
  const FederationEntityMetadata = z
110
95
  .object({
@@ -113,6 +98,9 @@ const FederationEntityMetadata = z
113
98
  federation_resolve_endpoint: z.string().optional(),
114
99
  federation_trust_mark_status_endpoint: z.string().optional(),
115
100
  federation_trust_mark_list_endpoint: z.string().optional(),
101
+ federation_trust_mark_endpoint: z.string().optional(),
102
+ federation_historical_keys_endpoint: z.string().optional(),
103
+ endpoint_auth_signing_alg_values_supported: z.string().optional(),
116
104
  organization_name: z.string().optional(),
117
105
  homepage_uri: z.string().optional(),
118
106
  policy_uri: z.string().optional(),
@@ -121,7 +109,7 @@ const FederationEntityMetadata = z
121
109
  })
122
110
  .passthrough();
123
111
 
124
- // Structuire common to every Entity Configuration document
112
+ // Structure common to every Entity Configuration document
125
113
  const BaseEntityConfiguration = z.object({
126
114
  header: EntityConfigurationHeader,
127
115
  payload: z
@@ -172,22 +160,15 @@ export const CredentialIssuerEntityConfiguration = BaseEntityConfiguration.and(
172
160
  oauth_authorization_server: z.object({
173
161
  authorization_endpoint: z.string(),
174
162
  pushed_authorization_request_endpoint: z.string(),
175
- dpop_signing_alg_values_supported: z.array(z.string()).optional(), // TODO [SIW-1268]: should not be optional
176
163
  token_endpoint: z.string(),
177
- introspection_endpoint: z.string().optional(), // TODO [SIW-1268]: should not be optional
178
164
  client_registration_types_supported: z.array(z.string()),
179
165
  code_challenge_methods_supported: z.array(z.string()),
180
- authorization_details_types_supported: z.array(z.string()).optional(), // TODO [SIW-1268]: should not be optional,
181
166
  acr_values_supported: z.array(z.string()),
182
167
  grant_types_supported: z.array(z.string()),
183
168
  issuer: z.string(),
184
169
  jwks: z.object({ keys: z.array(JWK) }),
185
170
  scopes_supported: z.array(z.string()),
186
- request_parameter_supported: z.boolean().optional(), // TODO [SIW-1268]: should not be optional
187
- request_uri_parameter_supported: z.boolean().optional(), // TODO [SIW-1268]: should not be optional
188
- response_types_supported: z.array(z.string()).optional(), // TODO [SIW-1268]: should not be optional
189
171
  response_modes_supported: z.array(z.string()),
190
- subject_types_supported: z.array(z.string()).optional(), // TODO [SIW-1268]: should not be optional
191
172
  token_endpoint_auth_methods_supported: z.array(z.string()),
192
173
  token_endpoint_auth_signing_alg_values_supported: z.array(z.string()),
193
174
  request_object_signing_alg_values_supported: z.array(z.string()),
@@ -253,3 +234,5 @@ export const EntityConfiguration = z.union(
253
234
  description: "Any kind of Entity Configuration allowed in the ecosystem",
254
235
  }
255
236
  );
237
+
238
+ export const FederationListResponse = z.array(z.string());
@@ -0,0 +1,32 @@
1
+ import {
2
+ decode as decodeJwt,
3
+ verify as verifyJwt,
4
+ } from "@pagopa/io-react-native-jwt";
5
+
6
+ import type { JWK } from "../utils/jwk";
7
+ import type { JWTDecodeResult } from "@pagopa/io-react-native-jwt/lib/typescript/types";
8
+
9
+ export type ParsedToken = {
10
+ header: JWTDecodeResult["protectedHeader"];
11
+ payload: JWTDecodeResult["payload"];
12
+ };
13
+
14
+ // Verify a token signature
15
+ // The kid is extracted from the token header
16
+ export const verify = async (
17
+ token: string,
18
+ kid: string,
19
+ jwks: JWK[]
20
+ ): Promise<ParsedToken> => {
21
+ const jwk = jwks.find((k) => k.kid === kid);
22
+ if (!jwk) {
23
+ throw new Error(`Invalid kid: ${kid}, token: ${token}`);
24
+ }
25
+ const { protectedHeader: header, payload } = await verifyJwt(token, jwk);
26
+ return { header, payload };
27
+ };
28
+
29
+ export const decode = (token: string) => {
30
+ const { protectedHeader: header, payload } = decodeJwt(token);
31
+ return { header, payload };
32
+ };
@@ -4,7 +4,7 @@ import {
4
4
  generate,
5
5
  deleteKey,
6
6
  } from "@pagopa/io-react-native-crypto";
7
- import uuid from "react-native-uuid";
7
+ import { v4 as uuidv4 } from "uuid";
8
8
  import { thumbprint, type CryptoContext } from "@pagopa/io-react-native-jwt";
9
9
  import { fixBase64EncodingOnKey } from "./jwk";
10
10
 
@@ -58,7 +58,7 @@ export const withEphemeralKey = async <R>(
58
58
  fn: (ephemeralContext: CryptoContext) => Promise<R>
59
59
  ): Promise<R> => {
60
60
  // Use an ephemeral key to be destroyed after use
61
- const keytag = `ephemeral-${uuid.v4()}`;
61
+ const keytag = `ephemeral-${uuidv4()}`;
62
62
  await generate(keytag);
63
63
  const ephemeralContext = createCryptoContextFor(keytag);
64
64
  return fn(ephemeralContext).finally(() => deleteKey(keytag));
package/src/utils/par.ts CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  type CryptoContext,
4
4
  SignJWT,
5
5
  } from "@pagopa/io-react-native-jwt";
6
- import uuid from "react-native-uuid";
6
+ import { v4 as uuidv4 } from "uuid";
7
7
  import * as z from "zod";
8
8
  import * as WalletInstanceAttestation from "../wallet-instance-attestation";
9
9
  import { generateRandomAlphaNumericString, hasStatusOrThrow } from "./misc";
@@ -51,7 +51,7 @@ export const makeParRequest =
51
51
 
52
52
  const signedWiaPoP = await createPopToken(
53
53
  {
54
- jti: `${uuid.v4()}`,
54
+ jti: `${uuidv4()}`,
55
55
  aud,
56
56
  iss,
57
57
  },
@@ -74,7 +74,7 @@ export const makeParRequest =
74
74
  kid: wiaPublicKey.kid,
75
75
  })
76
76
  .setPayload({
77
- jti: `${uuid.v4()}`,
77
+ jti: `${uuidv4()}`,
78
78
  aud,
79
79
  response_type: "code",
80
80
  response_mode: responseMode,
@@ -87,3 +87,16 @@ export async function getWalletInstanceStatus(context: {
87
87
  path: { id: context.id },
88
88
  });
89
89
  }
90
+
91
+ /**
92
+ * Get the status of the current Wallet Instance.
93
+ * @returns Details on the status of the current Wallet Instance
94
+ */
95
+ export async function getCurrentWalletInstanceStatus(context: {
96
+ walletProviderBaseUrl: string;
97
+ appFetch?: GlobalFetch["fetch"];
98
+ }): Promise<WalletInstanceData> {
99
+ const api = getWalletProviderClient(context);
100
+
101
+ return api.get("/wallet-instances/current/status");
102
+ }