@pagopa/io-react-native-wallet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ });