@pagopa/io-react-native-wallet 2.0.0-next.2 → 2.0.0-next.3

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 (122) hide show
  1. package/lib/commonjs/credential/issuance/03-start-user-authorization.js +38 -24
  2. package/lib/commonjs/credential/issuance/03-start-user-authorization.js.map +1 -1
  3. package/lib/commonjs/credential/issuance/05-authorize-access.js +6 -10
  4. package/lib/commonjs/credential/issuance/05-authorize-access.js.map +1 -1
  5. package/lib/commonjs/credential/issuance/06-obtain-credential.js +43 -11
  6. package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
  7. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +51 -48
  8. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  9. package/lib/commonjs/credential/issuance/README.md +34 -13
  10. package/lib/commonjs/credential/issuance/const.js +1 -1
  11. package/lib/commonjs/credential/issuance/types.js +16 -10
  12. package/lib/commonjs/credential/issuance/types.js.map +1 -1
  13. package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +4 -4
  14. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +3 -3
  15. package/lib/commonjs/credential/status/README.md +0 -1
  16. package/lib/commonjs/sd-jwt/__test__/index.test.js +11 -15
  17. package/lib/commonjs/sd-jwt/__test__/index.test.js.map +1 -1
  18. package/lib/commonjs/sd-jwt/__test__/types.test.js +5 -2
  19. package/lib/commonjs/sd-jwt/__test__/types.test.js.map +1 -1
  20. package/lib/commonjs/sd-jwt/__test__/utils.test.js +37 -0
  21. package/lib/commonjs/sd-jwt/__test__/utils.test.js.map +1 -0
  22. package/lib/commonjs/sd-jwt/index.js +20 -0
  23. package/lib/commonjs/sd-jwt/index.js.map +1 -1
  24. package/lib/commonjs/sd-jwt/types.js +51 -4
  25. package/lib/commonjs/sd-jwt/types.js.map +1 -1
  26. package/lib/commonjs/sd-jwt/utils.js +64 -0
  27. package/lib/commonjs/sd-jwt/utils.js.map +1 -0
  28. package/lib/commonjs/trust/types.js +18 -13
  29. package/lib/commonjs/trust/types.js.map +1 -1
  30. package/lib/commonjs/utils/par.js +32 -22
  31. package/lib/commonjs/utils/par.js.map +1 -1
  32. package/lib/commonjs/utils/pop.js +1 -1
  33. package/lib/commonjs/utils/pop.js.map +1 -1
  34. package/lib/commonjs/wallet-instance-attestation/types.js +5 -1
  35. package/lib/commonjs/wallet-instance-attestation/types.js.map +1 -1
  36. package/lib/module/credential/issuance/03-start-user-authorization.js +38 -24
  37. package/lib/module/credential/issuance/03-start-user-authorization.js.map +1 -1
  38. package/lib/module/credential/issuance/05-authorize-access.js +6 -10
  39. package/lib/module/credential/issuance/05-authorize-access.js.map +1 -1
  40. package/lib/module/credential/issuance/06-obtain-credential.js +44 -12
  41. package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
  42. package/lib/module/credential/issuance/07-verify-and-parse-credential.js +51 -48
  43. package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  44. package/lib/module/credential/issuance/README.md +34 -13
  45. package/lib/module/credential/issuance/const.js +1 -1
  46. package/lib/module/credential/issuance/types.js +12 -8
  47. package/lib/module/credential/issuance/types.js.map +1 -1
  48. package/lib/module/credential/presentation/07-evaluate-dcql-query.js +4 -4
  49. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +3 -3
  50. package/lib/module/credential/status/README.md +0 -1
  51. package/lib/module/sd-jwt/__test__/index.test.js +11 -16
  52. package/lib/module/sd-jwt/__test__/index.test.js.map +1 -1
  53. package/lib/module/sd-jwt/__test__/types.test.js +5 -2
  54. package/lib/module/sd-jwt/__test__/types.test.js.map +1 -1
  55. package/lib/module/sd-jwt/__test__/utils.test.js +35 -0
  56. package/lib/module/sd-jwt/__test__/utils.test.js.map +1 -0
  57. package/lib/module/sd-jwt/index.js +1 -0
  58. package/lib/module/sd-jwt/index.js.map +1 -1
  59. package/lib/module/sd-jwt/types.js +50 -3
  60. package/lib/module/sd-jwt/types.js.map +1 -1
  61. package/lib/module/sd-jwt/utils.js +57 -0
  62. package/lib/module/sd-jwt/utils.js.map +1 -0
  63. package/lib/module/trust/types.js +18 -13
  64. package/lib/module/trust/types.js.map +1 -1
  65. package/lib/module/utils/par.js +29 -20
  66. package/lib/module/utils/par.js.map +1 -1
  67. package/lib/module/utils/pop.js +1 -1
  68. package/lib/module/utils/pop.js.map +1 -1
  69. package/lib/module/wallet-instance-attestation/types.js +5 -1
  70. package/lib/module/wallet-instance-attestation/types.js.map +1 -1
  71. package/lib/typescript/client/generated/wallet-provider.d.ts +12 -12
  72. package/lib/typescript/credential/issuance/01-start-flow.d.ts +2 -2
  73. package/lib/typescript/credential/issuance/01-start-flow.d.ts.map +1 -1
  74. package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts +7 -6
  75. package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts.map +1 -1
  76. package/lib/typescript/credential/issuance/05-authorize-access.d.ts.map +1 -1
  77. package/lib/typescript/credential/issuance/06-obtain-credential.d.ts +10 -5
  78. package/lib/typescript/credential/issuance/06-obtain-credential.d.ts.map +1 -1
  79. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts +3 -2
  80. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
  81. package/lib/typescript/credential/issuance/const.d.ts +1 -1
  82. package/lib/typescript/credential/issuance/types.d.ts +46 -26
  83. package/lib/typescript/credential/issuance/types.d.ts.map +1 -1
  84. package/lib/typescript/pid/sd-jwt/types.d.ts +7 -7
  85. package/lib/typescript/sd-jwt/__test__/utils.test.d.ts +2 -0
  86. package/lib/typescript/sd-jwt/__test__/utils.test.d.ts.map +1 -0
  87. package/lib/typescript/sd-jwt/index.d.ts +21 -8
  88. package/lib/typescript/sd-jwt/index.d.ts.map +1 -1
  89. package/lib/typescript/sd-jwt/types.d.ts +194 -12
  90. package/lib/typescript/sd-jwt/types.d.ts.map +1 -1
  91. package/lib/typescript/sd-jwt/utils.d.ts +18 -0
  92. package/lib/typescript/sd-jwt/utils.d.ts.map +1 -0
  93. package/lib/typescript/trust/build-chain.d.ts +30 -14
  94. package/lib/typescript/trust/build-chain.d.ts.map +1 -1
  95. package/lib/typescript/trust/types.d.ts +322 -158
  96. package/lib/typescript/trust/types.d.ts.map +1 -1
  97. package/lib/typescript/utils/par.d.ts +29 -13
  98. package/lib/typescript/utils/par.d.ts.map +1 -1
  99. package/lib/typescript/wallet-instance-attestation/types.d.ts +9 -9
  100. package/lib/typescript/wallet-instance-attestation/types.d.ts.map +1 -1
  101. package/package.json +1 -1
  102. package/src/credential/issuance/01-start-flow.ts +2 -2
  103. package/src/credential/issuance/03-start-user-authorization.ts +57 -38
  104. package/src/credential/issuance/05-authorize-access.ts +5 -11
  105. package/src/credential/issuance/06-obtain-credential.ts +53 -23
  106. package/src/credential/issuance/07-verify-and-parse-credential.ts +54 -62
  107. package/src/credential/issuance/README.md +34 -13
  108. package/src/credential/issuance/const.ts +1 -1
  109. package/src/credential/issuance/types.ts +18 -8
  110. package/src/credential/presentation/07-evaluate-dcql-query.ts +4 -4
  111. package/src/credential/presentation/07-evaluate-input-descriptor.ts +3 -3
  112. package/src/credential/status/README.md +0 -1
  113. package/src/sd-jwt/__test__/index.test.ts +8 -29
  114. package/src/sd-jwt/__test__/types.test.ts +6 -2
  115. package/src/sd-jwt/__test__/utils.test.ts +37 -0
  116. package/src/sd-jwt/index.ts +2 -0
  117. package/src/sd-jwt/types.ts +49 -2
  118. package/src/sd-jwt/utils.ts +73 -0
  119. package/src/trust/types.ts +23 -17
  120. package/src/utils/par.ts +37 -21
  121. package/src/utils/pop.ts +1 -1
  122. package/src/wallet-instance-attestation/types.ts +3 -1
