@pagopa/io-react-native-wallet 1.3.0 → 1.4.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/lib/commonjs/credential/issuance/06-obtain-credential.js +8 -2
- package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +147 -3
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/commonjs/credential/issuance/const.js +1 -1
- package/lib/commonjs/credential/issuance/const.js.map +1 -1
- package/lib/commonjs/credential/issuance/types.js +1 -1
- package/lib/commonjs/credential/issuance/types.js.map +1 -1
- package/lib/commonjs/credential/presentation/03-get-request-object.js +7 -25
- package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +52 -12
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/commonjs/credential/presentation/README.md +1 -3
- package/lib/commonjs/credential/presentation/index.js +6 -0
- package/lib/commonjs/credential/presentation/index.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js +19 -1
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/commonjs/entity/openid-connect/issuer/types.js +10 -7
- package/lib/commonjs/entity/openid-connect/issuer/types.js.map +1 -1
- package/lib/commonjs/entity/trust/types.js +1 -1
- package/lib/commonjs/entity/trust/types.js.map +1 -1
- package/lib/commonjs/mdoc/converters.js +26 -0
- package/lib/commonjs/mdoc/converters.js.map +1 -0
- package/lib/commonjs/mdoc/index.js +28 -0
- package/lib/commonjs/mdoc/index.js.map +1 -0
- package/lib/commonjs/utils/string.js +13 -1
- package/lib/commonjs/utils/string.js.map +1 -1
- package/lib/module/credential/issuance/06-obtain-credential.js +8 -2
- package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js +147 -3
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/module/credential/issuance/const.js +1 -1
- package/lib/module/credential/issuance/const.js.map +1 -1
- package/lib/module/credential/issuance/types.js +1 -1
- package/lib/module/credential/issuance/types.js.map +1 -1
- package/lib/module/credential/presentation/03-get-request-object.js +7 -24
- package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +1 -1
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/module/credential/presentation/08-send-authorization-response.js +51 -11
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/module/credential/presentation/README.md +1 -3
- package/lib/module/credential/presentation/index.js +2 -2
- package/lib/module/credential/presentation/index.js.map +1 -1
- package/lib/module/credential/presentation/types.js +18 -0
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/module/entity/openid-connect/issuer/types.js +7 -6
- package/lib/module/entity/openid-connect/issuer/types.js.map +1 -1
- package/lib/module/entity/trust/types.js +1 -1
- package/lib/module/entity/trust/types.js.map +1 -1
- package/lib/module/mdoc/converters.js +20 -0
- package/lib/module/mdoc/converters.js.map +1 -0
- package/lib/module/mdoc/index.js +21 -0
- package/lib/module/mdoc/index.js.map +1 -0
- package/lib/module/utils/string.js +12 -0
- package/lib/module/utils/string.js.map +1 -1
- package/lib/typescript/credential/issuance/06-obtain-credential.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/const.d.ts +1 -1
- package/lib/typescript/credential/issuance/const.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/types.d.ts +7 -7
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts +2 -8
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +23 -7
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/index.d.ts +3 -3
- package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +26 -0
- package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
- package/lib/typescript/entity/openid-connect/issuer/types.d.ts +177 -41
- package/lib/typescript/entity/openid-connect/issuer/types.d.ts.map +1 -1
- package/lib/typescript/entity/trust/index.d.ts +2 -2
- package/lib/typescript/entity/trust/types.d.ts +22 -22
- package/lib/typescript/mdoc/converters.d.ts +8 -0
- package/lib/typescript/mdoc/converters.d.ts.map +1 -0
- package/lib/typescript/mdoc/index.d.ts +6 -0
- package/lib/typescript/mdoc/index.d.ts.map +1 -0
- package/lib/typescript/sd-jwt/index.d.ts +4 -4
- package/lib/typescript/sd-jwt/types.d.ts +5 -5
- package/lib/typescript/utils/string.d.ts +7 -0
- package/lib/typescript/utils/string.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/credential/issuance/06-obtain-credential.ts +14 -5
- package/src/credential/issuance/07-verify-and-parse-credential.ts +201 -1
- package/src/credential/issuance/const.ts +1 -1
- package/src/credential/issuance/types.ts +1 -1
- package/src/credential/presentation/03-get-request-object.ts +4 -29
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +2 -5
- package/src/credential/presentation/08-send-authorization-response.ts +70 -22
- package/src/credential/presentation/README.md +1 -3
- package/src/credential/presentation/index.ts +4 -0
- package/src/credential/presentation/types.ts +26 -0
- package/src/entity/openid-connect/issuer/types.ts +18 -10
- package/src/entity/trust/types.ts +1 -1
- package/src/mdoc/converters.ts +26 -0
- package/src/mdoc/index.ts +28 -0
- package/src/utils/string.ts +12 -0
@@ -1,19 +1,10 @@
|
|
1
|
-
import uuid from "react-native-uuid";
|
2
|
-
import {
|
3
|
-
sha256ToBase64,
|
4
|
-
type CryptoContext,
|
5
|
-
} from "@pagopa/io-react-native-jwt";
|
6
|
-
|
7
|
-
import { createDPopToken } from "../../utils/dpop";
|
8
1
|
import { hasStatusOrThrow, type Out } from "../../utils/misc";
|
9
2
|
import type { StartFlow } from "./01-start-flow";
|
10
3
|
|
11
4
|
export type GetRequestObject = (
|
12
5
|
requestUri: Out<StartFlow>["requestUri"],
|
13
|
-
context
|
14
|
-
wiaCryptoContext: CryptoContext;
|
6
|
+
context?: {
|
15
7
|
appFetch?: GlobalFetch["fetch"];
|
16
|
-
walletInstanceAttestation: string;
|
17
8
|
}
|
18
9
|
) => Promise<{ requestObjectEncodedJwt: string }>;
|
19
10
|
|
@@ -21,33 +12,17 @@ export type GetRequestObject = (
|
|
21
12
|
* Obtain the Request Object for RP authentication
|
22
13
|
* @see https://italia.github.io/eudi-wallet-it-docs/versione-corrente/en/relying-party-solution.html
|
23
14
|
*
|
24
|
-
* @param requestUri The
|
25
|
-
* @param rpConf The Relying Party's configuration
|
26
|
-
* @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
|
27
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
15
|
+
* @param requestUri The request uri of the Relying Party
|
28
16
|
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
29
17
|
* @returns The Request Object that describes the presentation
|
30
18
|
*/
|
31
19
|
export const getRequestObject: GetRequestObject = async (
|
32
20
|
requestUri,
|
33
|
-
|
21
|
+
context = {}
|
34
22
|
) => {
|
35
|
-
const
|
36
|
-
{
|
37
|
-
jti: `${uuid.v4()}`,
|
38
|
-
htm: "GET",
|
39
|
-
htu: requestUri,
|
40
|
-
ath: await sha256ToBase64(walletInstanceAttestation),
|
41
|
-
},
|
42
|
-
wiaCryptoContext
|
43
|
-
);
|
44
|
-
|
23
|
+
const { appFetch = fetch } = context;
|
45
24
|
const requestObjectEncodedJwt = await appFetch(requestUri, {
|
46
25
|
method: "GET",
|
47
|
-
headers: {
|
48
|
-
Authorization: `DPoP ${walletInstanceAttestation}`,
|
49
|
-
DPoP: signedWalletInstanceDPoP,
|
50
|
-
},
|
51
26
|
})
|
52
27
|
.then(hasStatusOrThrow(200))
|
53
28
|
.then((res) => res.text());
|
@@ -189,11 +189,8 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
|
|
189
189
|
requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
|
190
190
|
);
|
191
191
|
|
192
|
-
const optionalDisclosures = disclosures.filter(
|
193
|
-
(disclosure)
|
194
|
-
optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]) ||
|
195
|
-
(isNotLimitDisclosure &&
|
196
|
-
!requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]))
|
192
|
+
const optionalDisclosures = disclosures.filter((disclosure) =>
|
193
|
+
optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
|
197
194
|
);
|
198
195
|
|
199
196
|
const isNotLimitDisclosure = !(
|
@@ -9,7 +9,12 @@ import type { VerifyRequestObjectSignature } from "./05-verify-request-object";
|
|
9
9
|
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
|
10
10
|
import { hasStatusOrThrow, type Out } from "../../utils/misc";
|
11
11
|
import { disclose } from "../../sd-jwt";
|
12
|
-
import {
|
12
|
+
import {
|
13
|
+
DirectAuthorizationBodyPayload,
|
14
|
+
ErrorResponse,
|
15
|
+
PresentationDefinition,
|
16
|
+
type Presentation,
|
17
|
+
} from "./types";
|
13
18
|
import * as z from "zod";
|
14
19
|
import type { JWK } from "../../utils/jwk";
|
15
20
|
|
@@ -125,19 +130,20 @@ export const prepareVpToken = async (
|
|
125
130
|
* Builds a URL-encoded form body for a direct POST response without encryption.
|
126
131
|
*
|
127
132
|
* @param requestObject - Contains state, nonce, and other relevant info.
|
128
|
-
* @param
|
129
|
-
* @param presentationSubmission - Object mapping credential disclosures.
|
133
|
+
* @param payload - Object that contains either the VP token to encrypt and the stringified mapping of the credential disclosures or the error code
|
130
134
|
* @returns A URL-encoded string suitable for an `application/x-www-form-urlencoded` POST body.
|
131
135
|
*/
|
132
136
|
export const buildDirectPostBody = async (
|
133
137
|
requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
|
134
|
-
|
135
|
-
presentationSubmission: Record<string, unknown>
|
138
|
+
payload: DirectAuthorizationBodyPayload
|
136
139
|
): Promise<string> => {
|
137
140
|
const formUrlEncodedBody = new URLSearchParams({
|
138
141
|
state: requestObject.state,
|
139
|
-
|
140
|
-
|
142
|
+
...Object.fromEntries(
|
143
|
+
Object.entries(payload).map(([key, value]) => {
|
144
|
+
return [key, typeof value === "object" ? JSON.stringify(value) : value];
|
145
|
+
})
|
146
|
+
),
|
141
147
|
});
|
142
148
|
|
143
149
|
return formUrlEncodedBody.toString();
|
@@ -148,22 +154,19 @@ export const buildDirectPostBody = async (
|
|
148
154
|
*
|
149
155
|
* @param jwkKeys - Array of JWKs from the Relying Party for encryption.
|
150
156
|
* @param requestObject - Contains state, nonce, and other relevant info.
|
151
|
-
* @param
|
152
|
-
* @param presentationSubmission - Object mapping credential disclosures.
|
157
|
+
* @param payload - Object that contains either the VP token to encrypt and the mapping of the credential disclosures or the error code
|
153
158
|
* @returns A URL-encoded string for an `application/x-www-form-urlencoded` POST body,
|
154
159
|
* where `response` contains the encrypted JWE.
|
155
160
|
*/
|
156
161
|
export const buildDirectPostJwtBody = async (
|
157
162
|
jwkKeys: Out<FetchJwks>["keys"],
|
158
163
|
requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
|
159
|
-
|
160
|
-
presentationSubmission: Record<string, unknown>
|
164
|
+
payload: DirectAuthorizationBodyPayload
|
161
165
|
): Promise<string> => {
|
162
166
|
// Prepare the authorization response payload to be encrypted
|
163
167
|
const authzResponsePayload = JSON.stringify({
|
164
168
|
state: requestObject.state,
|
165
|
-
|
166
|
-
vp_token: vpToken,
|
169
|
+
...payload,
|
167
170
|
});
|
168
171
|
|
169
172
|
// Choose a suitable RSA public key for encryption
|
@@ -233,17 +236,14 @@ export const sendAuthorizationResponse: SendAuthorizationResponse = async (
|
|
233
236
|
// 2. Choose the appropriate request body builder based on response mode
|
234
237
|
const requestBody =
|
235
238
|
requestObject.response_mode === "direct_post.jwt"
|
236
|
-
? await buildDirectPostJwtBody(
|
237
|
-
jwkKeys,
|
238
|
-
requestObject,
|
239
|
+
? await buildDirectPostJwtBody(jwkKeys, requestObject, {
|
239
240
|
vp_token,
|
240
|
-
presentation_submission
|
241
|
-
)
|
242
|
-
: await buildDirectPostBody(
|
243
|
-
requestObject,
|
241
|
+
presentation_submission,
|
242
|
+
})
|
243
|
+
: await buildDirectPostBody(requestObject, {
|
244
244
|
vp_token,
|
245
|
-
presentation_submission
|
246
|
-
);
|
245
|
+
presentation_submission: presentation_submission,
|
246
|
+
});
|
247
247
|
|
248
248
|
// 3. Send the authorization response via HTTP POST and validate the response
|
249
249
|
return await appFetch(requestObject.response_uri, {
|
@@ -257,3 +257,51 @@ export const sendAuthorizationResponse: SendAuthorizationResponse = async (
|
|
257
257
|
.then((res) => res.json())
|
258
258
|
.then(AuthorizationResponse.parse);
|
259
259
|
};
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Type definition for the function that sends the authorization response
|
263
|
+
* to the Relying Party, completing the presentation flow.
|
264
|
+
*/
|
265
|
+
export type SendAuthorizationErrorResponse = (
|
266
|
+
requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
|
267
|
+
error: ErrorResponse,
|
268
|
+
jwkKeys: Out<FetchJwks>["keys"],
|
269
|
+
context?: {
|
270
|
+
appFetch?: GlobalFetch["fetch"];
|
271
|
+
}
|
272
|
+
) => Promise<AuthorizationResponse>;
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Sends the authorization error response to the Relying Party (RP) using the specified `response_mode`.
|
276
|
+
* This function completes the presentation flow in an OpenID 4 Verifiable Presentations scenario.
|
277
|
+
*
|
278
|
+
* @param requestObject - The request details, including presentation requirements.
|
279
|
+
* @param error - The response error value
|
280
|
+
* @param jwkKeys - Array of JWKs from the Relying Party for optional encryption.
|
281
|
+
* @param context - Contains optional custom fetch implementation.
|
282
|
+
* @returns Parsed and validated authorization response from the Relying Party.
|
283
|
+
*/
|
284
|
+
export const sendAuthorizationErrorResponse: SendAuthorizationErrorResponse =
|
285
|
+
async (
|
286
|
+
requestObject,
|
287
|
+
error,
|
288
|
+
jwkKeys,
|
289
|
+
{ appFetch = fetch } = {}
|
290
|
+
): Promise<AuthorizationResponse> => {
|
291
|
+
// 2. Choose the appropriate request body builder based on response mode
|
292
|
+
const requestBody =
|
293
|
+
requestObject.response_mode === "direct_post.jwt"
|
294
|
+
? await buildDirectPostJwtBody(jwkKeys, requestObject, { error })
|
295
|
+
: await buildDirectPostBody(requestObject, { error });
|
296
|
+
// 3. Send the authorization error response via HTTP POST and validate the response
|
297
|
+
return await appFetch(requestObject.response_uri, {
|
298
|
+
method: "POST",
|
299
|
+
headers: {
|
300
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
301
|
+
},
|
302
|
+
body: requestBody,
|
303
|
+
})
|
304
|
+
.then(hasStatusOrThrow(200))
|
305
|
+
.then((res) => res.json())
|
306
|
+
.then(AuthorizationResponse.parse);
|
307
|
+
};
|
@@ -62,9 +62,7 @@ const { rpConf } = await Credential.Presentation.evaluateRelyingPartyTrust(clien
|
|
62
62
|
|
63
63
|
const { requestObjectEncodedJwt } =
|
64
64
|
await Credential.Presentation.getRequestObject(requestURI, {
|
65
|
-
|
66
|
-
appFetch: appFetch,
|
67
|
-
walletInstanceAttestation: walletInstanceAttestation,
|
65
|
+
appFetch: appFetch
|
68
66
|
});
|
69
67
|
|
70
68
|
// Retrieve RP JWK
|
@@ -27,6 +27,8 @@ import {
|
|
27
27
|
import {
|
28
28
|
sendAuthorizationResponse,
|
29
29
|
type SendAuthorizationResponse,
|
30
|
+
sendAuthorizationErrorResponse,
|
31
|
+
type SendAuthorizationErrorResponse,
|
30
32
|
} from "./08-send-authorization-response";
|
31
33
|
import * as Errors from "./errors";
|
32
34
|
|
@@ -40,6 +42,7 @@ export {
|
|
40
42
|
fetchPresentDefinition,
|
41
43
|
evaluateInputDescriptorForSdJwt4VC,
|
42
44
|
sendAuthorizationResponse,
|
45
|
+
sendAuthorizationErrorResponse,
|
43
46
|
Errors,
|
44
47
|
};
|
45
48
|
export type {
|
@@ -51,4 +54,5 @@ export type {
|
|
51
54
|
FetchPresentationDefinition,
|
52
55
|
EvaluateInputDescriptorSdJwt4VC,
|
53
56
|
SendAuthorizationResponse,
|
57
|
+
SendAuthorizationErrorResponse,
|
54
58
|
};
|
@@ -90,3 +90,29 @@ export const RequestObject = z.object({
|
|
90
90
|
scope: z.string().optional(),
|
91
91
|
presentation_definition: PresentationDefinition.optional(),
|
92
92
|
});
|
93
|
+
|
94
|
+
/**
|
95
|
+
* This type models the possible error responses the OpenID4VP protocol allows for a presentation of a credential.
|
96
|
+
* See https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html#name-error-response for more information.
|
97
|
+
*/
|
98
|
+
export type ErrorResponse = z.infer<typeof ErrorResponse>;
|
99
|
+
export const ErrorResponse = z.enum([
|
100
|
+
"invalid_scope",
|
101
|
+
"invalid_request",
|
102
|
+
"invalid_client",
|
103
|
+
"access_denied",
|
104
|
+
]);
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Type that defines the possible payload formats accepted by {@link buildDirectPostJwtBody} and {@link buildDirectPostBody}
|
108
|
+
*/
|
109
|
+
export type DirectAuthorizationBodyPayload = z.infer<
|
110
|
+
typeof DirectAuthorizationBodyPayload
|
111
|
+
>;
|
112
|
+
export const DirectAuthorizationBodyPayload = z.union([
|
113
|
+
z.object({
|
114
|
+
vp_token: z.string(),
|
115
|
+
presentation_submission: z.record(z.string(), z.unknown()),
|
116
|
+
}),
|
117
|
+
z.object({ error: ErrorResponse }),
|
118
|
+
]);
|
@@ -24,14 +24,17 @@ export const CredentialClaimDisplay = z.object({
|
|
24
24
|
|
25
25
|
export const CredentialFormat = z.union([
|
26
26
|
z.literal("vc+sd-jwt"),
|
27
|
-
z.literal("
|
27
|
+
z.literal("mso_mdoc"),
|
28
28
|
]);
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
);
|
29
|
+
|
30
|
+
export type CredentialClaim = z.infer<typeof CredentialClaim>;
|
31
|
+
export const CredentialClaim = z.object({
|
32
|
+
mandatory: z.boolean(),
|
33
|
+
display: z.array(CredentialClaimDisplay),
|
34
|
+
});
|
35
|
+
|
36
|
+
export type CredentialSdJwtClaims = z.infer<typeof CredentialSdJwtClaims>;
|
37
|
+
export const CredentialSdJwtClaims = z.record(CredentialClaim);
|
35
38
|
|
36
39
|
export type CredentialConfigurationSupported = z.infer<
|
37
40
|
typeof CredentialConfigurationSupported
|
@@ -39,12 +42,17 @@ export type CredentialConfigurationSupported = z.infer<
|
|
39
42
|
export const CredentialConfigurationSupported = z.record(
|
40
43
|
z.object({
|
41
44
|
cryptographic_suites_supported: z.array(z.string()),
|
42
|
-
vct: z.string(),
|
43
|
-
scope: z.string(),
|
45
|
+
vct: z.string().optional(),
|
46
|
+
scope: z.string().optional(),
|
44
47
|
cryptographic_binding_methods_supported: z.array(z.string()),
|
45
48
|
display: z.array(CredentialDisplay),
|
46
49
|
format: CredentialFormat,
|
47
|
-
claims:
|
50
|
+
claims: z
|
51
|
+
.union([
|
52
|
+
CredentialSdJwtClaims,
|
53
|
+
z.record(z.string(), CredentialSdJwtClaims),
|
54
|
+
])
|
55
|
+
.optional(),
|
48
56
|
})
|
49
57
|
);
|
50
58
|
|
@@ -70,7 +70,7 @@ const IssuanceErrorSupported = z.object({
|
|
70
70
|
// Metadata for a credentia which is supported by a Issuer
|
71
71
|
type SupportedCredentialMetadata = z.infer<typeof SupportedCredentialMetadata>;
|
72
72
|
const SupportedCredentialMetadata = z.object({
|
73
|
-
format: z.union([z.literal("vc+sd-jwt"), z.literal("
|
73
|
+
format: z.union([z.literal("vc+sd-jwt"), z.literal("mso_mdoc")]),
|
74
74
|
scope: z.string(),
|
75
75
|
display: z.array(CredentialDisplayMetadata),
|
76
76
|
claims: ClaimsMetadata.optional(), // TODO [SIW-1268]: should not be optional
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* Extracts the date value of a given elementIdentifier from an MDOC object.
|
3
|
+
* Searches through the issuerSigned namespaces and attempts to parse the value as a Date.
|
4
|
+
* The expected date format is "DD-MM-YYYY".
|
5
|
+
* Returns the Date object if found, otherwise returns null.
|
6
|
+
*/
|
7
|
+
export function extractElementValueAsDate(elementValue: string): Date | null {
|
8
|
+
if (typeof elementValue === "string") {
|
9
|
+
const dateParts = elementValue.split("-");
|
10
|
+
if (dateParts.length === 3) {
|
11
|
+
const [day, month, year] = dateParts.map((part) => Number(part));
|
12
|
+
if (
|
13
|
+
day !== undefined &&
|
14
|
+
month !== undefined &&
|
15
|
+
year !== undefined &&
|
16
|
+
!isNaN(day) &&
|
17
|
+
!isNaN(month) &&
|
18
|
+
!isNaN(year)
|
19
|
+
) {
|
20
|
+
return new Date(year, month - 1, day); // Month is zero-based in JS Date
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
return null; // Return null if no matching element is found or it's not a valid date
|
26
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { CBOR } from "@pagopa/io-react-native-cbor";
|
2
|
+
import type { JWK } from "../utils/jwk";
|
3
|
+
|
4
|
+
export const verify = async (
|
5
|
+
token: string,
|
6
|
+
publicKey: JWK | JWK[]
|
7
|
+
): Promise<{ mDoc: CBOR.MDOC }> => {
|
8
|
+
// get decoded data
|
9
|
+
const documents = await CBOR.decodeDocuments(token);
|
10
|
+
if (!documents || documents.documents.length === 0) {
|
11
|
+
throw new Error("Invalid mDoc");
|
12
|
+
}
|
13
|
+
const mDoc = documents.documents[0];
|
14
|
+
if (!mDoc) {
|
15
|
+
throw new Error("Invalid mDoc");
|
16
|
+
}
|
17
|
+
|
18
|
+
const sigKey = Array.isArray(publicKey)
|
19
|
+
? publicKey.find((k) => k.use === "sig")
|
20
|
+
: publicKey;
|
21
|
+
sigKey;
|
22
|
+
|
23
|
+
//await COSE.verify(mDoc.issuerSigned.issuerAuth, sigKey as PublicKey);
|
24
|
+
|
25
|
+
return {
|
26
|
+
mDoc,
|
27
|
+
};
|
28
|
+
};
|
package/src/utils/string.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import { Buffer } from "buffer";
|
2
|
+
|
1
3
|
/**
|
2
4
|
* Randomly obfuscates characters in a string by replacing them with a specified character.
|
3
5
|
*
|
@@ -43,3 +45,13 @@ export const obfuscateString = (
|
|
43
45
|
|
44
46
|
return chars.join("");
|
45
47
|
};
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Converts a hexadecimal byte string to a Base64 URL-encoded string.
|
51
|
+
*
|
52
|
+
* @param byteString - The input string in hexadecimal format.
|
53
|
+
* @returns The Base64 URL-encoded string.
|
54
|
+
*/
|
55
|
+
export const byteStringToBase64Url = (byteString: string): string => {
|
56
|
+
return Buffer.from(byteString, "hex").toString("base64");
|
57
|
+
};
|