@pagopa/io-react-native-wallet 1.1.2 → 1.2.2
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/presentation/01-start-flow.js +7 -5
- package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/commonjs/credential/presentation/03-get-request-object.js +47 -0
- package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -0
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +82 -0
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js +35 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js +63 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +169 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +202 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/commonjs/credential/presentation/README.md +43 -4
- package/lib/commonjs/credential/presentation/errors.js +52 -1
- package/lib/commonjs/credential/presentation/errors.js.map +1 -1
- package/lib/commonjs/credential/presentation/index.js +27 -6
- package/lib/commonjs/credential/presentation/index.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js +69 -4
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/commonjs/entity/trust/types.js +4 -1
- package/lib/commonjs/entity/trust/types.js.map +1 -1
- package/lib/module/credential/presentation/01-start-flow.js +8 -6
- package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/module/credential/presentation/03-get-request-object.js +39 -0
- package/lib/module/credential/presentation/03-get-request-object.js.map +1 -0
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +75 -0
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/module/credential/presentation/05-verify-request-object.js +28 -0
- package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js +56 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +161 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js +188 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/module/credential/presentation/README.md +43 -4
- package/lib/module/credential/presentation/errors.js +48 -0
- package/lib/module/credential/presentation/errors.js.map +1 -1
- package/lib/module/credential/presentation/index.js +7 -4
- package/lib/module/credential/presentation/index.js.map +1 -1
- package/lib/module/credential/presentation/types.js +67 -3
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/module/entity/trust/types.js +4 -1
- package/lib/module/entity/trust/types.js.map +1 -1
- package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/{04-get-request-object.d.ts → 03-get-request-object.d.ts} +3 -5
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/{03-retrieve-jwks.d.ts → 04-retrieve-rp-jwks.d.ts} +5 -4
- package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +8 -0
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts +26 -0
- package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +27 -0
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +99 -0
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/errors.d.ts +33 -0
- package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/index.d.ts +8 -5
- package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +612 -9
- package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
- package/lib/typescript/entity/trust/index.d.ts +152 -0
- package/lib/typescript/entity/trust/index.d.ts.map +1 -1
- package/lib/typescript/entity/trust/types.d.ts +2088 -0
- package/lib/typescript/entity/trust/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/credential/presentation/01-start-flow.ts +10 -6
- package/src/credential/presentation/{04-get-request-object.ts → 03-get-request-object.ts} +6 -51
- package/src/credential/presentation/{03-retrieve-jwks.ts → 04-retrieve-rp-jwks.ts} +39 -24
- package/src/credential/presentation/05-verify-request-object.ts +35 -0
- package/src/credential/presentation/06-fetch-presentation-definition.ts +78 -0
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +204 -0
- package/src/credential/presentation/08-send-authorization-response.ts +251 -0
- package/src/credential/presentation/README.md +43 -4
- package/src/credential/presentation/errors.ts +48 -0
- package/src/credential/presentation/index.ts +27 -9
- package/src/credential/presentation/types.ts +59 -3
- package/src/entity/trust/types.ts +3 -0
- package/lib/commonjs/credential/presentation/03-retrieve-jwks.js +0 -68
- package/lib/commonjs/credential/presentation/03-retrieve-jwks.js.map +0 -1
- package/lib/commonjs/credential/presentation/04-get-request-object.js +0 -82
- package/lib/commonjs/credential/presentation/04-get-request-object.js.map +0 -1
- package/lib/commonjs/credential/presentation/05-send-authorization-response.js +0 -139
- package/lib/commonjs/credential/presentation/05-send-authorization-response.js.map +0 -1
- package/lib/module/credential/presentation/03-retrieve-jwks.js +0 -61
- package/lib/module/credential/presentation/03-retrieve-jwks.js.map +0 -1
- package/lib/module/credential/presentation/04-get-request-object.js +0 -74
- package/lib/module/credential/presentation/04-get-request-object.js.map +0 -1
- package/lib/module/credential/presentation/05-send-authorization-response.js +0 -128
- package/lib/module/credential/presentation/05-send-authorization-response.js.map +0 -1
- package/lib/typescript/credential/presentation/03-retrieve-jwks.d.ts.map +0 -1
- package/lib/typescript/credential/presentation/04-get-request-object.d.ts.map +0 -1
- package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts +0 -34
- package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts.map +0 -1
- package/src/credential/presentation/05-send-authorization-response.ts +0 -168
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.sendAuthorizationResponse = exports.AuthorizationResponse = void 0;
|
|
7
|
-
var _ioReactNativeJwt = require("@pagopa/io-react-native-jwt");
|
|
8
|
-
var _reactNativeUuid = _interopRequireDefault(require("react-native-uuid"));
|
|
9
|
-
var WalletInstanceAttestation = _interopRequireWildcard(require("../../wallet-instance-attestation"));
|
|
10
|
-
var _errors = require("./errors");
|
|
11
|
-
var _misc = require("../../utils/misc");
|
|
12
|
-
var _sdJwt = require("../../sd-jwt");
|
|
13
|
-
var z = _interopRequireWildcard(require("zod"));
|
|
14
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
15
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
16
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
const AuthorizationResponse = z.object({
|
|
18
|
-
status: z.string(),
|
|
19
|
-
response_code: z.string() /**
|
|
20
|
-
FIXME: [SIW-627] we expect this value from every RP implementation
|
|
21
|
-
Actually some RP does not return the value
|
|
22
|
-
We make it optional to not break the flow.
|
|
23
|
-
*/.optional()
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Choose an RSA public key from those offered by the RP for encryption.
|
|
28
|
-
*
|
|
29
|
-
* @param entity The RP entity configuration
|
|
30
|
-
* @returns A suitable public key with its compatible encryption algorithm
|
|
31
|
-
* @throws {NoSuitableKeysFoundInEntityConfiguration} If entity do not contain any public key suitable for encrypting
|
|
32
|
-
*/
|
|
33
|
-
exports.AuthorizationResponse = AuthorizationResponse;
|
|
34
|
-
const chooseRSAPublicKeyToEncrypt = entity => {
|
|
35
|
-
const [usingRsa256] = entity.wallet_relying_party.jwks.keys.filter(jwk => jwk.use === "enc" && jwk.kty === "RSA");
|
|
36
|
-
if (usingRsa256) {
|
|
37
|
-
return usingRsa256;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// No suitable key has been found
|
|
41
|
-
throw new _errors.NoSuitableKeysFoundInEntityConfiguration("Encrypt with RP public key");
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Generate a Verified Presentation token for a received request object within the context of an authorization request flow.
|
|
46
|
-
* The presentation is created by revealing data from the provided credentials based on the requested claims.
|
|
47
|
-
* Each Verified Credential is accompanied by the claims that the user consents to disclose from it.
|
|
48
|
-
*
|
|
49
|
-
* @todo: Allow for handling more than one Verified Credential.
|
|
50
|
-
*/
|
|
51
|
-
const prepareVpToken = async (requestObject, walletInstanceAttestation, _ref) => {
|
|
52
|
-
let [vc, claims, cryptoCtx] = _ref;
|
|
53
|
-
// this throws if vc cannot satisfy all the requested claims
|
|
54
|
-
const {
|
|
55
|
-
token: vp,
|
|
56
|
-
paths
|
|
57
|
-
} = await (0, _sdJwt.disclose)(vc, claims);
|
|
58
|
-
|
|
59
|
-
// obtain issuer from Wallet Instance
|
|
60
|
-
const {
|
|
61
|
-
payload: {
|
|
62
|
-
iss
|
|
63
|
-
}
|
|
64
|
-
} = WalletInstanceAttestation.decode(walletInstanceAttestation);
|
|
65
|
-
const pidKid = await cryptoCtx.getPublicKey().then(_ => _.kid);
|
|
66
|
-
|
|
67
|
-
// TODO: [SIW-359] check all requeste claims of the requestedObj are satisfied
|
|
68
|
-
const vp_token = await new _ioReactNativeJwt.SignJWT(cryptoCtx).setProtectedHeader({
|
|
69
|
-
typ: "JWT",
|
|
70
|
-
kid: pidKid
|
|
71
|
-
}).setPayload({
|
|
72
|
-
vp: vp,
|
|
73
|
-
jti: `${_reactNativeUuid.default.v4()}`,
|
|
74
|
-
iss,
|
|
75
|
-
nonce: requestObject.nonce
|
|
76
|
-
}).setAudience(requestObject.response_uri).setIssuedAt().setExpirationTime("1h").sign();
|
|
77
|
-
const vc_scope = requestObject.scope;
|
|
78
|
-
const presentation_submission = {
|
|
79
|
-
definition_id: `${_reactNativeUuid.default.v4()}`,
|
|
80
|
-
id: `${_reactNativeUuid.default.v4()}`,
|
|
81
|
-
descriptor_map: paths.map(p => ({
|
|
82
|
-
id: vc_scope,
|
|
83
|
-
path: `$.vp_token.${p.path}`,
|
|
84
|
-
format: "vc+sd-jwt"
|
|
85
|
-
}))
|
|
86
|
-
};
|
|
87
|
-
return {
|
|
88
|
-
vp_token,
|
|
89
|
-
presentation_submission
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Complete the presentation flow by sending the authorization response to the Relying Party
|
|
94
|
-
*
|
|
95
|
-
* @param requestObject The Request Object that describes the presentation
|
|
96
|
-
* @param rpConf The Relying Party's configuration
|
|
97
|
-
* @param presentation The presentation tuple consisting in the signed credential,
|
|
98
|
-
* the list of claims to be disclosed, and the context to access the key that proves the holder binding
|
|
99
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
|
100
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
|
101
|
-
* @returns The result of the presentation flow
|
|
102
|
-
*/
|
|
103
|
-
const sendAuthorizationResponse = async (requestObject, rpConf, presentation, _ref2) => {
|
|
104
|
-
let {
|
|
105
|
-
appFetch = fetch,
|
|
106
|
-
walletInstanceAttestation
|
|
107
|
-
} = _ref2;
|
|
108
|
-
// the request is an unsigned jws without iss, aud, exp
|
|
109
|
-
// https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-signed-and-encrypted-respon
|
|
110
|
-
const rsaPublicJwk = chooseRSAPublicKeyToEncrypt(rpConf);
|
|
111
|
-
const {
|
|
112
|
-
vp_token,
|
|
113
|
-
presentation_submission
|
|
114
|
-
} = await prepareVpToken(requestObject, walletInstanceAttestation, presentation);
|
|
115
|
-
const authzResponsePayload = JSON.stringify({
|
|
116
|
-
state: requestObject.state,
|
|
117
|
-
presentation_submission,
|
|
118
|
-
nonce: requestObject.nonce,
|
|
119
|
-
vp_token
|
|
120
|
-
});
|
|
121
|
-
const encrypted = await new _ioReactNativeJwt.EncryptJwe(authzResponsePayload, {
|
|
122
|
-
alg: "RSA-OAEP-256",
|
|
123
|
-
enc: "A256CBC-HS512",
|
|
124
|
-
kid: rsaPublicJwk.kid
|
|
125
|
-
}).encrypt(rsaPublicJwk);
|
|
126
|
-
const formBody = new URLSearchParams({
|
|
127
|
-
response: encrypted
|
|
128
|
-
});
|
|
129
|
-
const body = formBody.toString();
|
|
130
|
-
return appFetch(requestObject.response_uri, {
|
|
131
|
-
method: "POST",
|
|
132
|
-
headers: {
|
|
133
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
134
|
-
},
|
|
135
|
-
body
|
|
136
|
-
}).then((0, _misc.hasStatusOrThrow)(200)).then(res => res.json()).then(AuthorizationResponse.parse);
|
|
137
|
-
};
|
|
138
|
-
exports.sendAuthorizationResponse = sendAuthorizationResponse;
|
|
139
|
-
//# sourceMappingURL=05-send-authorization-response.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_ioReactNativeJwt","require","_reactNativeUuid","_interopRequireDefault","WalletInstanceAttestation","_interopRequireWildcard","_errors","_misc","_sdJwt","z","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","AuthorizationResponse","object","status","string","response_code","optional","exports","chooseRSAPublicKeyToEncrypt","entity","usingRsa256","wallet_relying_party","jwks","keys","filter","jwk","use","kty","NoSuitableKeysFoundInEntityConfiguration","prepareVpToken","requestObject","walletInstanceAttestation","_ref","vc","claims","cryptoCtx","token","vp","paths","disclose","payload","iss","decode","pidKid","getPublicKey","then","_","kid","vp_token","SignJWT","setProtectedHeader","typ","setPayload","jti","uuid","v4","nonce","setAudience","response_uri","setIssuedAt","setExpirationTime","sign","vc_scope","scope","presentation_submission","definition_id","id","descriptor_map","map","p","path","format","sendAuthorizationResponse","rpConf","presentation","_ref2","appFetch","fetch","rsaPublicJwk","authzResponsePayload","JSON","stringify","state","encrypted","EncryptJwe","alg","enc","encrypt","formBody","URLSearchParams","response","body","toString","method","headers","hasStatusOrThrow","res","json","parse"],"sourceRoot":"../../../../src","sources":["credential/presentation/05-send-authorization-response.ts"],"mappings":"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"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { JWKS } from "../../utils/jwk";
|
|
2
|
-
import { hasStatusOrThrow } from "../../utils/misc";
|
|
3
|
-
import { RelyingPartyEntityConfiguration } from "../../entity/trust/types";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Defines the signature for a function that retrieves JSON Web Key Sets (JWKS) from a client.
|
|
7
|
-
*
|
|
8
|
-
* @template T - The tuple type representing the function arguments.
|
|
9
|
-
* @param args - The arguments passed to the function.
|
|
10
|
-
* @returns A promise resolving to an object containing an array of JWKs.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Retrieves the JSON Web Key Set (JWKS) from the specified client's well-known endpoint.
|
|
15
|
-
*
|
|
16
|
-
* @param clientUrl - The base URL of the client entity from which to retrieve the JWKS.
|
|
17
|
-
* @param options - Optional context containing a custom fetch implementation.
|
|
18
|
-
* @param options.context - Optional context object.
|
|
19
|
-
* @param options.context.appFetch - Optional custom fetch function to use instead of the global `fetch`.
|
|
20
|
-
* @returns A promise resolving to an object containing an array of JWKs.
|
|
21
|
-
* @throws Will throw an error if the JWKS retrieval fails.
|
|
22
|
-
*/
|
|
23
|
-
export const fetchJwksFromUri = async function (clientUrl) {
|
|
24
|
-
let {
|
|
25
|
-
context = {}
|
|
26
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
27
|
-
const {
|
|
28
|
-
appFetch = fetch
|
|
29
|
-
} = context;
|
|
30
|
-
const wellKnownUrl = new URL("/.well-known/jar-issuer/jwk", clientUrl).toString();
|
|
31
|
-
|
|
32
|
-
// Fetches the JWKS from a specific endpoint of the entity's well-known configuration
|
|
33
|
-
const jwks = await appFetch(wellKnownUrl, {
|
|
34
|
-
method: "GET"
|
|
35
|
-
}).then(hasStatusOrThrow(200)).then(raw => raw.json()).then(json => JWKS.parse(json));
|
|
36
|
-
return {
|
|
37
|
-
keys: jwks.keys
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Retrieves the JSON Web Key Set (JWKS) from a Relying Party's entity configuration.
|
|
43
|
-
*
|
|
44
|
-
* @param rpConfig - The configuration object of the Relying Party entity.
|
|
45
|
-
* @returns An object containing an array of JWKs.
|
|
46
|
-
* @throws Will throw an error if the configuration is invalid or if JWKS is not found.
|
|
47
|
-
*/
|
|
48
|
-
export const fetchJwksFromConfig = async rpConfig => {
|
|
49
|
-
const parsedConfig = RelyingPartyEntityConfiguration.safeParse(rpConfig);
|
|
50
|
-
if (!parsedConfig.success) {
|
|
51
|
-
throw new Error("Invalid Relying Party configuration.");
|
|
52
|
-
}
|
|
53
|
-
const jwks = parsedConfig.data.payload.metadata.wallet_relying_party.jwks;
|
|
54
|
-
if (!jwks || !Array.isArray(jwks.keys)) {
|
|
55
|
-
throw new Error("JWKS not found in Relying Party configuration.");
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
keys: jwks.keys
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
//# sourceMappingURL=03-retrieve-jwks.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["JWKS","hasStatusOrThrow","RelyingPartyEntityConfiguration","fetchJwksFromUri","clientUrl","context","arguments","length","undefined","appFetch","fetch","wellKnownUrl","URL","toString","jwks","method","then","raw","json","parse","keys","fetchJwksFromConfig","rpConfig","parsedConfig","safeParse","success","Error","data","payload","metadata","wallet_relying_party","Array","isArray"],"sourceRoot":"../../../../src","sources":["credential/presentation/03-retrieve-jwks.ts"],"mappings":"AAAA,SAASA,IAAI,QAAa,iBAAiB;AAC3C,SAASC,gBAAgB,QAAQ,kBAAkB;AACnD,SAASC,+BAA+B,QAAQ,0BAA0B;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAEZ,GAAG,eAAAA,CAAOC,SAAS,EAA4B;EAAA,IAA1B;IAAEC,OAAO,GAAG,CAAC;EAAE,CAAC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EACzC,MAAM;IAAEG,QAAQ,GAAGC;EAAM,CAAC,GAAGL,OAAO;EAEpC,MAAMM,YAAY,GAAG,IAAIC,GAAG,CAC1B,6BAA6B,EAC7BR,SACF,CAAC,CAACS,QAAQ,CAAC,CAAC;;EAEZ;EACA,MAAMC,IAAI,GAAG,MAAML,QAAQ,CAACE,YAAY,EAAE;IACxCI,MAAM,EAAE;EACV,CAAC,CAAC,CACCC,IAAI,CAACf,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3Be,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAEE,IAAI,IAAKlB,IAAI,CAACmB,KAAK,CAACD,IAAI,CAAC,CAAC;EAEnC,OAAO;IACLE,IAAI,EAAEN,IAAI,CAACM;EACb,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,mBAEZ,GAAG,MAAOC,QAAQ,IAAK;EACtB,MAAMC,YAAY,GAAGrB,+BAA+B,CAACsB,SAAS,CAACF,QAAQ,CAAC;EACxE,IAAI,CAACC,YAAY,CAACE,OAAO,EAAE;IACzB,MAAM,IAAIC,KAAK,CAAC,sCAAsC,CAAC;EACzD;EAEA,MAAMZ,IAAI,GAAGS,YAAY,CAACI,IAAI,CAACC,OAAO,CAACC,QAAQ,CAACC,oBAAoB,CAAChB,IAAI;EAEzE,IAAI,CAACA,IAAI,IAAI,CAACiB,KAAK,CAACC,OAAO,CAAClB,IAAI,CAACM,IAAI,CAAC,EAAE;IACtC,MAAM,IAAIM,KAAK,CAAC,gDAAgD,CAAC;EACnE;EAEA,OAAO;IACLN,IAAI,EAAEN,IAAI,CAACM;EACb,CAAC;AACH,CAAC"}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import uuid from "react-native-uuid";
|
|
2
|
-
import { decode as decodeJwt, sha256ToBase64, verify } from "@pagopa/io-react-native-jwt";
|
|
3
|
-
import { createDPopToken } from "../../utils/dpop";
|
|
4
|
-
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
|
|
5
|
-
import { hasStatusOrThrow } from "../../utils/misc";
|
|
6
|
-
import { RequestObject } from "./types";
|
|
7
|
-
/**
|
|
8
|
-
* Obtain the Request Object for RP authentication
|
|
9
|
-
* @see https://italia.github.io/eudi-wallet-it-docs/versione-corrente/en/relying-party-solution.html
|
|
10
|
-
*
|
|
11
|
-
* @param requestUri The url for the Relying Party to connect with
|
|
12
|
-
* @param rpConf The Relying Party's configuration
|
|
13
|
-
* @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
|
|
14
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
|
15
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
|
16
|
-
* @returns The Request Object that describes the presentation
|
|
17
|
-
*/
|
|
18
|
-
export const getRequestObject = async (requestUri, _ref, jwkKeys) => {
|
|
19
|
-
let {
|
|
20
|
-
wiaCryptoContext,
|
|
21
|
-
appFetch = fetch,
|
|
22
|
-
walletInstanceAttestation
|
|
23
|
-
} = _ref;
|
|
24
|
-
const signedWalletInstanceDPoP = await createDPopToken({
|
|
25
|
-
jti: `${uuid.v4()}`,
|
|
26
|
-
htm: "GET",
|
|
27
|
-
htu: requestUri,
|
|
28
|
-
ath: await sha256ToBase64(walletInstanceAttestation)
|
|
29
|
-
}, wiaCryptoContext);
|
|
30
|
-
const responseEncodedJwt = await appFetch(requestUri, {
|
|
31
|
-
method: "GET",
|
|
32
|
-
headers: {
|
|
33
|
-
Authorization: `DPoP ${walletInstanceAttestation}`,
|
|
34
|
-
DPoP: signedWalletInstanceDPoP
|
|
35
|
-
}
|
|
36
|
-
}).then(hasStatusOrThrow(200)).then(res => res.json()).then(responseJson => responseJson.response);
|
|
37
|
-
const responseJwt = decodeJwt(responseEncodedJwt);
|
|
38
|
-
await verifyTokenSignature(jwkKeys, responseJwt);
|
|
39
|
-
|
|
40
|
-
// Ensure that the request object conforms to the expected specification.
|
|
41
|
-
const requestObject = RequestObject.parse(responseJwt.payload);
|
|
42
|
-
return {
|
|
43
|
-
requestObject
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
const verifyTokenSignature = async (jwkKeys, responseJwt) => {
|
|
47
|
-
var _responseJwt$protecte;
|
|
48
|
-
// verify token signature to ensure the request object is authentic
|
|
49
|
-
// 1. according to entity configuration if present
|
|
50
|
-
if (jwkKeys) {
|
|
51
|
-
const pubKey = jwkKeys.find(_ref2 => {
|
|
52
|
-
let {
|
|
53
|
-
kid
|
|
54
|
-
} = _ref2;
|
|
55
|
-
return kid === responseJwt.protectedHeader.kid;
|
|
56
|
-
});
|
|
57
|
-
if (!pubKey) {
|
|
58
|
-
throw new NoSuitableKeysFoundInEntityConfiguration("Request Object signature verification");
|
|
59
|
-
}
|
|
60
|
-
await verify(responseJwt, pubKey);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// 2. If jwk is not retrieved from entity config, check if the token contains the 'jwk' attribute
|
|
65
|
-
if ((_responseJwt$protecte = responseJwt.protectedHeader) !== null && _responseJwt$protecte !== void 0 && _responseJwt$protecte.jwk) {
|
|
66
|
-
const pubKey = responseJwt.protectedHeader.jwk;
|
|
67
|
-
await verify(responseJwt, pubKey);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// No verification condition matched: skipping signature verification for now.
|
|
72
|
-
// TODO: [EUDIW-215] Remove skipping signature verification
|
|
73
|
-
};
|
|
74
|
-
//# sourceMappingURL=04-get-request-object.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["uuid","decode","decodeJwt","sha256ToBase64","verify","createDPopToken","NoSuitableKeysFoundInEntityConfiguration","hasStatusOrThrow","RequestObject","getRequestObject","requestUri","_ref","jwkKeys","wiaCryptoContext","appFetch","fetch","walletInstanceAttestation","signedWalletInstanceDPoP","jti","v4","htm","htu","ath","responseEncodedJwt","method","headers","Authorization","DPoP","then","res","json","responseJson","response","responseJwt","verifyTokenSignature","requestObject","parse","payload","_responseJwt$protecte","pubKey","find","_ref2","kid","protectedHeader","jwk"],"sourceRoot":"../../../../src","sources":["credential/presentation/04-get-request-object.ts"],"mappings":"AAAA,OAAOA,IAAI,MAAM,mBAAmB;AACpC,SACEC,MAAM,IAAIC,SAAS,EACnBC,cAAc,EACdC,MAAM,QAED,6BAA6B;AAEpC,SAASC,eAAe,QAAQ,kBAAkB;AAClD,SAASC,wCAAwC,QAAQ,UAAU;AAEnE,SAASC,gBAAgB,QAAkB,kBAAkB;AAE7D,SAASC,aAAa,QAAQ,SAAS;AAYvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAkC,GAAG,MAAAA,CAChDC,UAAU,EAAAC,IAAA,EAEVC,OAAO,KACJ;EAAA,IAFH;IAAEC,gBAAgB;IAAEC,QAAQ,GAAGC,KAAK;IAAEC;EAA0B,CAAC,GAAAL,IAAA;EAGjE,MAAMM,wBAAwB,GAAG,MAAMZ,eAAe,CACpD;IACEa,GAAG,EAAG,GAAElB,IAAI,CAACmB,EAAE,CAAC,CAAE,EAAC;IACnBC,GAAG,EAAE,KAAK;IACVC,GAAG,EAAEX,UAAU;IACfY,GAAG,EAAE,MAAMnB,cAAc,CAACa,yBAAyB;EACrD,CAAC,EACDH,gBACF,CAAC;EAED,MAAMU,kBAAkB,GAAG,MAAMT,QAAQ,CAACJ,UAAU,EAAE;IACpDc,MAAM,EAAE,KAAK;IACbC,OAAO,EAAE;MACPC,aAAa,EAAG,QAAOV,yBAA0B,EAAC;MAClDW,IAAI,EAAEV;IACR;EACF,CAAC,CAAC,CACCW,IAAI,CAACrB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BqB,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAEG,YAAY,IAAKA,YAAY,CAACC,QAAQ,CAAC;EAEhD,MAAMC,WAAW,GAAG/B,SAAS,CAACqB,kBAAkB,CAAC;EAEjD,MAAMW,oBAAoB,CAACtB,OAAO,EAAEqB,WAAW,CAAC;;EAEhD;EACA,MAAME,aAAa,GAAG3B,aAAa,CAAC4B,KAAK,CAACH,WAAW,CAACI,OAAO,CAAC;EAE9D,OAAO;IACLF;EACF,CAAC;AACH,CAAC;AAED,MAAMD,oBAAoB,GAAG,MAAAA,CAC3BtB,OAAgC,EAChCqB,WAAiB,KACC;EAAA,IAAAK,qBAAA;EAClB;EACA;EACA,IAAI1B,OAAO,EAAE;IACX,MAAM2B,MAAM,GAAG3B,OAAO,CAAC4B,IAAI,CACzBC,KAAA;MAAA,IAAC;QAAEC;MAAI,CAAC,GAAAD,KAAA;MAAA,OAAKC,GAAG,KAAKT,WAAW,CAACU,eAAe,CAACD,GAAG;IAAA,CACtD,CAAC;IACD,IAAI,CAACH,MAAM,EAAE;MACX,MAAM,IAAIjC,wCAAwC,CAChD,uCACF,CAAC;IACH;IACA,MAAMF,MAAM,CAAC6B,WAAW,EAAEM,MAAM,CAAC;IACjC;EACF;;EAEA;EACA,KAAAD,qBAAA,GAAIL,WAAW,CAACU,eAAe,cAAAL,qBAAA,eAA3BA,qBAAA,CAA6BM,GAAG,EAAE;IACpC,MAAML,MAAM,GAAGN,WAAW,CAACU,eAAe,CAACC,GAAG;IAC9C,MAAMxC,MAAM,CAAC6B,WAAW,EAAEM,MAAM,CAAC;IACjC;EACF;;EAEA;EACA;AACF,CAAC"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { EncryptJwe, SignJWT } from "@pagopa/io-react-native-jwt";
|
|
2
|
-
import uuid from "react-native-uuid";
|
|
3
|
-
import * as WalletInstanceAttestation from "../../wallet-instance-attestation";
|
|
4
|
-
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
|
|
5
|
-
import { hasStatusOrThrow } from "../../utils/misc";
|
|
6
|
-
import { disclose } from "../../sd-jwt";
|
|
7
|
-
import * as z from "zod";
|
|
8
|
-
export const AuthorizationResponse = z.object({
|
|
9
|
-
status: z.string(),
|
|
10
|
-
response_code: z.string() /**
|
|
11
|
-
FIXME: [SIW-627] we expect this value from every RP implementation
|
|
12
|
-
Actually some RP does not return the value
|
|
13
|
-
We make it optional to not break the flow.
|
|
14
|
-
*/.optional()
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Choose an RSA public key from those offered by the RP for encryption.
|
|
19
|
-
*
|
|
20
|
-
* @param entity The RP entity configuration
|
|
21
|
-
* @returns A suitable public key with its compatible encryption algorithm
|
|
22
|
-
* @throws {NoSuitableKeysFoundInEntityConfiguration} If entity do not contain any public key suitable for encrypting
|
|
23
|
-
*/
|
|
24
|
-
const chooseRSAPublicKeyToEncrypt = entity => {
|
|
25
|
-
const [usingRsa256] = entity.wallet_relying_party.jwks.keys.filter(jwk => jwk.use === "enc" && jwk.kty === "RSA");
|
|
26
|
-
if (usingRsa256) {
|
|
27
|
-
return usingRsa256;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// No suitable key has been found
|
|
31
|
-
throw new NoSuitableKeysFoundInEntityConfiguration("Encrypt with RP public key");
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Generate a Verified Presentation token for a received request object within the context of an authorization request flow.
|
|
36
|
-
* The presentation is created by revealing data from the provided credentials based on the requested claims.
|
|
37
|
-
* Each Verified Credential is accompanied by the claims that the user consents to disclose from it.
|
|
38
|
-
*
|
|
39
|
-
* @todo: Allow for handling more than one Verified Credential.
|
|
40
|
-
*/
|
|
41
|
-
const prepareVpToken = async (requestObject, walletInstanceAttestation, _ref) => {
|
|
42
|
-
let [vc, claims, cryptoCtx] = _ref;
|
|
43
|
-
// this throws if vc cannot satisfy all the requested claims
|
|
44
|
-
const {
|
|
45
|
-
token: vp,
|
|
46
|
-
paths
|
|
47
|
-
} = await disclose(vc, claims);
|
|
48
|
-
|
|
49
|
-
// obtain issuer from Wallet Instance
|
|
50
|
-
const {
|
|
51
|
-
payload: {
|
|
52
|
-
iss
|
|
53
|
-
}
|
|
54
|
-
} = WalletInstanceAttestation.decode(walletInstanceAttestation);
|
|
55
|
-
const pidKid = await cryptoCtx.getPublicKey().then(_ => _.kid);
|
|
56
|
-
|
|
57
|
-
// TODO: [SIW-359] check all requeste claims of the requestedObj are satisfied
|
|
58
|
-
const vp_token = await new SignJWT(cryptoCtx).setProtectedHeader({
|
|
59
|
-
typ: "JWT",
|
|
60
|
-
kid: pidKid
|
|
61
|
-
}).setPayload({
|
|
62
|
-
vp: vp,
|
|
63
|
-
jti: `${uuid.v4()}`,
|
|
64
|
-
iss,
|
|
65
|
-
nonce: requestObject.nonce
|
|
66
|
-
}).setAudience(requestObject.response_uri).setIssuedAt().setExpirationTime("1h").sign();
|
|
67
|
-
const vc_scope = requestObject.scope;
|
|
68
|
-
const presentation_submission = {
|
|
69
|
-
definition_id: `${uuid.v4()}`,
|
|
70
|
-
id: `${uuid.v4()}`,
|
|
71
|
-
descriptor_map: paths.map(p => ({
|
|
72
|
-
id: vc_scope,
|
|
73
|
-
path: `$.vp_token.${p.path}`,
|
|
74
|
-
format: "vc+sd-jwt"
|
|
75
|
-
}))
|
|
76
|
-
};
|
|
77
|
-
return {
|
|
78
|
-
vp_token,
|
|
79
|
-
presentation_submission
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Complete the presentation flow by sending the authorization response to the Relying Party
|
|
84
|
-
*
|
|
85
|
-
* @param requestObject The Request Object that describes the presentation
|
|
86
|
-
* @param rpConf The Relying Party's configuration
|
|
87
|
-
* @param presentation The presentation tuple consisting in the signed credential,
|
|
88
|
-
* the list of claims to be disclosed, and the context to access the key that proves the holder binding
|
|
89
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
|
90
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
|
91
|
-
* @returns The result of the presentation flow
|
|
92
|
-
*/
|
|
93
|
-
export const sendAuthorizationResponse = async (requestObject, rpConf, presentation, _ref2) => {
|
|
94
|
-
let {
|
|
95
|
-
appFetch = fetch,
|
|
96
|
-
walletInstanceAttestation
|
|
97
|
-
} = _ref2;
|
|
98
|
-
// the request is an unsigned jws without iss, aud, exp
|
|
99
|
-
// https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-signed-and-encrypted-respon
|
|
100
|
-
const rsaPublicJwk = chooseRSAPublicKeyToEncrypt(rpConf);
|
|
101
|
-
const {
|
|
102
|
-
vp_token,
|
|
103
|
-
presentation_submission
|
|
104
|
-
} = await prepareVpToken(requestObject, walletInstanceAttestation, presentation);
|
|
105
|
-
const authzResponsePayload = JSON.stringify({
|
|
106
|
-
state: requestObject.state,
|
|
107
|
-
presentation_submission,
|
|
108
|
-
nonce: requestObject.nonce,
|
|
109
|
-
vp_token
|
|
110
|
-
});
|
|
111
|
-
const encrypted = await new EncryptJwe(authzResponsePayload, {
|
|
112
|
-
alg: "RSA-OAEP-256",
|
|
113
|
-
enc: "A256CBC-HS512",
|
|
114
|
-
kid: rsaPublicJwk.kid
|
|
115
|
-
}).encrypt(rsaPublicJwk);
|
|
116
|
-
const formBody = new URLSearchParams({
|
|
117
|
-
response: encrypted
|
|
118
|
-
});
|
|
119
|
-
const body = formBody.toString();
|
|
120
|
-
return appFetch(requestObject.response_uri, {
|
|
121
|
-
method: "POST",
|
|
122
|
-
headers: {
|
|
123
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
124
|
-
},
|
|
125
|
-
body
|
|
126
|
-
}).then(hasStatusOrThrow(200)).then(res => res.json()).then(AuthorizationResponse.parse);
|
|
127
|
-
};
|
|
128
|
-
//# sourceMappingURL=05-send-authorization-response.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["EncryptJwe","SignJWT","uuid","WalletInstanceAttestation","NoSuitableKeysFoundInEntityConfiguration","hasStatusOrThrow","disclose","z","AuthorizationResponse","object","status","string","response_code","optional","chooseRSAPublicKeyToEncrypt","entity","usingRsa256","wallet_relying_party","jwks","keys","filter","jwk","use","kty","prepareVpToken","requestObject","walletInstanceAttestation","_ref","vc","claims","cryptoCtx","token","vp","paths","payload","iss","decode","pidKid","getPublicKey","then","_","kid","vp_token","setProtectedHeader","typ","setPayload","jti","v4","nonce","setAudience","response_uri","setIssuedAt","setExpirationTime","sign","vc_scope","scope","presentation_submission","definition_id","id","descriptor_map","map","p","path","format","sendAuthorizationResponse","rpConf","presentation","_ref2","appFetch","fetch","rsaPublicJwk","authzResponsePayload","JSON","stringify","state","encrypted","alg","enc","encrypt","formBody","URLSearchParams","response","body","toString","method","headers","res","json","parse"],"sourceRoot":"../../../../src","sources":["credential/presentation/05-send-authorization-response.ts"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"03-retrieve-jwks.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/03-retrieve-jwks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,+BAA+B,EAAE,MAAM,0BAA0B,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC7E,IAAI,EAAE,GAAG,EAAE,CAAC;CACb,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,CACtC;IAAC,MAAM;IAAE;QAAE,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;SAAE,CAAA;KAAE;CAAC,CAoB5D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CACzC;IAAC,+BAA+B;CAAC,CAgBlC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"04-get-request-object.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/04-get-request-object.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAoB,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,MAAM,gBAAgB,GAAG,CAC7B,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,EACxC,OAAO,EAAE;IACP,gBAAgB,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAChC,yBAAyB,EAAE,MAAM,CAAC;CACnC,EACD,OAAO,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAC7B,OAAO,CAAC;IAAE,aAAa,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAoC9B,CAAC"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { type Out } from "../../utils/misc";
|
|
2
|
-
import type { GetRequestObject } from "./04-get-request-object";
|
|
3
|
-
import type { EvaluateRelyingPartyTrust } from "./02-evaluate-rp-trust";
|
|
4
|
-
import { type Presentation } from "./types";
|
|
5
|
-
import * as z from "zod";
|
|
6
|
-
export type AuthorizationResponse = z.infer<typeof AuthorizationResponse>;
|
|
7
|
-
export declare const AuthorizationResponse: z.ZodObject<{
|
|
8
|
-
status: z.ZodString;
|
|
9
|
-
response_code: z.ZodOptional<z.ZodString>;
|
|
10
|
-
}, "strip", z.ZodTypeAny, {
|
|
11
|
-
status: string;
|
|
12
|
-
response_code?: string | undefined;
|
|
13
|
-
}, {
|
|
14
|
-
status: string;
|
|
15
|
-
response_code?: string | undefined;
|
|
16
|
-
}>;
|
|
17
|
-
export type SendAuthorizationResponse = (requestObject: Out<GetRequestObject>["requestObject"], rpConf: Out<EvaluateRelyingPartyTrust>["rpConf"], presentation: Presentation, // TODO: [SIW-353] support multiple presentations
|
|
18
|
-
context: {
|
|
19
|
-
walletInstanceAttestation: string;
|
|
20
|
-
appFetch?: GlobalFetch["fetch"];
|
|
21
|
-
}) => Promise<AuthorizationResponse>;
|
|
22
|
-
/**
|
|
23
|
-
* Complete the presentation flow by sending the authorization response to the Relying Party
|
|
24
|
-
*
|
|
25
|
-
* @param requestObject The Request Object that describes the presentation
|
|
26
|
-
* @param rpConf The Relying Party's configuration
|
|
27
|
-
* @param presentation The presentation tuple consisting in the signed credential,
|
|
28
|
-
* the list of claims to be disclosed, and the context to access the key that proves the holder binding
|
|
29
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
|
30
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
|
31
|
-
* @returns The result of the presentation flow
|
|
32
|
-
*/
|
|
33
|
-
export declare const sendAuthorizationResponse: SendAuthorizationResponse;
|
|
34
|
-
//# sourceMappingURL=05-send-authorization-response.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"05-send-authorization-response.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/05-send-authorization-response.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,eAAO,MAAM,qBAAqB;;;;;;;;;EAShC,CAAC;AAkFH,MAAM,MAAM,yBAAyB,GAAG,CACtC,aAAa,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,EACrD,MAAM,EAAE,GAAG,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,EAChD,YAAY,EAAE,YAAY,EAAE,iDAAiD;AAC7E,OAAO,EAAE;IACP,yBAAyB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CACjC,KACE,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,yBA0CvC,CAAC"}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { EncryptJwe, SignJWT } from "@pagopa/io-react-native-jwt";
|
|
2
|
-
import uuid from "react-native-uuid";
|
|
3
|
-
import * as WalletInstanceAttestation from "../../wallet-instance-attestation";
|
|
4
|
-
import type { JWK } from "@pagopa/io-react-native-jwt/lib/typescript/types";
|
|
5
|
-
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
|
|
6
|
-
import { hasStatusOrThrow, type Out } from "../../utils/misc";
|
|
7
|
-
import type { GetRequestObject } from "./04-get-request-object";
|
|
8
|
-
import { disclose } from "../../sd-jwt";
|
|
9
|
-
import type { EvaluateRelyingPartyTrust } from "./02-evaluate-rp-trust";
|
|
10
|
-
import { type Presentation } from "./types";
|
|
11
|
-
import * as z from "zod";
|
|
12
|
-
|
|
13
|
-
export type AuthorizationResponse = z.infer<typeof AuthorizationResponse>;
|
|
14
|
-
export const AuthorizationResponse = z.object({
|
|
15
|
-
status: z.string(),
|
|
16
|
-
response_code: z
|
|
17
|
-
.string() /**
|
|
18
|
-
FIXME: [SIW-627] we expect this value from every RP implementation
|
|
19
|
-
Actually some RP does not return the value
|
|
20
|
-
We make it optional to not break the flow.
|
|
21
|
-
*/
|
|
22
|
-
.optional(),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Choose an RSA public key from those offered by the RP for encryption.
|
|
27
|
-
*
|
|
28
|
-
* @param entity The RP entity configuration
|
|
29
|
-
* @returns A suitable public key with its compatible encryption algorithm
|
|
30
|
-
* @throws {NoSuitableKeysFoundInEntityConfiguration} If entity do not contain any public key suitable for encrypting
|
|
31
|
-
*/
|
|
32
|
-
const chooseRSAPublicKeyToEncrypt = (
|
|
33
|
-
entity: Out<EvaluateRelyingPartyTrust>["rpConf"]
|
|
34
|
-
): JWK => {
|
|
35
|
-
const [usingRsa256] = entity.wallet_relying_party.jwks.keys.filter(
|
|
36
|
-
(jwk) => jwk.use === "enc" && jwk.kty === "RSA"
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
if (usingRsa256) {
|
|
40
|
-
return usingRsa256;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// No suitable key has been found
|
|
44
|
-
throw new NoSuitableKeysFoundInEntityConfiguration(
|
|
45
|
-
"Encrypt with RP public key"
|
|
46
|
-
);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Generate a Verified Presentation token for a received request object within the context of an authorization request flow.
|
|
51
|
-
* The presentation is created by revealing data from the provided credentials based on the requested claims.
|
|
52
|
-
* Each Verified Credential is accompanied by the claims that the user consents to disclose from it.
|
|
53
|
-
*
|
|
54
|
-
* @todo: Allow for handling more than one Verified Credential.
|
|
55
|
-
*/
|
|
56
|
-
const prepareVpToken = async (
|
|
57
|
-
requestObject: Out<GetRequestObject>["requestObject"],
|
|
58
|
-
walletInstanceAttestation: string,
|
|
59
|
-
[vc, claims, cryptoCtx]: Presentation // TODO: [SIW-353] support multiple presentations,
|
|
60
|
-
): Promise<{
|
|
61
|
-
vp_token: string;
|
|
62
|
-
presentation_submission: Record<string, unknown>;
|
|
63
|
-
}> => {
|
|
64
|
-
// this throws if vc cannot satisfy all the requested claims
|
|
65
|
-
const { token: vp, paths } = await disclose(vc, claims);
|
|
66
|
-
|
|
67
|
-
// obtain issuer from Wallet Instance
|
|
68
|
-
const {
|
|
69
|
-
payload: { iss },
|
|
70
|
-
} = WalletInstanceAttestation.decode(walletInstanceAttestation);
|
|
71
|
-
|
|
72
|
-
const pidKid = await cryptoCtx.getPublicKey().then((_) => _.kid);
|
|
73
|
-
|
|
74
|
-
// TODO: [SIW-359] check all requeste claims of the requestedObj are satisfied
|
|
75
|
-
const vp_token = await new SignJWT(cryptoCtx)
|
|
76
|
-
.setProtectedHeader({
|
|
77
|
-
typ: "JWT",
|
|
78
|
-
kid: pidKid,
|
|
79
|
-
})
|
|
80
|
-
.setPayload({
|
|
81
|
-
vp: vp,
|
|
82
|
-
jti: `${uuid.v4()}`,
|
|
83
|
-
iss,
|
|
84
|
-
nonce: requestObject.nonce,
|
|
85
|
-
})
|
|
86
|
-
.setAudience(requestObject.response_uri)
|
|
87
|
-
.setIssuedAt()
|
|
88
|
-
.setExpirationTime("1h")
|
|
89
|
-
.sign();
|
|
90
|
-
|
|
91
|
-
const vc_scope = requestObject.scope;
|
|
92
|
-
const presentation_submission = {
|
|
93
|
-
definition_id: `${uuid.v4()}`,
|
|
94
|
-
id: `${uuid.v4()}`,
|
|
95
|
-
descriptor_map: paths.map((p) => ({
|
|
96
|
-
id: vc_scope,
|
|
97
|
-
path: `$.vp_token.${p.path}`,
|
|
98
|
-
format: "vc+sd-jwt",
|
|
99
|
-
})),
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
return { vp_token, presentation_submission };
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export type SendAuthorizationResponse = (
|
|
106
|
-
requestObject: Out<GetRequestObject>["requestObject"],
|
|
107
|
-
rpConf: Out<EvaluateRelyingPartyTrust>["rpConf"],
|
|
108
|
-
presentation: Presentation, // TODO: [SIW-353] support multiple presentations
|
|
109
|
-
context: {
|
|
110
|
-
walletInstanceAttestation: string;
|
|
111
|
-
appFetch?: GlobalFetch["fetch"];
|
|
112
|
-
}
|
|
113
|
-
) => Promise<AuthorizationResponse>;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Complete the presentation flow by sending the authorization response to the Relying Party
|
|
117
|
-
*
|
|
118
|
-
* @param requestObject The Request Object that describes the presentation
|
|
119
|
-
* @param rpConf The Relying Party's configuration
|
|
120
|
-
* @param presentation The presentation tuple consisting in the signed credential,
|
|
121
|
-
* the list of claims to be disclosed, and the context to access the key that proves the holder binding
|
|
122
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
|
123
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
|
124
|
-
* @returns The result of the presentation flow
|
|
125
|
-
*/
|
|
126
|
-
export const sendAuthorizationResponse: SendAuthorizationResponse = async (
|
|
127
|
-
requestObject,
|
|
128
|
-
rpConf,
|
|
129
|
-
presentation,
|
|
130
|
-
{ appFetch = fetch, walletInstanceAttestation }
|
|
131
|
-
): Promise<AuthorizationResponse> => {
|
|
132
|
-
// the request is an unsigned jws without iss, aud, exp
|
|
133
|
-
// https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-signed-and-encrypted-respon
|
|
134
|
-
const rsaPublicJwk = chooseRSAPublicKeyToEncrypt(rpConf);
|
|
135
|
-
|
|
136
|
-
const { vp_token, presentation_submission } = await prepareVpToken(
|
|
137
|
-
requestObject,
|
|
138
|
-
walletInstanceAttestation,
|
|
139
|
-
presentation
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
const authzResponsePayload = JSON.stringify({
|
|
143
|
-
state: requestObject.state,
|
|
144
|
-
presentation_submission,
|
|
145
|
-
nonce: requestObject.nonce,
|
|
146
|
-
vp_token,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
const encrypted = await new EncryptJwe(authzResponsePayload, {
|
|
150
|
-
alg: "RSA-OAEP-256",
|
|
151
|
-
enc: "A256CBC-HS512",
|
|
152
|
-
kid: rsaPublicJwk.kid,
|
|
153
|
-
}).encrypt(rsaPublicJwk);
|
|
154
|
-
|
|
155
|
-
const formBody = new URLSearchParams({ response: encrypted });
|
|
156
|
-
const body = formBody.toString();
|
|
157
|
-
|
|
158
|
-
return appFetch(requestObject.response_uri, {
|
|
159
|
-
method: "POST",
|
|
160
|
-
headers: {
|
|
161
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
162
|
-
},
|
|
163
|
-
body,
|
|
164
|
-
})
|
|
165
|
-
.then(hasStatusOrThrow(200))
|
|
166
|
-
.then((res) => res.json())
|
|
167
|
-
.then(AuthorizationResponse.parse);
|
|
168
|
-
};
|