@@ -0,0 +1,73 @@
1
+ import { sha256ToBase64 } from "@pagopa/io-react-native-jwt";
2
+ import { hasStatusOrThrow } from "../utils/misc";
3
+ import { TypeMetadata, Verification } from "./types";
4
+ import {
5
+ IoWalletError,
6
+ IssuerResponseError,
7
+ ValidationFailed,
8
+ } from "../utils/errors";
9
+ import { decode } from ".";
10
+ import { getValueFromDisclosures } from "./converters";
11
+
12
+ /**
13
+ * Retrieve the Type Metadata for a credential and verify its integrity.
14
+ * @param vct The VCT as a valid HTTPS url
15
+ * @param vctIntegrity The integrity hash
16
+ * @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
17
+ * @returns The credential metadata {@link TypeMetadata}
18
+ */
19
+ export const fetchTypeMetadata = async (
20
+ vct: string,
21
+ vctIntegrity: string,
22
+ context: {
23
+ appFetch?: GlobalFetch["fetch"];
24
+ } = {}
25
+ ): Promise<TypeMetadata> => {
26
+ const { appFetch = fetch } = context;
27
+ const { origin, pathname } = new URL(vct);
28
+
29
+ const metadata = await appFetch(`${origin}/.well-known/vct${pathname}`, {
30
+ headers: {
31
+ "Content-Type": "application/json",
32
+ },
33
+ })
34
+ .then(hasStatusOrThrow(200, IssuerResponseError))
35
+ .then((res) => res.json())
36
+ .then(TypeMetadata.parse);
37
+
38
+ const [alg, hash] = vctIntegrity.split(/-(.*)/s);
39
+
40
+ if (alg !== "sha256") {
41
+ throw new IoWalletError(`${alg} algorithm is not supported`);
42
+ }
43
+
44
+ // TODO: [SIW-2264] check if the hash is correctly calculated
45
+ const metadataHash = await sha256ToBase64(JSON.stringify(metadata));
46
+
47
+ if (metadataHash !== hash) {
48
+ throw new ValidationFailed({
49
+ message: "Unable to verify VCT integrity",
50
+ reason: "vct#integrity does not match the metadata hash",
51
+ });
52
+ }
53
+
54
+ return metadata;
55
+ };
56
+
57
+ /**
58
+ * Extract and validate the `verification` claim from disclosures.
59
+ * @param credentialSdJwt The raw credential SD-JWT
60
+ * @returns The verification claim or undefined if it wasn't found
61
+ */
62
+ export const getVerification = (
63
+ credentialSdJwt: string
64
+ ): Verification | undefined => {
65
+ const { disclosures } = decode(credentialSdJwt);
66
+ const verificationDisclosure = getValueFromDisclosures(
67
+ disclosures.map((d) => d.decoded),
68
+ "verification"
69
+ );
70
+ return verificationDisclosure
71
+ ? Verification.parse(verificationDisclosure)
72
+ : undefined;
73
+ };
@@ -37,12 +37,10 @@ const CredentialIssuerDisplayMetadata = z.object({
37
37
  });
