@pagopa/io-react-native-wallet 2.0.0-next.4 → 2.0.0-next.6
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.
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +3 -3
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/commonjs/credential/status/{02-status-attestation.js → 02-status-assertion.js} +28 -22
- package/lib/commonjs/credential/status/02-status-assertion.js.map +1 -0
- package/lib/commonjs/credential/status/03-verify-and-parse-status-assertion.js +85 -0
- package/lib/commonjs/credential/status/03-verify-and-parse-status-assertion.js.map +1 -0
- package/lib/commonjs/credential/status/README.md +22 -20
- package/lib/commonjs/credential/status/index.js +6 -6
- package/lib/commonjs/credential/status/index.js.map +1 -1
- package/lib/commonjs/credential/status/types.js +48 -15
- package/lib/commonjs/credential/status/types.js.map +1 -1
- package/lib/commonjs/trust/types.js +2 -1
- package/lib/commonjs/trust/types.js.map +1 -1
- package/lib/commonjs/utils/credentials.js +33 -0
- package/lib/commonjs/utils/credentials.js.map +1 -0
- package/lib/commonjs/utils/crypto.js +1 -7
- package/lib/commonjs/utils/crypto.js.map +1 -1
- package/lib/commonjs/utils/jwk.js +12 -0
- package/lib/commonjs/utils/jwk.js.map +1 -1
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js +4 -4
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/module/credential/status/{02-status-attestation.js → 02-status-assertion.js} +28 -22
- package/lib/module/credential/status/02-status-assertion.js.map +1 -0
- package/lib/module/credential/status/03-verify-and-parse-status-assertion.js +78 -0
- package/lib/module/credential/status/03-verify-and-parse-status-assertion.js.map +1 -0
- package/lib/module/credential/status/README.md +22 -20
- package/lib/module/credential/status/index.js +3 -3
- package/lib/module/credential/status/index.js.map +1 -1
- package/lib/module/credential/status/types.js +43 -12
- package/lib/module/credential/status/types.js.map +1 -1
- package/lib/module/trust/types.js +2 -1
- package/lib/module/trust/types.js.map +1 -1
- package/lib/module/utils/credentials.js +26 -0
- package/lib/module/utils/credentials.js.map +1 -0
- package/lib/module/utils/crypto.js +2 -8
- package/lib/module/utils/crypto.js.map +1 -1
- package/lib/module/utils/jwk.js +11 -1
- package/lib/module/utils/jwk.js.map +1 -1
- package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
- package/lib/typescript/credential/status/02-status-assertion.d.ts +23 -0
- package/lib/typescript/credential/status/02-status-assertion.d.ts.map +1 -0
- package/lib/typescript/credential/status/03-verify-and-parse-status-assertion.d.ts +21 -0
- package/lib/typescript/credential/status/03-verify-and-parse-status-assertion.d.ts.map +1 -0
- package/lib/typescript/credential/status/index.d.ts +4 -4
- package/lib/typescript/credential/status/index.d.ts.map +1 -1
- package/lib/typescript/credential/status/types.d.ts +495 -18
- package/lib/typescript/credential/status/types.d.ts.map +1 -1
- package/lib/typescript/trust/build-chain.d.ts +2 -2
- package/lib/typescript/trust/types.d.ts +26 -26
- package/lib/typescript/utils/credentials.d.ts +11 -0
- package/lib/typescript/utils/credentials.d.ts.map +1 -0
- package/lib/typescript/utils/crypto.d.ts.map +1 -1
- package/lib/typescript/utils/jwk.d.ts +7 -0
- package/lib/typescript/utils/jwk.d.ts.map +1 -1
- package/package.json +6 -8
- package/src/credential/issuance/07-verify-and-parse-credential.ts +4 -6
- package/src/credential/status/{02-status-attestation.ts → 02-status-assertion.ts} +37 -28
- package/src/credential/status/03-verify-and-parse-status-assertion.ts +109 -0
- package/src/credential/status/README.md +22 -20
- package/src/credential/status/index.ts +7 -14
- package/src/credential/status/types.ts +62 -15
- package/src/trust/types.ts +1 -1
- package/src/utils/credentials.ts +29 -0
- package/src/utils/crypto.ts +12 -20
- package/src/utils/jwk.ts +15 -1
- package/lib/commonjs/credential/status/02-status-attestation.js.map +0 -1
- package/lib/commonjs/credential/status/03-verify-and-parse-status-attestation.js +0 -55
- package/lib/commonjs/credential/status/03-verify-and-parse-status-attestation.js.map +0 -1
- package/lib/module/credential/status/02-status-attestation.js.map +0 -1
- package/lib/module/credential/status/03-verify-and-parse-status-attestation.js +0 -49
- package/lib/module/credential/status/03-verify-and-parse-status-attestation.js.map +0 -1
- package/lib/typescript/credential/status/02-status-attestation.d.ts +0 -19
- package/lib/typescript/credential/status/02-status-attestation.d.ts.map +0 -1
- package/lib/typescript/credential/status/03-verify-and-parse-status-attestation.d.ts +0 -24
- package/lib/typescript/credential/status/03-verify-and-parse-status-attestation.d.ts.map +0 -1
- package/src/credential/status/03-verify-and-parse-status-attestation.ts +0 -70
@@ -2351,7 +2351,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2351
2351
|
locale: string;
|
2352
2352
|
}>, "many">;
|
2353
2353
|
claims: z.ZodArray<z.ZodObject<{
|
2354
|
-
path: z.ZodArray<z.ZodString, "many">;
|
2354
|
+
path: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodNull]>, "many">;
|
2355
2355
|
display: z.ZodArray<z.ZodObject<{
|
2356
2356
|
name: z.ZodString;
|
2357
2357
|
locale: z.ZodString;
|
@@ -2363,13 +2363,13 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2363
2363
|
locale: string;
|
2364
2364
|
}>, "many">;
|
2365
2365
|
}, "strip", z.ZodTypeAny, {
|
2366
|
-
path: string[];
|
2366
|
+
path: (string | number | null)[];
|
2367
2367
|
display: {
|
2368
2368
|
name: string;
|
2369
2369
|
locale: string;
|
2370
2370
|
}[];
|
2371
2371
|
}, {
|
2372
|
-
path: string[];
|
2372
|
+
path: (string | number | null)[];
|
2373
2373
|
display: {
|
2374
2374
|
name: string;
|
2375
2375
|
locale: string;
|
@@ -2412,7 +2412,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2412
2412
|
locale: string;
|
2413
2413
|
}[];
|
2414
2414
|
claims: {
|
2415
|
-
path: string[];
|
2415
|
+
path: (string | number | null)[];
|
2416
2416
|
display: {
|
2417
2417
|
name: string;
|
2418
2418
|
locale: string;
|
@@ -2435,7 +2435,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2435
2435
|
locale: string;
|
2436
2436
|
}[];
|
2437
2437
|
claims: {
|
2438
|
-
path: string[];
|
2438
|
+
path: (string | number | null)[];
|
2439
2439
|
display: {
|
2440
2440
|
name: string;
|
2441
2441
|
locale: string;
|
@@ -2624,7 +2624,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2624
2624
|
locale: string;
|
2625
2625
|
}[];
|
2626
2626
|
claims: {
|
2627
|
-
path: string[];
|
2627
|
+
path: (string | number | null)[];
|
2628
2628
|
display: {
|
2629
2629
|
name: string;
|
2630
2630
|
locale: string;
|
@@ -2692,7 +2692,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
2692
2692
|
locale: string;
|
2693
2693
|
}[];
|
2694
2694
|
claims: {
|
2695
|
-
path: string[];
|
2695
|
+
path: (string | number | null)[];
|
2696
2696
|
display: {
|
2697
2697
|
name: string;
|
2698
2698
|
locale: string;
|
@@ -3476,7 +3476,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
3476
3476
|
locale: string;
|
3477
3477
|
}[];
|
3478
3478
|
claims: {
|
3479
|
-
path: string[];
|
3479
|
+
path: (string | number | null)[];
|
3480
3480
|
display: {
|
3481
3481
|
name: string;
|
3482
3482
|
locale: string;
|
@@ -3660,7 +3660,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
3660
3660
|
locale: string;
|
3661
3661
|
}[];
|
3662
3662
|
claims: {
|
3663
|
-
path: string[];
|
3663
|
+
path: (string | number | null)[];
|
3664
3664
|
display: {
|
3665
3665
|
name: string;
|
3666
3666
|
locale: string;
|
@@ -3872,7 +3872,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
3872
3872
|
locale: string;
|
3873
3873
|
}[];
|
3874
3874
|
claims: {
|
3875
|
-
path: string[];
|
3875
|
+
path: (string | number | null)[];
|
3876
3876
|
display: {
|
3877
3877
|
name: string;
|
3878
3878
|
locale: string;
|
@@ -4084,7 +4084,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
4084
4084
|
locale: string;
|
4085
4085
|
}[];
|
4086
4086
|
claims: {
|
4087
|
-
path: string[];
|
4087
|
+
path: (string | number | null)[];
|
4088
4088
|
display: {
|
4089
4089
|
name: string;
|
4090
4090
|
locale: string;
|
@@ -4298,7 +4298,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
4298
4298
|
locale: string;
|
4299
4299
|
}[];
|
4300
4300
|
claims: {
|
4301
|
-
path: string[];
|
4301
|
+
path: (string | number | null)[];
|
4302
4302
|
display: {
|
4303
4303
|
name: string;
|
4304
4304
|
locale: string;
|
@@ -4512,7 +4512,7 @@ export declare const CredentialIssuerEntityConfiguration: z.ZodIntersection<z.Zo
|
|
4512
4512
|
locale: string;
|
4513
4513
|
}[];
|
4514
4514
|
claims: {
|
4515
|
-
path: string[];
|
4515
|
+
path: (string | number | null)[];
|
4516
4516
|
display: {
|
4517
4517
|
name: string;
|
4518
4518
|
locale: string;
|
@@ -10705,7 +10705,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
10705
10705
|
locale: string;
|
10706
10706
|
}>, "many">;
|
10707
10707
|
claims: z.ZodArray<z.ZodObject<{
|
10708
|
-
path: z.ZodArray<z.ZodString, "many">;
|
10708
|
+
path: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodNull]>, "many">;
|
10709
10709
|
display: z.ZodArray<z.ZodObject<{
|
10710
10710
|
name: z.ZodString;
|
10711
10711
|
locale: z.ZodString;
|
@@ -10717,13 +10717,13 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
10717
10717
|
locale: string;
|
10718
10718
|
}>, "many">;
|
10719
10719
|
}, "strip", z.ZodTypeAny, {
|
10720
|
-
path: string[];
|
10720
|
+
path: (string | number | null)[];
|
10721
10721
|
display: {
|
10722
10722
|
name: string;
|
10723
10723
|
locale: string;
|
10724
10724
|
}[];
|
10725
10725
|
}, {
|
10726
|
-
path: string[];
|
10726
|
+
path: (string | number | null)[];
|
10727
10727
|
display: {
|
10728
10728
|
name: string;
|
10729
10729
|
locale: string;
|
@@ -10766,7 +10766,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
10766
10766
|
locale: string;
|
10767
10767
|
}[];
|
10768
10768
|
claims: {
|
10769
|
-
path: string[];
|
10769
|
+
path: (string | number | null)[];
|
10770
10770
|
display: {
|
10771
10771
|
name: string;
|
10772
10772
|
locale: string;
|
@@ -10789,7 +10789,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
10789
10789
|
locale: string;
|
10790
10790
|
}[];
|
10791
10791
|
claims: {
|
10792
|
-
path: string[];
|
10792
|
+
path: (string | number | null)[];
|
10793
10793
|
display: {
|
10794
10794
|
name: string;
|
10795
10795
|
locale: string;
|
@@ -10978,7 +10978,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
10978
10978
|
locale: string;
|
10979
10979
|
}[];
|
10980
10980
|
claims: {
|
10981
|
-
path: string[];
|
10981
|
+
path: (string | number | null)[];
|
10982
10982
|
display: {
|
10983
10983
|
name: string;
|
10984
10984
|
locale: string;
|
@@ -11046,7 +11046,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
11046
11046
|
locale: string;
|
11047
11047
|
}[];
|
11048
11048
|
claims: {
|
11049
|
-
path: string[];
|
11049
|
+
path: (string | number | null)[];
|
11050
11050
|
display: {
|
11051
11051
|
name: string;
|
11052
11052
|
locale: string;
|
@@ -11830,7 +11830,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
11830
11830
|
locale: string;
|
11831
11831
|
}[];
|
11832
11832
|
claims: {
|
11833
|
-
path: string[];
|
11833
|
+
path: (string | number | null)[];
|
11834
11834
|
display: {
|
11835
11835
|
name: string;
|
11836
11836
|
locale: string;
|
@@ -12014,7 +12014,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
12014
12014
|
locale: string;
|
12015
12015
|
}[];
|
12016
12016
|
claims: {
|
12017
|
-
path: string[];
|
12017
|
+
path: (string | number | null)[];
|
12018
12018
|
display: {
|
12019
12019
|
name: string;
|
12020
12020
|
locale: string;
|
@@ -12226,7 +12226,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
12226
12226
|
locale: string;
|
12227
12227
|
}[];
|
12228
12228
|
claims: {
|
12229
|
-
path: string[];
|
12229
|
+
path: (string | number | null)[];
|
12230
12230
|
display: {
|
12231
12231
|
name: string;
|
12232
12232
|
locale: string;
|
@@ -12438,7 +12438,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
12438
12438
|
locale: string;
|
12439
12439
|
}[];
|
12440
12440
|
claims: {
|
12441
|
-
path: string[];
|
12441
|
+
path: (string | number | null)[];
|
12442
12442
|
display: {
|
12443
12443
|
name: string;
|
12444
12444
|
locale: string;
|
@@ -12652,7 +12652,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
12652
12652
|
locale: string;
|
12653
12653
|
}[];
|
12654
12654
|
claims: {
|
12655
|
-
path: string[];
|
12655
|
+
path: (string | number | null)[];
|
12656
12656
|
display: {
|
12657
12657
|
name: string;
|
12658
12658
|
locale: string;
|
@@ -12866,7 +12866,7 @@ export declare const EntityConfiguration: z.ZodUnion<[z.ZodIntersection<z.ZodObj
|
|
12866
12866
|
locale: string;
|
12867
12867
|
}[];
|
12868
12868
|
claims: {
|
12869
|
-
path: string[];
|
12869
|
+
path: (string | number | null)[];
|
12870
12870
|
display: {
|
12871
12871
|
name: string;
|
12872
12872
|
locale: string;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type { Out } from "./misc";
|
2
|
+
import type { ObtainCredential } from "../credential/issuance";
|
3
|
+
import type { JWK } from "./jwk";
|
4
|
+
/**
|
5
|
+
* Extracts a JWK from a credential.
|
6
|
+
* @param credential - The credential string, which can be in SD-JWT or CBOR format.
|
7
|
+
* @param format - The format of the credential
|
8
|
+
* @return A Promise that resolves to a JWK object if the credential is in SD-JWT format and contains a JWK, or undefined otherwise.
|
9
|
+
*/
|
10
|
+
export declare const extractJwkFromCredential: (credential: Out<ObtainCredential>["credential"], format: Out<ObtainCredential>["format"]) => Promise<JWK>;
|
11
|
+
//# sourceMappingURL=credentials.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/utils/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,eACvB,IAAI,gBAAgB,CAAC,CAAC,YAAY,CAAC,UACvC,IAAI,gBAAgB,CAAC,CAAC,QAAQ,CAAC,KACtC,QAAQ,GAAG,CAUb,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/utils/crypto.ts"],"names":[],"mappings":"AAOA,OAAO,
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/utils/crypto.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,KAAG,aAsBvD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,6BACJ,aAAa,8BAOrC,CAAC"}
|
@@ -228,4 +228,11 @@ export declare const JWKS: z.ZodObject<{
|
|
228
228
|
}[];
|
229
229
|
}>;
|
230
230
|
export type JWTDecodeResult = ReturnType<typeof decode>;
|
231
|
+
/**
|
232
|
+
* Utility function that checks if two JWKs have the same thumbprint.
|
233
|
+
* @param jwkA The first JWK
|
234
|
+
* @param jwkB The second JWK
|
235
|
+
* @returns Whether the thumbprints match
|
236
|
+
*/
|
237
|
+
export declare const isSameThumbprint: (jwkA: JWK, jwkB: JWK) => Promise<boolean>;
|
231
238
|
//# sourceMappingURL=jwk.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"jwk.d.ts","sourceRoot":"","sources":["../../../src/utils/jwk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,
|
1
|
+
{"version":3,"file":"jwk.d.ts","sourceRoot":"","sources":["../../../src/utils/jwk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA6B,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;AACtC,eAAO,MAAM,GAAG;IACd,uCAAuC;;;;;;;IAOvC,yCAAyC;;;IAGzC,gDAAgD;;IAEhD,oCAAoC;;IAEpC;;kCAE8B;;;;;;IAM9B,4CAA4C;;;;IAI5C,qDAAqD;;IAErD,gEAAgE;;IAEhE,mEAAmE;;IAEnE,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEvC,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAUpD;AAED,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AACxC,eAAO,MAAM,IAAI;;QAzDf,uCAAuC;;;;;;;QAOvC,yCAAyC;;;QAGzC,gDAAgD;;QAEhD,oCAAoC;;QAEpC;;sCAE8B;;;;;;QAM9B,4CAA4C;;;;QAI5C,qDAAqD;;QAErD,gEAAgE;;QAEhE,mEAAmE;;QAEnE,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BvC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,SAAgB,GAAG,QAAQ,GAAG,qBAM1D,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@pagopa/io-react-native-wallet",
|
3
|
-
"version": "2.0.0-next.
|
3
|
+
"version": "2.0.0-next.6",
|
4
4
|
"description": "Provide data structures, helpers and API for IO Wallet",
|
5
5
|
"main": "lib/commonjs/index",
|
6
6
|
"module": "lib/module/index",
|
@@ -55,10 +55,11 @@
|
|
55
55
|
"devDependencies": {
|
56
56
|
"@pagopa/io-react-native-crypto": "^1.2.2",
|
57
57
|
"@pagopa/io-react-native-jwt": "^2.1.0",
|
58
|
+
"@react-native/babel-preset": "0.78.3",
|
58
59
|
"@react-native/eslint-config": "^0.75.5",
|
59
60
|
"@rushstack/eslint-patch": "^1.3.2",
|
60
|
-
"@types/jest": "^
|
61
|
-
"@types/react": "^
|
61
|
+
"@types/jest": "^29.5.13",
|
62
|
+
"@types/react": "^19.0.0",
|
62
63
|
"@types/react-native": "0.70.0",
|
63
64
|
"@types/url-parse": "^1.4.11",
|
64
65
|
"del-cli": "^5.0.0",
|
@@ -67,15 +68,12 @@
|
|
67
68
|
"jest": "^28.1.1",
|
68
69
|
"pod-install": "^0.1.0",
|
69
70
|
"prettier": "^3.5.3",
|
70
|
-
"react": "
|
71
|
-
"react-native": "0.
|
71
|
+
"react": "19.0.0",
|
72
|
+
"react-native": "0.78.3",
|
72
73
|
"react-native-builder-bob": "^0.20.0",
|
73
74
|
"typed-openapi": "^0.4.1",
|
74
75
|
"typescript": "5.0.4"
|
75
76
|
},
|
76
|
-
"resolutions": {
|
77
|
-
"@types/react": "^18.2.6"
|
78
|
-
},
|
79
77
|
"peerDependencies": {
|
80
78
|
"@pagopa/io-react-native-crypto": "*",
|
81
79
|
"@pagopa/io-react-native-jwt": "*",
|
@@ -2,12 +2,11 @@ import type { CryptoContext } from "@pagopa/io-react-native-jwt";
|
|
2
2
|
import type { Out } from "../../utils/misc";
|
3
3
|
import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
|
4
4
|
import { IoWalletError } from "../../utils/errors";
|
5
|
-
import { SdJwt4VC } from "../../sd-jwt
|
6
|
-
import { verify as verifySdJwt } from "../../sd-jwt";
|
5
|
+
import { SdJwt4VC, verify as verifySdJwt } from "../../sd-jwt";
|
7
6
|
import { getValueFromDisclosures } from "../../sd-jwt/converters";
|
8
|
-
import type
|
7
|
+
import { isSameThumbprint, type JWK } from "../../utils/jwk";
|
9
8
|
import type { ObtainCredential } from "./06-obtain-credential";
|
10
|
-
import {
|
9
|
+
import { Logger, LogLevel } from "../../utils/logging";
|
11
10
|
|
12
11
|
type IssuerConf = Out<EvaluateIssuerTrust>["issuerConf"];
|
13
12
|
type CredentialConf =
|
@@ -169,8 +168,7 @@ async function verifyCredentialSdJwt(
|
|
169
168
|
]);
|
170
169
|
|
171
170
|
const { cnf } = decodedCredential.sdJwt.payload;
|
172
|
-
|
173
|
-
if (!cnf.jwk.kid || cnf.jwk.kid !== holderBindingKey.kid) {
|
171
|
+
if (!(await isSameThumbprint(cnf.jwk, holderBindingKey as JWK))) {
|
174
172
|
const message = `Failed to verify holder binding, expected kid: ${holderBindingKey.kid}, got: ${decodedCredential.sdJwt.payload.cnf.jwk.kid}`;
|
175
173
|
Logger.log(LogLevel.ERROR, message);
|
176
174
|
throw new IoWalletError(message);
|
@@ -6,54 +6,65 @@ import {
|
|
6
6
|
import type { EvaluateIssuerTrust, ObtainCredential } from "../issuance";
|
7
7
|
import { type CryptoContext, SignJWT } from "@pagopa/io-react-native-jwt";
|
8
8
|
import { v4 as uuidv4 } from "uuid";
|
9
|
-
import {
|
9
|
+
import { StatusAssertionResponse } from "./types";
|
10
10
|
import {
|
11
11
|
IssuerResponseError,
|
12
12
|
IssuerResponseErrorCodes,
|
13
13
|
ResponseErrorBuilder,
|
14
14
|
UnexpectedStatusCodeError,
|
15
15
|
} from "../../utils/errors";
|
16
|
-
import {
|
16
|
+
import { Logger, LogLevel } from "../../utils/logging";
|
17
|
+
import { extractJwkFromCredential } from "../../utils/credentials";
|
17
18
|
|
18
|
-
export type
|
19
|
+
export type StatusAssertion = (
|
19
20
|
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
|
20
21
|
credential: Out<ObtainCredential>["credential"],
|
21
|
-
|
22
|
-
|
22
|
+
format: Out<ObtainCredential>["format"],
|
23
|
+
context: {
|
24
|
+
credentialCryptoContext: CryptoContext;
|
25
|
+
wiaCryptoContext: CryptoContext;
|
26
|
+
appFetch?: GlobalFetch["fetch"];
|
27
|
+
}
|
23
28
|
) => Promise<{
|
24
|
-
|
29
|
+
statusAssertion: string;
|
25
30
|
}>;
|
26
31
|
|
27
32
|
/**
|
28
|
-
*
|
29
|
-
* Verify the status of the credential attestation.
|
33
|
+
* Get the status assertion of a digital credential.
|
30
34
|
* @param issuerConf - The issuer's configuration
|
31
35
|
* @param credential - The credential to be verified
|
32
|
-
* @param
|
36
|
+
* @param format - The format of the credential, e.g. "sd-jwt"
|
37
|
+
* @param context.credentialCryptoContext - The credential's crypto context
|
38
|
+
* @param context.wiaCryptoContext - The Wallet Attestation's crypto context
|
33
39
|
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
34
40
|
* @throws {IssuerResponseError} with a specific code for more context
|
35
|
-
* @returns The credential status
|
41
|
+
* @returns The credential status assertion
|
36
42
|
*/
|
37
|
-
export const
|
43
|
+
export const statusAssertion: StatusAssertion = async (
|
38
44
|
issuerConf,
|
39
45
|
credential,
|
40
|
-
|
41
|
-
|
46
|
+
format,
|
47
|
+
ctx
|
42
48
|
) => {
|
43
|
-
const
|
49
|
+
const { credentialCryptoContext, wiaCryptoContext, appFetch = fetch } = ctx;
|
50
|
+
|
51
|
+
const jwk = await extractJwkFromCredential(credential, format);
|
52
|
+
const issuerJwk = await wiaCryptoContext.getPublicKey();
|
44
53
|
const credentialHash = await getCredentialHashWithouDiscloures(credential);
|
45
54
|
const statusAttUrl =
|
46
55
|
issuerConf.openid_credential_issuer.status_attestation_endpoint;
|
56
|
+
|
47
57
|
const credentialPop = await new SignJWT(credentialCryptoContext)
|
48
58
|
.setPayload({
|
59
|
+
iss: issuerJwk.kid,
|
49
60
|
aud: statusAttUrl,
|
50
61
|
jti: uuidv4().toString(),
|
51
62
|
credential_hash: credentialHash,
|
52
|
-
credential_hash_alg: "
|
63
|
+
credential_hash_alg: "sha-256",
|
53
64
|
})
|
54
65
|
.setProtectedHeader({
|
55
66
|
alg: "ES256",
|
56
|
-
typ: "status-
|
67
|
+
typ: "status-assertion-request+jwt",
|
57
68
|
kid: jwk.kid,
|
58
69
|
})
|
59
70
|
.setIssuedAt()
|
@@ -61,7 +72,7 @@ export const statusAttestation: StatusAttestation = async (
|
|
61
72
|
.sign();
|
62
73
|
|
63
74
|
const body = {
|
64
|
-
|
75
|
+
status_assertion_requests: [credentialPop],
|
65
76
|
};
|
66
77
|
|
67
78
|
Logger.log(LogLevel.DEBUG, `Credential pop: ${credentialPop}`);
|
@@ -73,33 +84,31 @@ export const statusAttestation: StatusAttestation = async (
|
|
73
84
|
},
|
74
85
|
body: JSON.stringify(body),
|
75
86
|
})
|
76
|
-
.then(hasStatusOrThrow(
|
87
|
+
.then(hasStatusOrThrow(200))
|
77
88
|
.then((raw) => raw.json())
|
78
|
-
.then((json) =>
|
79
|
-
.catch(
|
89
|
+
.then((json) => StatusAssertionResponse.parse(json))
|
90
|
+
.catch(handleStatusAssertionError);
|
80
91
|
|
81
|
-
|
92
|
+
const [statusAttestationJwt] = result.status_assertion_responses;
|
93
|
+
|
94
|
+
return { statusAssertion: statusAttestationJwt! };
|
82
95
|
};
|
83
96
|
|
84
97
|
/**
|
85
|
-
* Handle the status
|
98
|
+
* Handle the status assertion error by mapping it to a custom exception.
|
86
99
|
* If the error is not an instance of {@link UnexpectedStatusCodeError}, it is thrown as is.
|
87
100
|
* @param e - The error to be handled
|
88
101
|
* @throws {IssuerResponseError} with a specific code for more context
|
89
102
|
*/
|
90
|
-
const
|
103
|
+
const handleStatusAssertionError = (e: unknown) => {
|
91
104
|
if (!(e instanceof UnexpectedStatusCodeError)) {
|
92
105
|
throw e;
|
93
106
|
}
|
94
107
|
|
95
108
|
throw new ResponseErrorBuilder(IssuerResponseError)
|
96
|
-
.handle(404, {
|
97
|
-
code: IssuerResponseErrorCodes.CredentialInvalidStatus,
|
98
|
-
message: "Invalid status found for the given credential",
|
99
|
-
})
|
100
109
|
.handle("*", {
|
101
110
|
code: IssuerResponseErrorCodes.StatusAttestationRequestFailed,
|
102
|
-
message: `Unable to obtain the status
|
111
|
+
message: `Unable to obtain the status assertion for the given credential`,
|
103
112
|
})
|
104
113
|
.buildFrom(e);
|
105
114
|
};
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import type { Out } from "../../utils/misc";
|
2
|
+
import {
|
3
|
+
IoWalletError,
|
4
|
+
IssuerResponseError,
|
5
|
+
IssuerResponseErrorCodes,
|
6
|
+
} from "../../utils/errors";
|
7
|
+
import { decode as decodeJwt, verify } from "@pagopa/io-react-native-jwt";
|
8
|
+
import type { EvaluateIssuerTrust, StatusAssertion } from ".";
|
9
|
+
import {
|
10
|
+
type InvalidStatusErrorReason,
|
11
|
+
ParsedStatusAssertion,
|
12
|
+
ParsedStatusAssertionError,
|
13
|
+
ParsedStatusAssertionResponse,
|
14
|
+
StatusType,
|
15
|
+
} from "./types";
|
16
|
+
import { Logger, LogLevel } from "../../utils/logging";
|
17
|
+
import type { ObtainCredential } from "../issuance";
|
18
|
+
import { extractJwkFromCredential } from "../../utils/credentials";
|
19
|
+
import { isSameThumbprint } from "../../utils/jwk";
|
20
|
+
|
21
|
+
export type VerifyAndParseStatusAssertion = (
|
22
|
+
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
|
23
|
+
statusAssertion: Out<StatusAssertion>,
|
24
|
+
credential: Out<ObtainCredential>["credential"],
|
25
|
+
format: Out<ObtainCredential>["format"]
|
26
|
+
) => Promise<{ parsedStatusAssertion: ParsedStatusAssertion }>;
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Given a status assertion, verifies that:
|
30
|
+
* - It's in the supported format;
|
31
|
+
* - The assertion is correctly signed;
|
32
|
+
* - It's bound to the given key.
|
33
|
+
* @param issuerConf The Issuer configuration returned by {@link evaluateIssuerTrust}
|
34
|
+
* @param statusAssertion The encoded status assertion returned by {@link statusAssertion}
|
35
|
+
* @param context.credentialCryptoContext The crypto context used to obtain the credential in {@link obtainCredential}
|
36
|
+
* @returns A parsed status assertion
|
37
|
+
* @throws {IoWalletError} If the credential signature is not verified with the Issuer key set
|
38
|
+
* @throws {IssuerResponseError} If the status assertion contains an error or the credential status is invalid
|
39
|
+
*/
|
40
|
+
export const verifyAndParseStatusAssertion: VerifyAndParseStatusAssertion =
|
41
|
+
async (issuerConf, rawStatusAssertion, credential, format) => {
|
42
|
+
const { statusAssertion } = rawStatusAssertion;
|
43
|
+
|
44
|
+
await verify(
|
45
|
+
statusAssertion,
|
46
|
+
issuerConf.openid_credential_issuer.jwks.keys
|
47
|
+
);
|
48
|
+
|
49
|
+
const decodedJwt = decodeJwt(statusAssertion);
|
50
|
+
const parsedStatusAssertion = ParsedStatusAssertionResponse.parse({
|
51
|
+
header: decodedJwt.protectedHeader,
|
52
|
+
payload: decodedJwt.payload,
|
53
|
+
});
|
54
|
+
|
55
|
+
Logger.log(
|
56
|
+
LogLevel.DEBUG,
|
57
|
+
`Parsed status assertion: ${JSON.stringify(parsedStatusAssertion)}`
|
58
|
+
);
|
59
|
+
|
60
|
+
// Errors are transmitted in the JWT and use a 200 HTTP status code
|
61
|
+
if (isStatusAssertionError(parsedStatusAssertion)) {
|
62
|
+
throw new IssuerResponseError({
|
63
|
+
code: IssuerResponseErrorCodes.CredentialInvalidStatus,
|
64
|
+
message: "The status assertion contains an error",
|
65
|
+
statusCode: 200,
|
66
|
+
reason: buildErrorReason(parsedStatusAssertion),
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
70
|
+
const { cnf, credential_status_type } = parsedStatusAssertion.payload;
|
71
|
+
const holderBindingKey = await extractJwkFromCredential(credential, format);
|
72
|
+
|
73
|
+
if (!(await isSameThumbprint(cnf.jwk, holderBindingKey))) {
|
74
|
+
const errorMessage = `Failed to verify holder binding for status assertion: the thumbprints of keys ${cnf.jwk.kid} and ${holderBindingKey.kid} do not match`;
|
75
|
+
Logger.log(LogLevel.ERROR, errorMessage);
|
76
|
+
throw new IoWalletError(errorMessage);
|
77
|
+
}
|
78
|
+
|
79
|
+
if (credential_status_type !== StatusType.VALID) {
|
80
|
+
throw new IssuerResponseError({
|
81
|
+
code: IssuerResponseErrorCodes.CredentialInvalidStatus,
|
82
|
+
message: "Invalid status found for the given credential",
|
83
|
+
statusCode: 200,
|
84
|
+
reason: buildErrorReason(parsedStatusAssertion),
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
88
|
+
return { parsedStatusAssertion };
|
89
|
+
};
|
90
|
+
|
91
|
+
const isStatusAssertionError = (
|
92
|
+
assertion: ParsedStatusAssertionResponse
|
93
|
+
): assertion is ParsedStatusAssertionError =>
|
94
|
+
assertion.header.typ === "status-assertion-error+jwt";
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Build an object containing the details on the error to use as the IssuerResponseError's reason
|
98
|
+
* @param assertion The status assertion response, both success or failure
|
99
|
+
* @returns The error's reason object
|
100
|
+
*/
|
101
|
+
const buildErrorReason = ({
|
102
|
+
payload,
|
103
|
+
}: ParsedStatusAssertionResponse): InvalidStatusErrorReason =>
|
104
|
+
"error" in payload
|
105
|
+
? payload
|
106
|
+
: {
|
107
|
+
error: payload.credential_status_detail!.state,
|
108
|
+
error_description: payload.credential_status_detail!.description,
|
109
|
+
};
|
@@ -1,16 +1,16 @@
|
|
1
|
-
# Credential Status
|
1
|
+
# Credential Status Assertion
|
2
2
|
|
3
|
-
This flow is used to obtain a credential status
|
4
|
-
The credential status
|
5
|
-
The status
|
3
|
+
This flow is used to obtain a credential status assertion from its credential issuer. Each step in the flow is imported from the related file which is named with a sequential number.
|
4
|
+
The credential status assertion is a JWT which contains the credential status which indicates if the credential is valid or not (see [OAuth Status Assertions](https://italia.github.io/eid-wallet-it-docs/versione-corrente/en/credential-revocation.html#oauth-status-assertions)).
|
5
|
+
The status assertion is supposed to be stored securely along with the credential. It has a limited lifetime and should be refreshed periodically according to the `exp` field in the JWT payload.
|
6
6
|
|
7
7
|
## Sequence Diagram
|
8
8
|
|
9
9
|
```mermaid
|
10
10
|
graph TD;
|
11
11
|
0[startFlow]
|
12
|
-
1[
|
13
|
-
2[
|
12
|
+
1[statusAssertion]
|
13
|
+
2[verifyAndParseStatusAssertion]
|
14
14
|
|
15
15
|
0 --> 1
|
16
16
|
1 --> 2
|
@@ -21,14 +21,14 @@ graph TD;
|
|
21
21
|
|
22
22
|
The following errors are mapped to a `IssuerResponseError` with specific codes.
|
23
23
|
|
24
|
-
|
|
25
|
-
|
26
|
-
|`
|
24
|
+
|Error Code|Description|
|
25
|
+
|----------|-----------|
|
26
|
+
|`ERR_CREDENTIAL_INVALID_STATUS`|This error is thrown when the status assertion for a given credential is invalid. It might contain more details in the `reason` property.|
|
27
27
|
|
28
28
|
## Example
|
29
29
|
|
30
30
|
<details>
|
31
|
-
<summary>Credential status
|
31
|
+
<summary>Credential status assertion flow</summary>
|
32
32
|
|
33
33
|
```ts
|
34
34
|
// Start the issuance flow
|
@@ -42,24 +42,26 @@ const { issuerUrl } = startFlow();
|
|
42
42
|
// Evaluate issuer trust
|
43
43
|
const { issuerConf } = await Credential.Status.evaluateIssuerTrust(issuerUrl);
|
44
44
|
|
45
|
-
// Get the credential
|
46
|
-
const res = await Credential.Status.
|
45
|
+
// Get the credential assertion
|
46
|
+
const res = await Credential.Status.statusAssertion(
|
47
47
|
issuerConf,
|
48
48
|
credential,
|
49
|
-
|
49
|
+
format,
|
50
|
+
{ credentialCryptoContext, wiaCryptoContext }
|
50
51
|
);
|
51
52
|
|
52
|
-
// Verify and parse the status
|
53
|
-
const {
|
54
|
-
await Credential.Status.
|
53
|
+
// Verify and parse the status assertion
|
54
|
+
const { parsedStatusAssertion } =
|
55
|
+
await Credential.Status.verifyAndParseStatusAssertion(
|
55
56
|
issuerConf,
|
56
|
-
res.
|
57
|
-
|
57
|
+
res.statusAssertion,
|
58
|
+
credential,
|
59
|
+
format
|
58
60
|
);
|
59
61
|
|
60
62
|
return {
|
61
|
-
|
62
|
-
|
63
|
+
statusAssertion: res.statusAssertion,
|
64
|
+
parsedStatusAssertion,
|
63
65
|
};
|
64
66
|
```
|
65
67
|
|