@pagopa/io-react-native-wallet 0.1.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 (114) hide show
  1. package/README.md +91 -0
  2. package/lib/commonjs/index.js +17 -0
  3. package/lib/commonjs/index.js.map +1 -0
  4. package/lib/commonjs/pid/index.js +11 -0
  5. package/lib/commonjs/pid/index.js.map +1 -0
  6. package/lib/commonjs/pid/sd-jwt/converters.js +29 -0
  7. package/lib/commonjs/pid/sd-jwt/converters.js.map +1 -0
  8. package/lib/commonjs/pid/sd-jwt/index.js +76 -0
  9. package/lib/commonjs/pid/sd-jwt/index.js.map +1 -0
  10. package/lib/commonjs/pid/sd-jwt/types.js +50 -0
  11. package/lib/commonjs/pid/sd-jwt/types.js.map +1 -0
  12. package/lib/commonjs/sd-jwt/__test__/converters.test.js +25 -0
  13. package/lib/commonjs/sd-jwt/__test__/converters.test.js.map +1 -0
  14. package/lib/commonjs/sd-jwt/__test__/types.test.js +70 -0
  15. package/lib/commonjs/sd-jwt/__test__/types.test.js.map +1 -0
  16. package/lib/commonjs/sd-jwt/converters.js +30 -0
  17. package/lib/commonjs/sd-jwt/converters.js.map +1 -0
  18. package/lib/commonjs/sd-jwt/index.js +77 -0
  19. package/lib/commonjs/sd-jwt/index.js.map +1 -0
  20. package/lib/commonjs/sd-jwt/types.js +53 -0
  21. package/lib/commonjs/sd-jwt/types.js.map +1 -0
  22. package/lib/commonjs/sd-jwt/verifier.js +18 -0
  23. package/lib/commonjs/sd-jwt/verifier.js.map +1 -0
  24. package/lib/commonjs/utils/errors.js +82 -0
  25. package/lib/commonjs/utils/errors.js.map +1 -0
  26. package/lib/commonjs/utils/jwk.js +45 -0
  27. package/lib/commonjs/utils/jwk.js.map +1 -0
  28. package/lib/commonjs/wallet-instance-attestation/index.js +63 -0
  29. package/lib/commonjs/wallet-instance-attestation/index.js.map +1 -0
  30. package/lib/commonjs/wallet-instance-attestation/issuing.js +96 -0
  31. package/lib/commonjs/wallet-instance-attestation/issuing.js.map +1 -0
  32. package/lib/commonjs/wallet-instance-attestation/types.js +65 -0
  33. package/lib/commonjs/wallet-instance-attestation/types.js.map +1 -0
  34. package/lib/module/index.js +7 -0
  35. package/lib/module/index.js.map +1 -0
  36. package/lib/module/pid/index.js +3 -0
  37. package/lib/module/pid/index.js.map +1 -0
  38. package/lib/module/pid/sd-jwt/converters.js +23 -0
  39. package/lib/module/pid/sd-jwt/converters.js.map +1 -0
  40. package/lib/module/pid/sd-jwt/index.js +66 -0
  41. package/lib/module/pid/sd-jwt/index.js.map +1 -0
  42. package/lib/module/pid/sd-jwt/types.js +43 -0
  43. package/lib/module/pid/sd-jwt/types.js.map +1 -0
  44. package/lib/module/sd-jwt/__test__/converters.test.js +23 -0
  45. package/lib/module/sd-jwt/__test__/converters.test.js.map +1 -0
  46. package/lib/module/sd-jwt/__test__/types.test.js +68 -0
  47. package/lib/module/sd-jwt/__test__/types.test.js.map +1 -0
  48. package/lib/module/sd-jwt/converters.js +24 -0
  49. package/lib/module/sd-jwt/converters.js.map +1 -0
  50. package/lib/module/sd-jwt/index.js +71 -0
  51. package/lib/module/sd-jwt/index.js.map +1 -0
  52. package/lib/module/sd-jwt/types.js +44 -0
  53. package/lib/module/sd-jwt/types.js.map +1 -0
  54. package/lib/module/sd-jwt/verifier.js +11 -0
  55. package/lib/module/sd-jwt/verifier.js.map +1 -0
  56. package/lib/module/utils/errors.js +73 -0
  57. package/lib/module/utils/errors.js.map +1 -0
  58. package/lib/module/utils/jwk.js +38 -0
  59. package/lib/module/utils/jwk.js.map +1 -0
  60. package/lib/module/wallet-instance-attestation/index.js +52 -0
  61. package/lib/module/wallet-instance-attestation/index.js.map +1 -0
  62. package/lib/module/wallet-instance-attestation/issuing.js +90 -0
  63. package/lib/module/wallet-instance-attestation/issuing.js.map +1 -0
  64. package/lib/module/wallet-instance-attestation/types.js +55 -0
  65. package/lib/module/wallet-instance-attestation/types.js.map +1 -0
  66. package/lib/typescript/index.d.ts +5 -0
  67. package/lib/typescript/index.d.ts.map +1 -0
  68. package/lib/typescript/pid/index.d.ts +3 -0
  69. package/lib/typescript/pid/index.d.ts.map +1 -0
  70. package/lib/typescript/pid/sd-jwt/converters.d.ts +4 -0
  71. package/lib/typescript/pid/sd-jwt/converters.d.ts.map +1 -0
  72. package/lib/typescript/pid/sd-jwt/index.d.ts +50 -0
  73. package/lib/typescript/pid/sd-jwt/index.d.ts.map +1 -0
  74. package/lib/typescript/pid/sd-jwt/types.d.ts +196 -0
  75. package/lib/typescript/pid/sd-jwt/types.d.ts.map +1 -0
  76. package/lib/typescript/sd-jwt/__test__/converters.test.d.ts +2 -0
  77. package/lib/typescript/sd-jwt/__test__/converters.test.d.ts.map +1 -0
  78. package/lib/typescript/sd-jwt/__test__/types.test.d.ts +2 -0
  79. package/lib/typescript/sd-jwt/__test__/types.test.d.ts.map +1 -0
  80. package/lib/typescript/sd-jwt/converters.d.ts +3 -0
  81. package/lib/typescript/sd-jwt/converters.d.ts.map +1 -0
  82. package/lib/typescript/sd-jwt/index.d.ts +42 -0
  83. package/lib/typescript/sd-jwt/index.d.ts.map +1 -0
  84. package/lib/typescript/sd-jwt/types.d.ts +416 -0
  85. package/lib/typescript/sd-jwt/types.d.ts.map +1 -0
  86. package/lib/typescript/sd-jwt/verifier.d.ts +3 -0
  87. package/lib/typescript/sd-jwt/verifier.d.ts.map +1 -0
  88. package/lib/typescript/utils/errors.d.ts +45 -0
  89. package/lib/typescript/utils/errors.d.ts.map +1 -0
  90. package/lib/typescript/utils/jwk.d.ts +85 -0
  91. package/lib/typescript/utils/jwk.d.ts.map +1 -0
  92. package/lib/typescript/wallet-instance-attestation/index.d.ts +36 -0
  93. package/lib/typescript/wallet-instance-attestation/index.d.ts.map +1 -0
  94. package/lib/typescript/wallet-instance-attestation/issuing.d.ts +32 -0
  95. package/lib/typescript/wallet-instance-attestation/issuing.d.ts.map +1 -0
  96. package/lib/typescript/wallet-instance-attestation/types.d.ts +733 -0
  97. package/lib/typescript/wallet-instance-attestation/types.d.ts.map +1 -0
  98. package/package.json +108 -0
  99. package/src/index.ts +8 -0
  100. package/src/pid/index.ts +2 -0
  101. package/src/pid/sd-jwt/converters.ts +26 -0
  102. package/src/pid/sd-jwt/index.ts +71 -0
  103. package/src/pid/sd-jwt/types.ts +44 -0
  104. package/src/sd-jwt/__test__/converters.test.ts +27 -0
  105. package/src/sd-jwt/__test__/types.test.ts +85 -0
  106. package/src/sd-jwt/converters.ts +24 -0
  107. package/src/sd-jwt/index.ts +92 -0
  108. package/src/sd-jwt/types.ts +54 -0
  109. package/src/sd-jwt/verifier.ts +20 -0
  110. package/src/utils/errors.ts +74 -0
  111. package/src/utils/jwk.ts +39 -0
  112. package/src/wallet-instance-attestation/index.ts +56 -0
  113. package/src/wallet-instance-attestation/issuing.ts +107 -0
  114. package/src/wallet-instance-attestation/types.ts +77 -0
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+
3
+ export type JWK = z.infer<typeof JWK>;
4
+ export const JWK = z.object({
5
+ /** JWK "alg" (Algorithm) Parameter. */
6
+ alg: z.string().optional(),
7
+ crv: z.string().optional(),
8
+ d: z.string().optional(),
9
+ dp: z.string().optional(),
10
+ dq: z.string().optional(),
11
+ e: z.string().optional(),
12
+ /** JWK "ext" (Extractable) Parameter. */
13
+ ext: z.boolean().optional(),
14
+ k: z.string().optional(),
15
+ /** JWK "key_ops" (Key Operations) Parameter. */
16
+ key_ops: z.array(z.string()).optional(),
17
+ /** JWK "kid" (Key ID) Parameter. */
18
+ kid: z.string().optional(),
19
+ /** JWK "kty" (Key Type) Parameter.
20
+ * This attribute is required to discriminate the
21
+ * type of EC/RSA algorithm */
22
+ kty: z.union([z.literal("RSA"), z.literal("EC")]),
23
+ n: z.string().optional(),
24
+ p: z.string().optional(),
25
+ q: z.string().optional(),
26
+ qi: z.string().optional(),
27
+ /** JWK "use" (Public Key Use) Parameter. */
28
+ use: z.string().optional(),
29
+ x: z.string().optional(),
30
+ y: z.string().optional(),
31
+ /** JWK "x5c" (X.509 Certificate Chain) Parameter. */
32
+ x5c: z.array(z.string()).optional(),
33
+ /** JWK "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter. */
34
+ x5t: z.string().optional(),
35
+ /** "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Parameter. */
36
+ "x5t#S256": z.string().optional(),
37
+ /** JWK "x5u" (X.509 URL) Parameter. */
38
+ x5u: z.string().optional(),
39
+ });
@@ -0,0 +1,56 @@
1
+ import { WalletInstanceAttestationJwt } from "./types";
2
+ import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
3
+ import { verify as verifyJwt } from "@pagopa/io-react-native-jwt";
4
+
5
+ import { Issuing } from "./issuing";
6
+ export { Issuing };
7
+ /**
8
+ * Decode a given JWT to get the parsed Wallet Instance Attestation object they define.
9
+ * It ensures provided data is in a valid shape.
10
+ *
11
+ * It DOES NOT verify token signature nor check disclosures are correctly referenced by the JWT.
12
+ * Use {@link verify} instead
13
+ *
14
+ * @function
15
+ * @param token The encoded token that represents a valid jwt for Wallet Instance Attestation
16
+ *
17
+ * @returns The validated Wallet Instance Attestation object
18
+ * @throws A decoding error if the token doesn't resolve in a valid JWT
19
+ * @throws A validation error if the provided data doesn't result in a valid Wallet Instance Attestation
20
+ *
21
+ */
22
+ export function decode(token: string): WalletInstanceAttestationJwt {
23
+ // decode JWT parts
24
+ const decodedJwt = decodeJwt(token);
25
+ // parse JWT to ensure it has the shape of a WalletInstanceAttestationJwt
26
+ return WalletInstanceAttestationJwt.parse({
27
+ header: decodedJwt.protectedHeader,
28
+ payload: decodedJwt.payload,
29
+ });
30
+ }
31
+
32
+ /**
33
+ * Verify a given JWT to get the parsed Wallet Instance Attestation object they define.
34
+ * Same as {@link decode} plus token signature verification
35
+ *
36
+ * @async @function
37
+ *
38
+ *
39
+ * @param token The encoded token that represents a valid jwt
40
+ *
41
+ * @returns {WalletInstanceAttestationJwt} The validated Wallet Instance Attestation object
42
+ * @throws A decoding error if the token doesn't resolve in a valid JWT
43
+ * @throws A validation error if the provided data doesn't result in a valid Wallet Instance Attestation
44
+ * @throws Invalid signature error if the token signature is not valid
45
+ *
46
+ */
47
+ export async function verify(
48
+ token: string
49
+ ): Promise<WalletInstanceAttestationJwt> {
50
+ const decoded = decode(token);
51
+ const pubKey = decoded.payload.cnf.jwk;
52
+
53
+ await verifyJwt(token, pubKey);
54
+
55
+ return decoded;
56
+ }
@@ -0,0 +1,107 @@
1
+ import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
2
+ import { verify as verifyJwt } from "@pagopa/io-react-native-jwt";
3
+ import { SignJWT, thumbprint } from "@pagopa/io-react-native-jwt";
4
+ import { JWK } from "../utils/jwk";
5
+ import { WalletInstanceAttestationRequestJwt } from "./types";
6
+ import uuid from "react-native-uuid";
7
+ import { WalletInstanceAttestationIssuingError } from "../utils/errors";
8
+
9
+ export class Issuing {
10
+ walletProviderBaseUrl: string;
11
+
12
+ constructor(walletProviderBaseUrl: string) {
13
+ this.walletProviderBaseUrl = walletProviderBaseUrl;
14
+ }
15
+
16
+ /**
17
+ * Get the Wallet Instance Attestation Request to sign
18
+ *
19
+ * @async @function
20
+ *
21
+ * @param jwk Public key of the wallet instance
22
+ *
23
+ * @returns {string} Wallet Instance Attestation Request to sign
24
+ *
25
+ */
26
+ async getAttestationRequestToSign(jwk: JWK): Promise<string> {
27
+ const parsedJwk = JWK.parse(jwk);
28
+ const keyThumbprint = await thumbprint(parsedJwk);
29
+ const publicKey = { ...parsedJwk, kid: keyThumbprint };
30
+
31
+ const walletInstanceAttestationRequest = new SignJWT({
32
+ iss: keyThumbprint,
33
+ sub: this.walletProviderBaseUrl,
34
+ jti: `${uuid.v4()}`,
35
+ type: "WalletInstanceAttestationRequest",
36
+ cnf: {
37
+ jwk: publicKey,
38
+ },
39
+ })
40
+ .setProtectedHeader({
41
+ alg: "ES256",
42
+ kid: publicKey.kid,
43
+ typ: "var+jwt",
44
+ })
45
+ .setIssuedAt()
46
+ .setExpirationTime("1h")
47
+ .toSign();
48
+
49
+ return walletInstanceAttestationRequest;
50
+ }
51
+
52
+ /**
53
+ * Get the Wallet Instance Attestation given a
54
+ * Wallet Instance Attestation Request and signature
55
+ *
56
+ * @async @function
57
+ *
58
+ * @param attestationRequest Wallet Instance Attestaion Request
59
+ * obtained with {@link getAttestationRequestToSign}
60
+ * @param signature Signature of the Wallet Instance Attestaion Request
61
+ * @param appFetch Optional object with fetch function to use
62
+ *
63
+ * @returns {string} Wallet Instance Attestation
64
+ *
65
+ */
66
+ async getAttestation(
67
+ attestationRequest: string,
68
+ signature: string,
69
+ appFetch: GlobalFetch = { fetch }
70
+ ): Promise<String> {
71
+ const signedAttestationRequest = await SignJWT.appendSignature(
72
+ attestationRequest,
73
+ signature
74
+ );
75
+ const decodedRequest = decodeJwt(signedAttestationRequest);
76
+ const parsedRequest = WalletInstanceAttestationRequestJwt.parse({
77
+ payload: decodedRequest.payload,
78
+ header: decodedRequest.protectedHeader,
79
+ });
80
+ const publicKey = parsedRequest.payload.cnf.jwk;
81
+
82
+ await verifyJwt(signedAttestationRequest, publicKey);
83
+
84
+ const tokenUrl = new URL("token", this.walletProviderBaseUrl).href;
85
+ const requestBody = {
86
+ grant_type:
87
+ "urn:ietf:params:oauth:client-assertion-type:jwt-key-attestation",
88
+ assertion: signedAttestationRequest,
89
+ };
90
+ const response = await appFetch.fetch(tokenUrl, {
91
+ method: "POST",
92
+ headers: {
93
+ "Content-Type": "application/json",
94
+ },
95
+ body: JSON.stringify(requestBody),
96
+ });
97
+
98
+ if (response.status === 201) {
99
+ return await response.text();
100
+ }
101
+
102
+ throw new WalletInstanceAttestationIssuingError(
103
+ "Unable to obtain wallet instance attestation from wallet provider",
104
+ `Response code: ${response.status}`
105
+ );
106
+ }
107
+ }
@@ -0,0 +1,77 @@
1
+ import { JWK } from "../utils/jwk";
2
+ import * as z from "zod";
3
+
4
+ const UnixTime = z.number().min(0).max(2147483647000);
5
+ type UnixTime = z.infer<typeof UnixTime>;
6
+
7
+ const Jwt = z.object({
8
+ header: z.object({
9
+ alg: z.string(),
10
+ kid: z.string(),
11
+ typ: z.string(),
12
+ x5c: z.array(z.string()).optional(),
13
+ trust_chain: z.array(z.string()).optional(),
14
+ }),
15
+ payload: z.object({
16
+ iss: z.string(),
17
+ sub: z.string(),
18
+ iat: UnixTime,
19
+ exp: UnixTime,
20
+ cnf: z.object({
21
+ jwk: JWK,
22
+ }),
23
+ }),
24
+ });
25
+
26
+ export type WalletInstanceAttestationRequestJwt = z.infer<
27
+ typeof WalletInstanceAttestationRequestJwt
28
+ >;
29
+ export const WalletInstanceAttestationRequestJwt = z.object({
30
+ header: z.intersection(
31
+ Jwt.shape.header,
32
+ z.object({
33
+ typ: z.literal("var+jwt"),
34
+ })
35
+ ),
36
+ payload: z.intersection(
37
+ Jwt.shape.payload,
38
+ z.object({
39
+ jti: z.string(),
40
+ type: z.literal("WalletInstanceAttestationRequest"),
41
+ })
42
+ ),
43
+ });
44
+
45
+ export type WalletInstanceAttestationJwt = z.infer<
46
+ typeof WalletInstanceAttestationJwt
47
+ >;
48
+ export const WalletInstanceAttestationJwt = z.object({
49
+ header: z.intersection(
50
+ Jwt.shape.header,
51
+ z.object({
52
+ typ: z.literal("va+jwt"),
53
+ })
54
+ ),
55
+ payload: z.intersection(
56
+ Jwt.shape.payload,
57
+ z.object({
58
+ type: z.literal("WalletInstanceAttestation"),
59
+ policy_uri: z.string().url(),
60
+ tos_uri: z.string().url(),
61
+ logo_uri: z.string().url(),
62
+ asc: z.string(),
63
+ authorization_endpoint: z.string().url(),
64
+ response_types_supported: z.array(z.string()),
65
+ vp_formats_supported: z.object({
66
+ jwt_vp_json: z.object({
67
+ alg_values_supported: z.array(z.string()),
68
+ }),
69
+ jwt_vc_json: z.object({
70
+ alg_values_supported: z.array(z.string()),
71
+ }),
72
+ }),
73
+ request_object_signing_alg_values_supported: z.array(z.string()),
74
+ presentation_definition_uri_supported: z.boolean(),
75
+ })
76
+ ),
77
+ });