38
38
 
39
39
  type ClaimsMetadata = z.infer<typeof ClaimsMetadata>;
40
- const ClaimsMetadata = z.record(
41
- z.object({
42
- value_type: z.string(),
43
- display: z.array(z.object({ name: z.string(), locale: z.string() })),
44
- })
45
- );
40
+ const ClaimsMetadata = z.object({
41
+ path: z.array(z.string()),
42
+ display: z.array(CredentialDisplayMetadata),
43
+ });
46
44
 
47
45
  type IssuanceErrorSupported = z.infer<typeof IssuanceErrorSupported>;
48
46
  const IssuanceErrorSupported = z.object({
@@ -57,16 +55,21 @@ const IssuanceErrorSupported = z.object({
57
55
 
58
56
  // Metadata for a credential which is supported by an Issuer
59
57
  type SupportedCredentialMetadata = z.infer<typeof SupportedCredentialMetadata>;
60
- const SupportedCredentialMetadata = z.object({
61
- format: z.union([z.literal("vc+sd-jwt"), z.literal("vc+mdoc-cbor")]),
62
- scope: z.string(),
63
- display: z.array(CredentialDisplayMetadata),
64
- claims: ClaimsMetadata,
65
- cryptographic_binding_methods_supported: z.array(z.string()),
66
- credential_signing_alg_values_supported: z.array(z.string()),
67
- authentic_source: z.string().optional(),
68
- issuance_errors_supported: z.record(IssuanceErrorSupported).optional(),
69
- });
58
+ const SupportedCredentialMetadata = z.intersection(
59
+ z.discriminatedUnion("format", [
60
+ z.object({ format: z.literal("dc+sd-jwt"), vct: z.string() }),
61
+ z.object({ format: z.literal("mso_mdoc"), doctype: z.string() }),
62
+ ]),
63
+ z.object({
64
+ scope: z.string(),
65
+ display: z.array(CredentialDisplayMetadata),
66
+ claims: z.array(ClaimsMetadata),
67
+ cryptographic_binding_methods_supported: z.array(z.string()),
68
+ credential_signing_alg_values_supported: z.array(z.string()),
69
+ authentic_source: z.string().optional(),
70
+ issuance_errors_supported: z.record(IssuanceErrorSupported).optional(),
71
+ })
72
+ );
70
73
 
71
74
  export type EntityStatement = z.infer<typeof EntityStatement>;
72
75
  export const EntityStatement = z.object({
@@ -155,13 +158,16 @@ export const CredentialIssuerEntityConfiguration = BaseEntityConfiguration.and(
155
158
  openid_credential_issuer: z.object({
156
159
  credential_issuer: z.string(),
157
160
  credential_endpoint: z.string(),
158
- revocation_endpoint: z.string(),
161
+ revocation_endpoint: z.string().optional(),
162
+ nonce_endpoint: z.string(),
159
163
  status_attestation_endpoint: z.string(),
160
164
  display: z.array(CredentialIssuerDisplayMetadata),
161
165
  credential_configurations_supported: z.record(
162
166
  SupportedCredentialMetadata
163
167
  ),
164
168
  jwks: z.object({ keys: z.array(JWK) }),
169
+ trust_frameworks_supported: z.array(z.string()),
170
+ evidence_supported: z.array(z.string()),
165
171
  }),
166
172
  oauth_authorization_server: z.object({
167
173
  authorization_endpoint: z.string(),
package/src/utils/par.ts CHANGED
@@ -13,14 +13,31 @@ import { LogLevel, Logger } from "./logging";
13
13
 
14
14
  export type AuthorizationDetail = z.infer<typeof AuthorizationDetail>;
15
15
  export const AuthorizationDetail = z.object({
16
- credential_configuration_id: z.string(),
17
- format: z.union([z.literal("vc+sd-jwt"), z.literal("vc+mdoc-cbor")]),
18
16
  type: z.literal("openid_credential"),
17
+ credential_configuration_id: z.string(),
19
18
  });
20
19
 
21
20
  export type AuthorizationDetails = z.infer<typeof AuthorizationDetails>;
22
21
  export const AuthorizationDetails = z.array(AuthorizationDetail);
23
22
 
23
+ export type ParResponse = z.infer<typeof ParResponse>;
24
+ export const ParResponse = z.object({
25
+ request_uri: z.string(),
26
+ expires_in: z.number(),
27
+ });
28
+
29
+ type AuthDetailsOrScope =
30
+ | { authorizationDetails: AuthorizationDetails; scope?: string }
31
+ | { authorizationDetails?: AuthorizationDetails; scope: string };
32
+
33
+ type ParRequestPayload = {
34
+ clientId: string;
35
+ codeVerifier: string;
36
+ redirectUri: string;
37
+ responseMode: string;
38
+ aud: string;
39
+ } & AuthDetailsOrScope;
40
+
24
41
  /**
25
42
  * Make a PAR request to the issuer and return the response url
26
43
  */
@@ -33,20 +50,20 @@ export const makeParRequest =
33
50
  appFetch: GlobalFetch["fetch"];
34
51
  }) =>
35
52
  async (
36
- clientId: string,
37
- codeVerifier: string,
38
- redirectUri: string,
39
- responseMode: string,
40
53
  parEndpoint: string,
41
54
  walletInstanceAttestation: string,
42
- authorizationDetails: AuthorizationDetails,
43
- assertionType: string
55
+ {
56
+ codeVerifier,
57
+ responseMode,
58
+ clientId,
59
+ redirectUri,
60
+ authorizationDetails,
61
+ scope,
62
+ aud,
63
+ }: ParRequestPayload
44
64
  ): Promise<string> => {
45
65
  const wiaPublicKey = await wiaCryptoContext.getPublicKey();
46
66
 
47
- const parUrl = new URL(parEndpoint);
48
- const aud = `${parUrl.protocol}//${parUrl.hostname}`;
49
-
50
67
  const iss = WalletInstanceAttestation.decode(walletInstanceAttestation)
51
68
  .payload.cnf.jwk.kid;
52
69
 
@@ -71,7 +88,7 @@ export const makeParRequest =
71
88
  The key is matched by its kid */
72
89
  const signedJwtForPar = await new SignJWT(wiaCryptoContext)
73
90
  .setProtectedHeader({
74
- typ: "jwk",
91
+ typ: "jwt",
75
92
  kid: wiaPublicKey.kid,
76
93
  })
77
94
  .setPayload({
@@ -84,24 +101,20 @@ export const makeParRequest =
84
101
  state: generateRandomAlphaNumericString(32),
85
102
  code_challenge: codeChallenge,
86
103
  code_challenge_method: codeChallengeMethod,
87
- authorization_details: authorizationDetails,
88
104
  redirect_uri: redirectUri,
89
- client_assertion_type: assertionType,
90
- client_assertion: walletInstanceAttestation + "~" + signedWiaPoP,
105
+ ...(authorizationDetails && {
106
+ authorization_details: authorizationDetails,
107
+ }),
108
+ ...(scope && { scope }),
91
109
  })
92
- .setIssuedAt() //iat is set to now
110
+ .setIssuedAt() // iat is set to now
93
111
  .setExpirationTime("5min")
94
112
  .sign();
95
113
 
96
114
  /** The request body for the Pushed Authorization Request */
97
115
  var formBody = new URLSearchParams({
98
- response_type: "code",
99
116
  client_id: clientId,
100
- code_challenge: codeChallenge,
101
- code_challenge_method: "S256",
102
117
  request: signedJwtForPar,
103
- client_assertion_type: assertionType,
104
- client_assertion: walletInstanceAttestation + "~" + signedWiaPoP,
105
118
  });
106
119
 
107
120
  Logger.log(
@@ -113,10 +126,13 @@ export const makeParRequest =
113
126
  method: "POST",
114
127
  headers: {
115
128
  "Content-Type": "application/x-www-form-urlencoded",
129
+ "OAuth-Client-Attestation": walletInstanceAttestation,
130
+ "OAuth-Client-Attestation-PoP": signedWiaPoP,
116
131
  },
117
132
  body: formBody.toString(),
118
133
  })
119
134
  .then(hasStatusOrThrow(201, IssuerResponseError))
120
135
  .then((res) => res.json())
136
+ .then(ParResponse.parse)
121
137
  .then((result) => result.request_uri);
122
138
  };
package/src/utils/pop.ts CHANGED
@@ -18,7 +18,7 @@ export const createPopToken = async (
18
18
  return new SignJWT(crypto)
19
19
  .setPayload(payload)
20
20
  .setProtectedHeader({
21
- typ: "jwt-client-attestation-pop",
21
+ typ: "oauth-client-attestation-pop+jwt",
22
22
  kid,
23
23
  })
24
24
  .setIssuedAt()
@@ -48,6 +48,8 @@ export const WalletInstanceAttestationRequestJwt = z.object({
48
48
  ),
49
49
  });
50
50
 
51
+ // TODO: [SIW-2089] add type for Wallet Attestation in SD-JWT and MDOC format
52
+ // See https://italia.github.io/eid-wallet-it-docs/versione-corrente/en/wallet-solution.html#wallet-attestation-issuance step 18
51
53
  export type WalletInstanceAttestationJwt = z.infer<
52
54
  typeof WalletInstanceAttestationJwt
53
55
  >;
@@ -56,7 +58,7 @@ export const WalletInstanceAttestationJwt = z.object({
56
58
  Jwt.shape.header,
57
59
  z.object({
58
60
  typ: z.literal("oauth-client-attestation+jwt"),
59
- trust_chain: z.array(z.string()),
61
+ trust_chain: z.array(z.string()).optional(), // TODO: [SIW-2264] Make mandatory
60
62
  })
61
63
  ),
62
64
  payload: z.intersection(