@pagopa/io-wallet-oid4vci 1.2.0 → 1.3.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.
- package/dist/index.d.mts +56 -26
- package/dist/index.d.ts +56 -26
- package/dist/index.js +194 -133
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +144 -79
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -91,83 +91,80 @@ var import_io_wallet_utils = require("@pagopa/io-wallet-utils");
|
|
|
91
91
|
|
|
92
92
|
// src/errors.ts
|
|
93
93
|
var Oid4vciError = class extends Error {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
statusCode;
|
|
95
|
+
constructor(message, options) {
|
|
96
|
+
super(message, options);
|
|
97
97
|
this.name = "Oid4vciError";
|
|
98
|
+
this.statusCode = options?.statusCode;
|
|
98
99
|
}
|
|
99
100
|
};
|
|
100
101
|
var WalletProviderError = class extends Oid4vciError {
|
|
101
|
-
constructor(message,
|
|
102
|
-
super(message);
|
|
102
|
+
constructor(message, options) {
|
|
103
|
+
super(message, options);
|
|
103
104
|
this.name = "WalletProviderError";
|
|
104
|
-
this.cause = cause;
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
107
|
var NonceRequestError = class extends Error {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
statusCode;
|
|
109
|
+
constructor(message, options) {
|
|
110
|
+
super(message, options);
|
|
111
111
|
this.name = "NonceRequestError";
|
|
112
|
+
this.statusCode = options?.statusCode;
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
115
|
var FetchCredentialResponseError = class extends Oid4vciError {
|
|
115
|
-
constructor(message,
|
|
116
|
-
super(message);
|
|
116
|
+
constructor(message, options) {
|
|
117
|
+
super(message, options);
|
|
117
118
|
this.name = "FetchCredentialResponseError";
|
|
118
|
-
this.cause = cause;
|
|
119
119
|
}
|
|
120
120
|
};
|
|
121
121
|
var ParseCredentialRequestError = class extends Oid4vciError {
|
|
122
|
-
constructor(message,
|
|
123
|
-
super(message);
|
|
122
|
+
constructor(message, options) {
|
|
123
|
+
super(message, options);
|
|
124
124
|
this.name = "ParseCredentialRequestError";
|
|
125
|
-
this.cause = cause;
|
|
126
125
|
}
|
|
127
126
|
};
|
|
128
127
|
var FetchMetadataError = class extends Oid4vciError {
|
|
129
|
-
constructor(message,
|
|
130
|
-
super(message);
|
|
131
|
-
this.cause = cause;
|
|
128
|
+
constructor(message, options) {
|
|
129
|
+
super(message, options);
|
|
132
130
|
this.name = "FetchMetadataError";
|
|
133
131
|
}
|
|
134
132
|
};
|
|
135
133
|
var CreateCredentialResponseError = class extends Oid4vciError {
|
|
136
|
-
constructor(message,
|
|
137
|
-
super(message);
|
|
134
|
+
constructor(message, options) {
|
|
135
|
+
super(message, options);
|
|
138
136
|
this.name = "CreateCredentialResponseError";
|
|
139
|
-
this.cause = cause;
|
|
140
137
|
}
|
|
141
138
|
};
|
|
142
139
|
var VerifyCredentialRequestJwtProofError = class extends Oid4vciError {
|
|
143
|
-
constructor(message,
|
|
144
|
-
super(message);
|
|
140
|
+
constructor(message, options) {
|
|
141
|
+
super(message, options);
|
|
145
142
|
this.name = "VerifyCredentialRequestJwtProofError";
|
|
146
|
-
this.cause = cause;
|
|
147
143
|
}
|
|
148
144
|
};
|
|
149
145
|
var VerifyKeyAttestationJwtError = class extends Oid4vciError {
|
|
150
|
-
constructor(message,
|
|
151
|
-
super(message);
|
|
146
|
+
constructor(message, options) {
|
|
147
|
+
super(message, options);
|
|
152
148
|
this.name = "VerifyKeyAttestationJwtError";
|
|
153
|
-
this.cause = cause;
|
|
154
149
|
}
|
|
155
150
|
};
|
|
156
151
|
var CredentialOfferError = class extends Oid4vciError {
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
statusCode;
|
|
153
|
+
constructor(message, options) {
|
|
154
|
+
super(message, options);
|
|
159
155
|
this.name = "CredentialOfferError";
|
|
156
|
+
this.statusCode = options?.statusCode;
|
|
160
157
|
}
|
|
161
158
|
};
|
|
162
159
|
var MissingDpopProofError = class extends Oid4vciError {
|
|
163
|
-
constructor(message = "Credential request is missing required 'DPoP' proof header") {
|
|
164
|
-
super(message);
|
|
160
|
+
constructor(message = "Credential request is missing required 'DPoP' proof header", options) {
|
|
161
|
+
super(message, options);
|
|
165
162
|
this.name = "MissingDpopProofError";
|
|
166
163
|
}
|
|
167
164
|
};
|
|
168
165
|
var CredentialAuthorizationHeaderError = class extends Oid4vciError {
|
|
169
|
-
constructor(message = "Credential request is missing required 'Authorization' header with DPoP scheme") {
|
|
170
|
-
super(message);
|
|
166
|
+
constructor(message = "Credential request is missing required 'Authorization' header with DPoP scheme", options) {
|
|
167
|
+
super(message, options);
|
|
171
168
|
this.name = "CredentialAuthorizationHeaderError";
|
|
172
169
|
}
|
|
173
170
|
};
|
|
@@ -559,8 +556,9 @@ var import_io_wallet_utils4 = require("@pagopa/io-wallet-utils");
|
|
|
559
556
|
|
|
560
557
|
// src/credential-request/v1.3/z-credential.ts
|
|
561
558
|
var import_zod5 = require("zod");
|
|
559
|
+
var zCredentialRequestProofJwt = import_zod5.z.string().min(1, "JWT must not be empty in credential request proofs array");
|
|
562
560
|
var zCredentialRequestProofs = import_zod5.z.object({
|
|
563
|
-
jwt: import_zod5.z.
|
|
561
|
+
jwt: import_zod5.z.tuple([zCredentialRequestProofJwt], zCredentialRequestProofJwt)
|
|
564
562
|
});
|
|
565
563
|
var zCredentialRequestV1_3 = zBaseCredentialRequest.extend({
|
|
566
564
|
proofs: zCredentialRequestProofs.describe(
|
|
@@ -574,7 +572,8 @@ var zCredentialRequestV1_3 = zBaseCredentialRequest.extend({
|
|
|
574
572
|
var createCredentialRequest2 = async (options) => {
|
|
575
573
|
try {
|
|
576
574
|
const { maxBatchSize, signers } = options;
|
|
577
|
-
|
|
575
|
+
const [firstSigner, ...otherSigners] = signers;
|
|
576
|
+
if (!firstSigner) {
|
|
578
577
|
throw new import_io_wallet_utils4.ValidationError("At least one signer is required");
|
|
579
578
|
}
|
|
580
579
|
if (maxBatchSize !== void 0) {
|
|
@@ -607,29 +606,28 @@ var createCredentialRequest2 = async (options) => {
|
|
|
607
606
|
);
|
|
608
607
|
}
|
|
609
608
|
}
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
)
|
|
627
|
-
);
|
|
609
|
+
const createProofJwt = async (signer) => (await signJwt(signer, {
|
|
610
|
+
header: {
|
|
611
|
+
alg: signer.alg,
|
|
612
|
+
jwk: signer.publicJwk,
|
|
613
|
+
key_attestation: options.keyAttestation,
|
|
614
|
+
typ: "openid4vci-proof+jwt"
|
|
615
|
+
},
|
|
616
|
+
payload: {
|
|
617
|
+
aud: options.issuerIdentifier,
|
|
618
|
+
iat: (0, import_io_wallet_utils4.dateToSeconds)(/* @__PURE__ */ new Date()),
|
|
619
|
+
iss: options.clientId,
|
|
620
|
+
nonce: options.nonce
|
|
621
|
+
}
|
|
622
|
+
})).jwt;
|
|
623
|
+
const proofJwts = await Promise.all([
|
|
624
|
+
createProofJwt(firstSigner),
|
|
625
|
+
...otherSigners.map(createProofJwt)
|
|
626
|
+
]);
|
|
628
627
|
return (0, import_io_wallet_utils4.parseWithErrorHandling)(zCredentialRequestV1_3, {
|
|
629
628
|
credential_identifier: options.credential_identifier,
|
|
630
629
|
proofs: {
|
|
631
|
-
jwt: proofJwts
|
|
632
|
-
// Array for batch support
|
|
630
|
+
jwt: proofJwts
|
|
633
631
|
}
|
|
634
632
|
});
|
|
635
633
|
} catch (error) {
|
|
@@ -717,7 +715,10 @@ function validateTransactionContext(options) {
|
|
|
717
715
|
}
|
|
718
716
|
}
|
|
719
717
|
function parseProofJwt(options) {
|
|
720
|
-
const decoded = (0, import_io_wallet_oauth23.decodeJwt)({
|
|
718
|
+
const decoded = (0, import_io_wallet_oauth23.decodeJwt)({
|
|
719
|
+
errorMessagePrefix: "Error decoding credential request proof JWT:",
|
|
720
|
+
jwt: options.jwt
|
|
721
|
+
});
|
|
721
722
|
const headerValidation = options.itWalletSpecsVersion === import_io_wallet_utils6.ItWalletSpecsVersion.V1_3 ? zProofJwtHeaderV1_3.safeParse(decoded.header) : zProofJwtHeaderV1_0.safeParse(decoded.header);
|
|
722
723
|
if (!headerValidation.success) {
|
|
723
724
|
throw new import_io_wallet_utils6.ValidationError(
|
|
@@ -889,7 +890,7 @@ function parseCredentialRequest(options) {
|
|
|
889
890
|
}
|
|
890
891
|
throw new ParseCredentialRequestError(
|
|
891
892
|
`Unexpected error during credential request parsing: ${error instanceof Error ? error.message : String(error)}`,
|
|
892
|
-
error
|
|
893
|
+
{ cause: error }
|
|
893
894
|
);
|
|
894
895
|
}
|
|
895
896
|
}
|
|
@@ -897,16 +898,17 @@ function parseCredentialRequest(options) {
|
|
|
897
898
|
// src/credential-request/verify-credential-request-jwt-proof.ts
|
|
898
899
|
var import_oauth24 = require("@openid4vc/oauth2");
|
|
899
900
|
var import_io_wallet_oauth26 = require("@pagopa/io-wallet-oauth2");
|
|
900
|
-
var
|
|
901
|
+
var import_io_wallet_utils9 = require("@pagopa/io-wallet-utils");
|
|
901
902
|
|
|
902
903
|
// src/credential-request/verify-key-attestation-jwt.ts
|
|
903
904
|
var import_oauth23 = require("@openid4vc/oauth2");
|
|
904
905
|
var import_io_wallet_oauth25 = require("@pagopa/io-wallet-oauth2");
|
|
905
|
-
var
|
|
906
|
+
var import_io_wallet_utils8 = require("@pagopa/io-wallet-utils");
|
|
906
907
|
|
|
907
908
|
// src/wallet-provider/z-key-attestation.ts
|
|
908
909
|
var import_io_wallet_oauth24 = require("@pagopa/io-wallet-oauth2");
|
|
909
910
|
var import_io_wallet_oid_federation = require("@pagopa/io-wallet-oid-federation");
|
|
911
|
+
var import_io_wallet_utils7 = require("@pagopa/io-wallet-utils");
|
|
910
912
|
var import_zod7 = require("zod");
|
|
911
913
|
var zStatusList = import_zod7.z.object({
|
|
912
914
|
idx: import_zod7.z.number(),
|
|
@@ -915,14 +917,7 @@ var zStatusList = import_zod7.z.object({
|
|
|
915
917
|
var zKeyAttestationStatus = import_zod7.z.object({
|
|
916
918
|
status_list: zStatusList
|
|
917
919
|
});
|
|
918
|
-
var zKeyAttestationAlg =
|
|
919
|
-
"ES256",
|
|
920
|
-
"ES384",
|
|
921
|
-
"ES512",
|
|
922
|
-
"PS256",
|
|
923
|
-
"PS384",
|
|
924
|
-
"PS512"
|
|
925
|
-
]);
|
|
920
|
+
var zKeyAttestationAlg = import_io_wallet_utils7.zItwSupportedSignatureAlg;
|
|
926
921
|
var zKeyAttestationHeader = import_zod7.z.object({
|
|
927
922
|
alg: zKeyAttestationAlg,
|
|
928
923
|
kid: import_zod7.z.string(),
|
|
@@ -947,6 +942,7 @@ var keyAttestationTypeHeader = zKeyAttestationTypeHeader.value;
|
|
|
947
942
|
async function verifyKeyAttestationJwt(options) {
|
|
948
943
|
try {
|
|
949
944
|
const { header, payload } = (0, import_io_wallet_oauth25.decodeJwt)({
|
|
945
|
+
errorMessagePrefix: "Error decoding key attestation JWT:",
|
|
950
946
|
headerSchema: zKeyAttestationHeader,
|
|
951
947
|
jwt: options.keyAttestationJwt,
|
|
952
948
|
payloadSchema: zKeyAttestationPayload
|
|
@@ -974,12 +970,12 @@ async function verifyKeyAttestationJwt(options) {
|
|
|
974
970
|
}
|
|
975
971
|
return { header, payload, signer };
|
|
976
972
|
} catch (error) {
|
|
977
|
-
if (error instanceof VerifyKeyAttestationJwtError || error instanceof
|
|
973
|
+
if (error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils8.ValidationError || error instanceof import_oauth23.Oauth2JwtParseError) {
|
|
978
974
|
throw error;
|
|
979
975
|
}
|
|
980
976
|
throw new VerifyKeyAttestationJwtError(
|
|
981
977
|
`Unexpected error during key attestation jwt verification: ${error instanceof Error ? error.message : String(error)}`,
|
|
982
|
-
error
|
|
978
|
+
{ cause: error }
|
|
983
979
|
);
|
|
984
980
|
}
|
|
985
981
|
}
|
|
@@ -1004,7 +1000,7 @@ async function isJwkInSet(options) {
|
|
|
1004
1000
|
}
|
|
1005
1001
|
function verifyProofJwtIatOrThrow(options) {
|
|
1006
1002
|
try {
|
|
1007
|
-
(0,
|
|
1003
|
+
(0, import_io_wallet_utils9.verifyJwtIatOrThrow)({
|
|
1008
1004
|
iat: options.payload.iat,
|
|
1009
1005
|
now: options.now
|
|
1010
1006
|
});
|
|
@@ -1012,7 +1008,7 @@ function verifyProofJwtIatOrThrow(options) {
|
|
|
1012
1008
|
if (error instanceof Error) {
|
|
1013
1009
|
throw new VerifyCredentialRequestJwtProofError(
|
|
1014
1010
|
`Invalid iat claim in credential request proof JWT: ${error.message}`,
|
|
1015
|
-
error
|
|
1011
|
+
{ cause: error }
|
|
1016
1012
|
);
|
|
1017
1013
|
}
|
|
1018
1014
|
}
|
|
@@ -1026,8 +1022,9 @@ async function verifyCredentialRequestJwtProof(options) {
|
|
|
1026
1022
|
"Nonce used for credential request proof expired"
|
|
1027
1023
|
);
|
|
1028
1024
|
}
|
|
1029
|
-
if ((0,
|
|
1025
|
+
if ((0, import_io_wallet_utils9.hasConfigVersion)(options, import_io_wallet_utils9.ItWalletSpecsVersion.V1_0)) {
|
|
1030
1026
|
const { header, payload } = (0, import_io_wallet_oauth26.decodeJwt)({
|
|
1027
|
+
errorMessagePrefix: "Error decoding credential request proof JWT:",
|
|
1031
1028
|
headerSchema: zProofJwtHeaderV1_0,
|
|
1032
1029
|
jwt: options.jwt,
|
|
1033
1030
|
payloadSchema: zProofJwtPayload
|
|
@@ -1051,8 +1048,9 @@ async function verifyCredentialRequestJwtProof(options) {
|
|
|
1051
1048
|
signer
|
|
1052
1049
|
};
|
|
1053
1050
|
}
|
|
1054
|
-
if ((0,
|
|
1051
|
+
if ((0, import_io_wallet_utils9.hasConfigVersion)(options, import_io_wallet_utils9.ItWalletSpecsVersion.V1_3)) {
|
|
1055
1052
|
const { header, payload } = (0, import_io_wallet_oauth26.decodeJwt)({
|
|
1053
|
+
errorMessagePrefix: "Error decoding credential request proof JWT:",
|
|
1056
1054
|
headerSchema: zProofJwtHeaderV1_3,
|
|
1057
1055
|
jwt: options.jwt,
|
|
1058
1056
|
payloadSchema: zProofJwtPayload
|
|
@@ -1105,27 +1103,27 @@ async function verifyCredentialRequestJwtProof(options) {
|
|
|
1105
1103
|
signer
|
|
1106
1104
|
};
|
|
1107
1105
|
}
|
|
1108
|
-
throw new
|
|
1106
|
+
throw new import_io_wallet_utils9.ItWalletSpecsVersionError(
|
|
1109
1107
|
"verifyCredentialRequestJwtProof",
|
|
1110
1108
|
configVersion,
|
|
1111
|
-
[
|
|
1109
|
+
[import_io_wallet_utils9.ItWalletSpecsVersion.V1_0, import_io_wallet_utils9.ItWalletSpecsVersion.V1_3]
|
|
1112
1110
|
);
|
|
1113
1111
|
} catch (error) {
|
|
1114
|
-
if (error instanceof VerifyCredentialRequestJwtProofError || error instanceof VerifyKeyAttestationJwtError || error instanceof
|
|
1112
|
+
if (error instanceof VerifyCredentialRequestJwtProofError || error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils9.ItWalletSpecsVersionError || error instanceof import_io_wallet_utils9.ValidationError || error instanceof import_io_wallet_oauth26.Oauth2JwtParseError) {
|
|
1115
1113
|
throw error;
|
|
1116
1114
|
}
|
|
1117
1115
|
throw new VerifyCredentialRequestJwtProofError(
|
|
1118
1116
|
`Unexpected error during credential request proof verification: ${error instanceof Error ? error.message : String(error)}`,
|
|
1119
|
-
error
|
|
1117
|
+
{ cause: error }
|
|
1120
1118
|
);
|
|
1121
1119
|
}
|
|
1122
1120
|
}
|
|
1123
1121
|
|
|
1124
1122
|
// src/credential-response/create-credential-response.ts
|
|
1125
|
-
var
|
|
1123
|
+
var import_io_wallet_utils12 = require("@pagopa/io-wallet-utils");
|
|
1126
1124
|
|
|
1127
1125
|
// src/credential-response/v1.0/create-credential-response.ts
|
|
1128
|
-
var
|
|
1126
|
+
var import_io_wallet_utils10 = require("@pagopa/io-wallet-utils");
|
|
1129
1127
|
|
|
1130
1128
|
// src/credential-response/v1.0/z-credential-response.ts
|
|
1131
1129
|
var import_zod9 = require("zod");
|
|
@@ -1159,7 +1157,7 @@ var zCredentialResponseV1_0 = import_zod9.z.union([
|
|
|
1159
1157
|
// src/credential-response/v1.0/create-credential-response.ts
|
|
1160
1158
|
function createCredentialResponseV1_0(flow) {
|
|
1161
1159
|
if ("credentials" in flow) {
|
|
1162
|
-
return (0,
|
|
1160
|
+
return (0, import_io_wallet_utils10.parseWithErrorHandling)(
|
|
1163
1161
|
zCredentialResponseV1_0,
|
|
1164
1162
|
{
|
|
1165
1163
|
credentials: flow.credentials,
|
|
@@ -1170,7 +1168,7 @@ function createCredentialResponseV1_0(flow) {
|
|
|
1170
1168
|
"Invalid credential response for ItWalletSpecsVersion 1.0"
|
|
1171
1169
|
);
|
|
1172
1170
|
}
|
|
1173
|
-
return (0,
|
|
1171
|
+
return (0, import_io_wallet_utils10.parseWithErrorHandling)(
|
|
1174
1172
|
zCredentialResponseV1_0,
|
|
1175
1173
|
{
|
|
1176
1174
|
lead_time: flow.leadTime,
|
|
@@ -1181,7 +1179,7 @@ function createCredentialResponseV1_0(flow) {
|
|
|
1181
1179
|
}
|
|
1182
1180
|
|
|
1183
1181
|
// src/credential-response/v1.3/create-credential-response.ts
|
|
1184
|
-
var
|
|
1182
|
+
var import_io_wallet_utils11 = require("@pagopa/io-wallet-utils");
|
|
1185
1183
|
|
|
1186
1184
|
// src/credential-response/v1.3/z-credential-response.ts
|
|
1187
1185
|
var import_zod10 = require("zod");
|
|
@@ -1199,7 +1197,7 @@ var zCredentialResponseV1_3 = import_zod10.z.union([
|
|
|
1199
1197
|
// src/credential-response/v1.3/create-credential-response.ts
|
|
1200
1198
|
function createCredentialResponseV1_3(flow) {
|
|
1201
1199
|
if ("credentials" in flow) {
|
|
1202
|
-
return (0,
|
|
1200
|
+
return (0, import_io_wallet_utils11.parseWithErrorHandling)(
|
|
1203
1201
|
zCredentialResponseV1_3,
|
|
1204
1202
|
{
|
|
1205
1203
|
credentials: flow.credentials,
|
|
@@ -1210,7 +1208,7 @@ function createCredentialResponseV1_3(flow) {
|
|
|
1210
1208
|
"Invalid credential response for ItWalletSpecsVersion 1.3"
|
|
1211
1209
|
);
|
|
1212
1210
|
}
|
|
1213
|
-
return (0,
|
|
1211
|
+
return (0, import_io_wallet_utils11.parseWithErrorHandling)(
|
|
1214
1212
|
zCredentialResponseV1_3,
|
|
1215
1213
|
{
|
|
1216
1214
|
interval: flow.interval,
|
|
@@ -1240,26 +1238,26 @@ async function createCredentialResponse(options) {
|
|
|
1240
1238
|
}
|
|
1241
1239
|
return { credentialResponse, credentialResponseJwt };
|
|
1242
1240
|
} catch (error) {
|
|
1243
|
-
if (error instanceof
|
|
1241
|
+
if (error instanceof import_io_wallet_utils12.ItWalletSpecsVersionError || error instanceof import_io_wallet_utils12.ValidationError || error instanceof Oid4vciError) {
|
|
1244
1242
|
throw error;
|
|
1245
1243
|
}
|
|
1246
1244
|
throw new CreateCredentialResponseError(
|
|
1247
1245
|
`Unexpected error during create credential response: ${error instanceof Error ? error.message : String(error)}`,
|
|
1248
|
-
error
|
|
1246
|
+
{ cause: error }
|
|
1249
1247
|
);
|
|
1250
1248
|
}
|
|
1251
1249
|
}
|
|
1252
1250
|
function buildVersionedResponse(options) {
|
|
1253
1251
|
const version = options.config.itWalletSpecsVersion;
|
|
1254
|
-
if ((0,
|
|
1252
|
+
if ((0, import_io_wallet_utils12.hasConfigVersion)(options, import_io_wallet_utils12.ItWalletSpecsVersion.V1_0)) {
|
|
1255
1253
|
return createCredentialResponseV1_0(options.flow);
|
|
1256
1254
|
}
|
|
1257
|
-
if ((0,
|
|
1255
|
+
if ((0, import_io_wallet_utils12.hasConfigVersion)(options, import_io_wallet_utils12.ItWalletSpecsVersion.V1_3)) {
|
|
1258
1256
|
return createCredentialResponseV1_3(options.flow);
|
|
1259
1257
|
}
|
|
1260
|
-
throw new
|
|
1261
|
-
|
|
1262
|
-
|
|
1258
|
+
throw new import_io_wallet_utils12.ItWalletSpecsVersionError("createCredentialResponse", version, [
|
|
1259
|
+
import_io_wallet_utils12.ItWalletSpecsVersion.V1_0,
|
|
1260
|
+
import_io_wallet_utils12.ItWalletSpecsVersion.V1_3
|
|
1263
1261
|
]);
|
|
1264
1262
|
}
|
|
1265
1263
|
async function encryptResponse(credentialResponse, credentialResponseEncryption, encryptJwe) {
|
|
@@ -1277,7 +1275,7 @@ async function encryptResponse(credentialResponse, credentialResponseEncryption,
|
|
|
1277
1275
|
}
|
|
1278
1276
|
|
|
1279
1277
|
// src/credential-response/fetch-credential-response.ts
|
|
1280
|
-
var
|
|
1278
|
+
var import_io_wallet_utils13 = require("@pagopa/io-wallet-utils");
|
|
1281
1279
|
|
|
1282
1280
|
// src/credential-response/z-credential-response.ts
|
|
1283
1281
|
var import_io_wallet_oauth27 = require("@pagopa/io-wallet-oauth2");
|
|
@@ -1291,35 +1289,35 @@ var zCredentialResponseEncryption = import_zod11.z.looseObject({
|
|
|
1291
1289
|
// src/credential-response/fetch-credential-response.ts
|
|
1292
1290
|
async function fetchCredentialResponse(options) {
|
|
1293
1291
|
try {
|
|
1294
|
-
const fetch = (0,
|
|
1292
|
+
const fetch = (0, import_io_wallet_utils13.createFetcher)(options.callbacks.fetch);
|
|
1295
1293
|
const credentialResponse = await fetch(options.credentialEndpoint, {
|
|
1296
1294
|
body: JSON.stringify(options.credentialRequest),
|
|
1297
1295
|
headers: {
|
|
1298
|
-
[
|
|
1299
|
-
[
|
|
1300
|
-
[
|
|
1296
|
+
[import_io_wallet_utils13.HEADERS.AUTHORIZATION]: `DPoP ${options.accessToken}`,
|
|
1297
|
+
[import_io_wallet_utils13.HEADERS.CONTENT_TYPE]: import_io_wallet_utils13.CONTENT_TYPES.JSON,
|
|
1298
|
+
[import_io_wallet_utils13.HEADERS.DPOP]: options.dPoP
|
|
1301
1299
|
},
|
|
1302
1300
|
method: "POST"
|
|
1303
1301
|
});
|
|
1304
|
-
await (0,
|
|
1302
|
+
await (0, import_io_wallet_utils13.hasStatusOrThrow)(
|
|
1305
1303
|
[200, 202],
|
|
1306
|
-
|
|
1304
|
+
import_io_wallet_utils13.UnexpectedStatusCodeError
|
|
1307
1305
|
)(credentialResponse);
|
|
1308
1306
|
const credentialResponseJson = await credentialResponse.json();
|
|
1309
1307
|
if ("proof" in options.credentialRequest) {
|
|
1310
|
-
return (0,
|
|
1308
|
+
return (0, import_io_wallet_utils13.parseWithErrorHandling)(
|
|
1311
1309
|
zCredentialResponseV1_0,
|
|
1312
1310
|
credentialResponseJson,
|
|
1313
1311
|
`Failed to parse credential response (v1.0)`
|
|
1314
1312
|
);
|
|
1315
1313
|
}
|
|
1316
|
-
return (0,
|
|
1314
|
+
return (0, import_io_wallet_utils13.parseWithErrorHandling)(
|
|
1317
1315
|
zCredentialResponseV1_3,
|
|
1318
1316
|
credentialResponseJson,
|
|
1319
1317
|
`Failed to parse credential response (v1.3)`
|
|
1320
1318
|
);
|
|
1321
1319
|
} catch (error) {
|
|
1322
|
-
if (error instanceof
|
|
1320
|
+
if (error instanceof import_io_wallet_utils13.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils13.ValidationError) {
|
|
1323
1321
|
throw error;
|
|
1324
1322
|
}
|
|
1325
1323
|
throw new FetchCredentialResponseError(
|
|
@@ -1331,7 +1329,7 @@ async function fetchCredentialResponse(options) {
|
|
|
1331
1329
|
// src/metadata/fetch-metadata.ts
|
|
1332
1330
|
var import_io_wallet_oauth28 = require("@pagopa/io-wallet-oauth2");
|
|
1333
1331
|
var import_io_wallet_oid_federation3 = require("@pagopa/io-wallet-oid-federation");
|
|
1334
|
-
var
|
|
1332
|
+
var import_io_wallet_utils14 = require("@pagopa/io-wallet-utils");
|
|
1335
1333
|
var import_zod13 = __toESM(require("zod"));
|
|
1336
1334
|
|
|
1337
1335
|
// src/metadata/z-metadata-response.ts
|
|
@@ -1371,6 +1369,7 @@ async function tryFederationDiscovery(fetch, baseUrl, verifyJwt4) {
|
|
|
1371
1369
|
}
|
|
1372
1370
|
const entityStatement = await response.text();
|
|
1373
1371
|
const { header, payload } = (0, import_io_wallet_oauth28.decodeJwt)({
|
|
1372
|
+
errorMessagePrefix: "Error decoding entity statement JWT:",
|
|
1374
1373
|
jwt: entityStatement,
|
|
1375
1374
|
payloadSchema: import_io_wallet_oid_federation3.itWalletEntityStatementClaimsSchema
|
|
1376
1375
|
});
|
|
@@ -1386,7 +1385,7 @@ async function tryFederationDiscovery(fetch, baseUrl, verifyJwt4) {
|
|
|
1386
1385
|
payload
|
|
1387
1386
|
});
|
|
1388
1387
|
if (!result.verified) {
|
|
1389
|
-
throw new
|
|
1388
|
+
throw new import_io_wallet_utils14.ValidationError(
|
|
1390
1389
|
"Entity statement signature verification failed"
|
|
1391
1390
|
);
|
|
1392
1391
|
}
|
|
@@ -1397,7 +1396,7 @@ async function tryFederationDiscovery(fetch, baseUrl, verifyJwt4) {
|
|
|
1397
1396
|
openid_federation_claims: payload
|
|
1398
1397
|
};
|
|
1399
1398
|
} catch (error) {
|
|
1400
|
-
if (error instanceof
|
|
1399
|
+
if (error instanceof import_io_wallet_utils14.ValidationError) {
|
|
1401
1400
|
throw error;
|
|
1402
1401
|
}
|
|
1403
1402
|
return void 0;
|
|
@@ -1409,8 +1408,8 @@ async function fallbackDiscovery(fetch, baseUrl) {
|
|
|
1409
1408
|
ensureTrailingSlash(baseUrl)
|
|
1410
1409
|
).toString();
|
|
1411
1410
|
const issuerResponse = await fetch(issuerUrl);
|
|
1412
|
-
await (0,
|
|
1413
|
-
const issuerJson = (0,
|
|
1411
|
+
await (0, import_io_wallet_utils14.hasStatusOrThrow)(200, import_io_wallet_utils14.UnexpectedStatusCodeError)(issuerResponse);
|
|
1412
|
+
const issuerJson = (0, import_io_wallet_utils14.parseWithErrorHandling)(
|
|
1414
1413
|
zPartialIssuerMetadata,
|
|
1415
1414
|
await issuerResponse.json(),
|
|
1416
1415
|
"Failed to parse credential issuer metadata"
|
|
@@ -1420,7 +1419,7 @@ async function fallbackDiscovery(fetch, baseUrl) {
|
|
|
1420
1419
|
if (authorizationServers && authorizationServers.length > 0) {
|
|
1421
1420
|
const parsedUrl = import_zod13.default.url().safeParse(authorizationServers[0]);
|
|
1422
1421
|
if (!parsedUrl.success || !parsedUrl.data.startsWith("https://")) {
|
|
1423
|
-
throw new
|
|
1422
|
+
throw new import_io_wallet_utils14.ValidationError(
|
|
1424
1423
|
"authorization_servers[0] is not a valid HTTPS URL"
|
|
1425
1424
|
);
|
|
1426
1425
|
}
|
|
@@ -1429,7 +1428,7 @@ async function fallbackDiscovery(fetch, baseUrl) {
|
|
|
1429
1428
|
ensureTrailingSlash(parsedUrl.data)
|
|
1430
1429
|
).toString();
|
|
1431
1430
|
const authServerResponse = await fetch(authServerUrl);
|
|
1432
|
-
await (0,
|
|
1431
|
+
await (0, import_io_wallet_utils14.hasStatusOrThrow)(200, import_io_wallet_utils14.UnexpectedStatusCodeError)(authServerResponse);
|
|
1433
1432
|
oauthAuthorizationServer = await authServerResponse.json();
|
|
1434
1433
|
} else {
|
|
1435
1434
|
oauthAuthorizationServer = issuerJson;
|
|
@@ -1447,12 +1446,12 @@ async function fetchMetadata(options) {
|
|
|
1447
1446
|
try {
|
|
1448
1447
|
const urlValidation = import_zod13.default.url().safeParse(options.credentialIssuerUrl);
|
|
1449
1448
|
if (!urlValidation.success || !urlValidation.data.startsWith("https://")) {
|
|
1450
|
-
throw new
|
|
1449
|
+
throw new import_io_wallet_utils14.ValidationError(
|
|
1451
1450
|
"credentialIssuerUrl must be a valid HTTPS URL"
|
|
1452
1451
|
);
|
|
1453
1452
|
}
|
|
1454
|
-
const fetch = (0,
|
|
1455
|
-
if (config.isVersion(
|
|
1453
|
+
const fetch = (0, import_io_wallet_utils14.createFetcher)(options.callbacks.fetch);
|
|
1454
|
+
if (config.isVersion(import_io_wallet_utils14.ItWalletSpecsVersion.V1_0)) {
|
|
1456
1455
|
const federationResult = await tryFederationDiscovery(
|
|
1457
1456
|
fetch,
|
|
1458
1457
|
options.credentialIssuerUrl,
|
|
@@ -1463,44 +1462,43 @@ async function fetchMetadata(options) {
|
|
|
1463
1462
|
`Federation discovery failed for IT Wallet v1.0; no fallback available for credentialIssuerUrl ${options.credentialIssuerUrl}`
|
|
1464
1463
|
);
|
|
1465
1464
|
}
|
|
1466
|
-
return (0,
|
|
1465
|
+
return (0, import_io_wallet_utils14.parseWithErrorHandling)(
|
|
1467
1466
|
zMetadataResponseV1_0,
|
|
1468
1467
|
federationResult,
|
|
1469
1468
|
"Failed to parse v1.0 metadata response"
|
|
1470
1469
|
);
|
|
1471
1470
|
}
|
|
1472
|
-
if (config.isVersion(
|
|
1471
|
+
if (config.isVersion(import_io_wallet_utils14.ItWalletSpecsVersion.V1_3)) {
|
|
1473
1472
|
const federationResult = await tryFederationDiscovery(
|
|
1474
1473
|
fetch,
|
|
1475
1474
|
options.credentialIssuerUrl,
|
|
1476
1475
|
options.callbacks.verifyJwt
|
|
1477
1476
|
);
|
|
1478
1477
|
const raw = federationResult ?? await fallbackDiscovery(fetch, options.credentialIssuerUrl);
|
|
1479
|
-
return (0,
|
|
1478
|
+
return (0, import_io_wallet_utils14.parseWithErrorHandling)(
|
|
1480
1479
|
zMetadataResponseV1_3,
|
|
1481
1480
|
raw,
|
|
1482
1481
|
"Failed to parse v1.3 metadata response"
|
|
1483
1482
|
);
|
|
1484
1483
|
}
|
|
1485
|
-
throw new
|
|
1484
|
+
throw new import_io_wallet_utils14.ItWalletSpecsVersionError(
|
|
1486
1485
|
"fetchMetadata",
|
|
1487
1486
|
config.itWalletSpecsVersion,
|
|
1488
|
-
[
|
|
1487
|
+
[import_io_wallet_utils14.ItWalletSpecsVersion.V1_0, import_io_wallet_utils14.ItWalletSpecsVersion.V1_3]
|
|
1489
1488
|
);
|
|
1490
1489
|
} catch (error) {
|
|
1491
|
-
if (error instanceof
|
|
1490
|
+
if (error instanceof import_io_wallet_utils14.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils14.ValidationError || error instanceof import_io_wallet_utils14.ItWalletSpecsVersionError || error instanceof FetchMetadataError) {
|
|
1492
1491
|
throw error;
|
|
1493
1492
|
}
|
|
1494
|
-
throw new FetchMetadataError(
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
);
|
|
1493
|
+
throw new FetchMetadataError("Unexpected error during metadata fetch", {
|
|
1494
|
+
cause: error
|
|
1495
|
+
});
|
|
1498
1496
|
}
|
|
1499
1497
|
}
|
|
1500
1498
|
|
|
1501
1499
|
// src/wallet-provider/WalletProvider.ts
|
|
1502
1500
|
var import_io_wallet_oauth29 = require("@pagopa/io-wallet-oauth2");
|
|
1503
|
-
var
|
|
1501
|
+
var import_io_wallet_utils15 = require("@pagopa/io-wallet-utils");
|
|
1504
1502
|
function assertV1_0Options(options) {
|
|
1505
1503
|
if (options.signer.method !== "federation") {
|
|
1506
1504
|
throw new WalletProviderError(
|
|
@@ -1515,6 +1513,28 @@ function assertV1_3Options(options) {
|
|
|
1515
1513
|
);
|
|
1516
1514
|
}
|
|
1517
1515
|
}
|
|
1516
|
+
function assertV1_4Options(options) {
|
|
1517
|
+
if (options.signer.method !== "x5c") {
|
|
1518
|
+
throw new WalletProviderError(
|
|
1519
|
+
`Version mismatch: provider is configured for v1.4 (x5c) but received options with signer method "${options.signer.method}"`
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
if (!options.walletLink) {
|
|
1523
|
+
throw new WalletProviderError(
|
|
1524
|
+
`Version mismatch: provider is configured for v1.4 but 'walletLink' is required and missing`
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
if (!options.walletName) {
|
|
1528
|
+
throw new WalletProviderError(
|
|
1529
|
+
`Version mismatch: provider is configured for v1.4 but 'walletName' is required and missing`
|
|
1530
|
+
);
|
|
1531
|
+
}
|
|
1532
|
+
if (!("status" in options) || !options.status) {
|
|
1533
|
+
throw new WalletProviderError(
|
|
1534
|
+
`Version mismatch: provider is configured for v1.4 but 'status' is required and missing`
|
|
1535
|
+
);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1518
1538
|
var WalletProvider = class {
|
|
1519
1539
|
specVersion;
|
|
1520
1540
|
constructor(options) {
|
|
@@ -1536,7 +1556,7 @@ var WalletProvider = class {
|
|
|
1536
1556
|
const { signJwt } = options.callbacks;
|
|
1537
1557
|
const now = /* @__PURE__ */ new Date();
|
|
1538
1558
|
const issuedAt = options.issuedAt ?? now;
|
|
1539
|
-
const expiresAt = options.expiresAt ?? (0,
|
|
1559
|
+
const expiresAt = options.expiresAt ?? (0, import_io_wallet_utils15.addSecondsToDate)(now, 3600 * 24 * 360);
|
|
1540
1560
|
const header = {
|
|
1541
1561
|
alg: options.signer.alg,
|
|
1542
1562
|
kid: options.signer.kid,
|
|
@@ -1546,8 +1566,8 @@ var WalletProvider = class {
|
|
|
1546
1566
|
};
|
|
1547
1567
|
const payload = {
|
|
1548
1568
|
attested_keys: options.attestedKeys,
|
|
1549
|
-
exp: (0,
|
|
1550
|
-
iat: (0,
|
|
1569
|
+
exp: (0, import_io_wallet_utils15.dateToSeconds)(expiresAt),
|
|
1570
|
+
iat: (0, import_io_wallet_utils15.dateToSeconds)(issuedAt),
|
|
1551
1571
|
iss: options.issuer,
|
|
1552
1572
|
key_storage: options.keyStorage,
|
|
1553
1573
|
status: options.status,
|
|
@@ -1570,8 +1590,10 @@ var WalletProvider = class {
|
|
|
1570
1590
|
* Creates a wallet attestation JWT according to the configured Italian Wallet specification version.
|
|
1571
1591
|
*
|
|
1572
1592
|
* Version Differences:
|
|
1573
|
-
* - v1.0: Uses only `trust_chain` in header (federation method)
|
|
1574
|
-
* - v1.3: Requires `x5c` in header, optional `trust_chain
|
|
1593
|
+
* - v1.0: Uses only `trust_chain` in header (federation method); no `status` claim
|
|
1594
|
+
* - v1.3: Requires `x5c` in header, optional `trust_chain`; supports optional `nbf` and `status` claims
|
|
1595
|
+
* - v1.4: Requires `x5c` in header, optional `trust_chain`; `status`, `wallet_link`, and `wallet_name`
|
|
1596
|
+
* are all **required**; optional `eudi_wallet_info` claim; sets `sub` to `dpopJwkPublic.kid`
|
|
1575
1597
|
*
|
|
1576
1598
|
* @public
|
|
1577
1599
|
* @async
|
|
@@ -1606,14 +1628,39 @@ var WalletProvider = class {
|
|
|
1606
1628
|
* nbf: new Date('2025-01-01'), // Optional
|
|
1607
1629
|
* status: { status_list: { idx: 2, uri: "https://status.example.com" } } // Optional
|
|
1608
1630
|
* });
|
|
1631
|
+
*
|
|
1632
|
+
* @example v1.4 - Wallet attestation with required status and optional eudi_wallet_info
|
|
1633
|
+
* const jwt = await provider.createItWalletAttestationJwt({
|
|
1634
|
+
* callbacks: { signJwt: mySignJwtCallback },
|
|
1635
|
+
* dpopJwkPublic: myJwk,
|
|
1636
|
+
* issuer: "https://wallet-provider.example.com",
|
|
1637
|
+
* signer: {
|
|
1638
|
+
* alg: "ES256",
|
|
1639
|
+
* kid: "provider-key-id",
|
|
1640
|
+
* method: "x5c",
|
|
1641
|
+
* x5c: ["cert1-base64", "cert2-base64"],
|
|
1642
|
+
* trustChain: ["trust-anchor-jwt"] // Optional
|
|
1643
|
+
* },
|
|
1644
|
+
* status: { status_list: { idx: 2, uri: "https://status.example.com" } }, // Required
|
|
1645
|
+
* walletLink: "https://wallet.example.com", // Required
|
|
1646
|
+
* walletName: "My Wallet", // Required
|
|
1647
|
+
* eudiWalletInfo: { // Optional
|
|
1648
|
+
* general_info: {
|
|
1649
|
+
* wallet_provider_name: "PagoPA",
|
|
1650
|
+
* wallet_solution_certification_information: "certification-ref",
|
|
1651
|
+
* wallet_solution_id: "wallet-solution-id",
|
|
1652
|
+
* wallet_solution_version: "1.0.0"
|
|
1653
|
+
* }
|
|
1654
|
+
* }
|
|
1655
|
+
* });
|
|
1609
1656
|
*/
|
|
1610
1657
|
async createItWalletAttestationJwt(options) {
|
|
1611
1658
|
if (!options.dpopJwkPublic.kid) {
|
|
1612
1659
|
throw new WalletProviderError("The DPoP JWK must have a 'kid' property");
|
|
1613
1660
|
}
|
|
1614
|
-
if (this.specVersion ===
|
|
1661
|
+
if (this.specVersion === import_io_wallet_utils15.ItWalletSpecsVersion.V1_0) {
|
|
1615
1662
|
assertV1_0Options(options);
|
|
1616
|
-
return import_io_wallet_oauth29.
|
|
1663
|
+
return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_0)({
|
|
1617
1664
|
authenticatorAssuranceLevel: options.authenticatorAssuranceLevel,
|
|
1618
1665
|
callbacks: options.callbacks,
|
|
1619
1666
|
dpopJwkPublic: options.dpopJwkPublic,
|
|
@@ -1624,9 +1671,9 @@ var WalletProvider = class {
|
|
|
1624
1671
|
walletName: options.walletName
|
|
1625
1672
|
});
|
|
1626
1673
|
}
|
|
1627
|
-
if (this.specVersion ===
|
|
1674
|
+
if (this.specVersion === import_io_wallet_utils15.ItWalletSpecsVersion.V1_3) {
|
|
1628
1675
|
assertV1_3Options(options);
|
|
1629
|
-
return import_io_wallet_oauth29.
|
|
1676
|
+
return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_3)({
|
|
1630
1677
|
callbacks: options.callbacks,
|
|
1631
1678
|
dpopJwkPublic: options.dpopJwkPublic,
|
|
1632
1679
|
expiresAt: options.expiresAt,
|
|
@@ -1638,10 +1685,24 @@ var WalletProvider = class {
|
|
|
1638
1685
|
walletName: options.walletName
|
|
1639
1686
|
});
|
|
1640
1687
|
}
|
|
1641
|
-
|
|
1688
|
+
if (this.specVersion === import_io_wallet_utils15.ItWalletSpecsVersion.V1_4) {
|
|
1689
|
+
assertV1_4Options(options);
|
|
1690
|
+
return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_4)({
|
|
1691
|
+
callbacks: options.callbacks,
|
|
1692
|
+
dpopJwkPublic: options.dpopJwkPublic,
|
|
1693
|
+
eudiWalletInfo: options.eudiWalletInfo,
|
|
1694
|
+
expiresAt: options.expiresAt,
|
|
1695
|
+
issuer: options.issuer,
|
|
1696
|
+
signer: options.signer,
|
|
1697
|
+
status: options.status,
|
|
1698
|
+
walletLink: options.walletLink,
|
|
1699
|
+
walletName: options.walletName
|
|
1700
|
+
});
|
|
1701
|
+
}
|
|
1702
|
+
throw new import_io_wallet_utils15.ItWalletSpecsVersionError(
|
|
1642
1703
|
"createItWalletAttestationJwt",
|
|
1643
1704
|
this.specVersion,
|
|
1644
|
-
|
|
1705
|
+
Object.values(import_io_wallet_utils15.ItWalletSpecsVersion)
|
|
1645
1706
|
);
|
|
1646
1707
|
}
|
|
1647
1708
|
};
|