@pagopa/io-react-native-wallet 0.25.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +0 -32
- package/lib/commonjs/credential/issuance/03-start-user-authorization.js +1 -1
- package/lib/commonjs/credential/issuance/04-complete-user-authorization.js +19 -57
- package/lib/commonjs/credential/issuance/04-complete-user-authorization.js.map +1 -1
- package/lib/commonjs/credential/issuance/index.js +6 -0
- package/lib/commonjs/credential/issuance/index.js.map +1 -1
- package/lib/commonjs/utils/misc.js +19 -58
- package/lib/commonjs/utils/misc.js.map +1 -1
- package/lib/module/credential/issuance/03-start-user-authorization.js +1 -1
- package/lib/module/credential/issuance/04-complete-user-authorization.js +19 -58
- package/lib/module/credential/issuance/04-complete-user-authorization.js.map +1 -1
- package/lib/module/credential/issuance/index.js +2 -2
- package/lib/module/credential/issuance/index.js.map +1 -1
- package/lib/module/utils/misc.js +14 -51
- package/lib/module/utils/misc.js.map +1 -1
- package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts +1 -1
- package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts +16 -15
- package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/index.d.ts +3 -3
- package/lib/typescript/credential/issuance/index.d.ts.map +1 -1
- package/lib/typescript/utils/misc.d.ts +5 -25
- package/lib/typescript/utils/misc.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/credential/issuance/03-start-user-authorization.ts +1 -1
- package/src/credential/issuance/04-complete-user-authorization.ts +42 -103
- package/src/credential/issuance/index.ts +4 -0
- package/src/utils/misc.ts +16 -63
package/README.md
CHANGED
@@ -70,36 +70,6 @@ The
|
|
70
70
|
|
71
71
|
</details>
|
72
72
|
|
73
|
-
<details>
|
74
|
-
<summary>AuthorizationContext (strong authentication handling)</summary>
|
75
|
-
|
76
|
-
Whenever a strong authentication is required, the library asks the consumer application to provide a way to perform the user authentication. This is done by providing a AuthenticationContext object formed as follows:
|
77
|
-
|
78
|
-
```ts
|
79
|
-
/**
|
80
|
-
* Context for authorization during the {@link 03-start-user-authorization.ts} phase.
|
81
|
-
* It consists of a single method to identify the user which takes a URL and a redirect schema as input.
|
82
|
-
* Once the authorization is completed and the URL calls the redirect schema, the method should return the redirect URL.
|
83
|
-
*/
|
84
|
-
export interface AuthorizationContext {
|
85
|
-
authorize: (url: string, redirectSchema: string) => Promise<string>;
|
86
|
-
}
|
87
|
-
```
|
88
|
-
|
89
|
-
The authorize function is called with the URL to be opened and the schema to be used to redirect the user back to the application. The function should return a promise that resolves with the URL that the user has been redirected to.
|
90
|
-
The suggested library to manage authorizations is [io-react-native-login-utils](https://github.com/pagopa/io-react-native-login-utils), an example is shown below:
|
91
|
-
|
92
|
-
```ts
|
93
|
-
import { type AuthorizationContext } from "@pagopa/io-react-native-wallet";
|
94
|
-
import { openAuthenticationSession } from "@pagopa/io-react-native-login-utils";
|
95
|
-
|
96
|
-
const authorizationContext: AuthorizationContext = {
|
97
|
-
authorize: openAuthenticationSession,
|
98
|
-
};
|
99
|
-
```
|
100
|
-
|
101
|
-
</details>
|
102
|
-
|
103
73
|
<details>
|
104
74
|
<summary>IntegrityToken (device integrity)</summary>
|
105
75
|
|
@@ -159,7 +129,6 @@ Below there's a list of the libraries and a schema of how they interact with eac
|
|
159
129
|
|
160
130
|
- [@pagopa/io-react-native-crypto](https://github.com/pagopa/io-react-native-crypto) - Used to manage cryptographic keys and signatures
|
161
131
|
- [@pagopa/io-react-native-integrity](https://github.com/pagopa/io-react-native-integrity) - Used to manage and verify the integrity of the device
|
162
|
-
- [@pagopa/io-react-native-login-utils](https://github.com/pagopa/io-react-native-login-utils) - Used to manage strong authentication flows securely
|
163
132
|
- [@pagopa/io-react-native-secure-storage](https://github.com/pagopa/io-react-native-secure-storage) - Used to store data securely on the device
|
164
133
|
|
165
134
|
```mermaid
|
@@ -168,7 +137,6 @@ graph TD;
|
|
168
137
|
iornw[io-react-native-wallet]
|
169
138
|
iornc[io-react-native-crypto]
|
170
139
|
iorni[io-react-native-integrity]
|
171
|
-
iornlu[io-react-native-login-utils]
|
172
140
|
iornss[io-react-native-secure-storage]
|
173
141
|
iornjwt[io-react-native-jwt]
|
174
142
|
rncie[react-native-cie]
|
@@ -57,7 +57,7 @@ const selectResponseMode = (issuerConf, credentialType) => {
|
|
57
57
|
* the application session identifier on the Wallet Instance side (state),
|
58
58
|
* the method (query or form_post.jwt) by which the Authorization Server
|
59
59
|
* should transmit the Authorization Response containing the authorization code issued upon the end user's authentication (response_mode)
|
60
|
-
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the
|
60
|
+
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the redirectUri of the Wallet Instance where the Authorization Response
|
61
61
|
* should be delivered. The redirect is achived by using a custom URL scheme that the Wallet Instance is registered to handle.
|
62
62
|
* @param issuerConf The issuer configuration
|
63
63
|
* @param credentialType The type of the credential to be requested returned by {@link selectCredentialDefinition}
|
@@ -3,12 +3,11 @@
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
4
4
|
value: true
|
5
5
|
});
|
6
|
-
exports.parseAuthorizationResponse = exports.getRequestedCredentialToBePresented = exports.completeUserAuthorizationWithQueryMode = exports.completeUserAuthorizationWithFormPostJwtMode = void 0;
|
6
|
+
exports.parseAuthorizationResponse = exports.getRequestedCredentialToBePresented = exports.completeUserAuthorizationWithQueryMode = exports.completeUserAuthorizationWithFormPostJwtMode = exports.buildAuthorizationUrl = void 0;
|
7
7
|
var _auth = require("../../utils/auth");
|
8
8
|
var _misc = require("../../utils/misc");
|
9
9
|
var _parseUrl = _interopRequireDefault(require("parse-url"));
|
10
10
|
var _errors = require("../../utils/errors");
|
11
|
-
var _reactNative = require("react-native");
|
12
11
|
var _ioReactNativeJwt = require("@pagopa/io-react-native-jwt");
|
13
12
|
var _types = require("../presentation/types");
|
14
13
|
var _reactNativeUuid = _interopRequireDefault(require("react-native-uuid"));
|
@@ -21,25 +20,15 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
21
20
|
*/
|
22
21
|
|
23
22
|
/**
|
24
|
-
* WARNING: This function must be called after {@link startUserAuthorization}. The
|
25
|
-
*
|
26
|
-
* It is used to complete the user authorization by catching the redirectSchema from the authorization server which then contains the authorization response.
|
27
|
-
* This function utilizes the authorization context to open an in-app browser capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
28
|
-
* If the 302 redirect happens and the redirectSchema is caught, the function will return the authorization response after parsing it from the query string.
|
23
|
+
* WARNING: This function must be called after {@link startUserAuthorization}. The generated authUrl must be used to open a browser or webview capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
24
|
+
* Builds the authorization URL to which the end user should be redirected to continue the authentication flow.
|
29
25
|
* @param issuerRequestUri the URI of the issuer where the request is sent
|
30
26
|
* @param clientId Identifies the current client across all the requests of the issuing flow returned by {@link startUserAuthorization}
|
31
27
|
* @param issuerConf The issuer configuration returned by {@link evaluateIssuerTrust}
|
32
|
-
* @param
|
33
|
-
*
|
34
|
-
* @param idphint Unique identifier of the SPID IDP selected by the user
|
35
|
-
* @param redirectUri The url to reach to complete the user authorization which is the custom URL scheme that the Wallet Instance is registered to handle, usually a custom URL or deeplink
|
36
|
-
* @param signal An optional {@link AbortSignal} to abort the operation when using the default browser
|
37
|
-
* @throws {AuthorizationError} if an error occurs during the authorization process
|
38
|
-
* @throws {AuthorizationIdpError} if an error occurs during the authorization process and the error is related to the IDP
|
39
|
-
* @throws {OperationAbortedError} if the caller aborts the operation via the provided signal
|
40
|
-
* @returns the authorization response which contains code, state and iss
|
28
|
+
* @param idpHint Unique identifier of the IDP selected by the user
|
29
|
+
* @returns An object containing the authorization URL
|
41
30
|
*/
|
42
|
-
const
|
31
|
+
const buildAuthorizationUrl = async (issuerRequestUri, clientId, issuerConf, idpHint) => {
|
43
32
|
const authzRequestEndpoint = issuerConf.oauth_authorization_server.authorization_endpoint;
|
44
33
|
const params = new URLSearchParams({
|
45
34
|
client_id: clientId,
|
@@ -47,47 +36,20 @@ const completeUserAuthorizationWithQueryMode = async (issuerRequestUri, clientId
|
|
47
36
|
idphint: idpHint
|
48
37
|
});
|
49
38
|
const authUrl = `${authzRequestEndpoint}?${params}`;
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
throw new _errors2.AuthorizationError(e.message);
|
55
|
-
});
|
56
|
-
} else {
|
57
|
-
// handler for redirectUri
|
58
|
-
const urlEventListener = _reactNative.Linking.addEventListener("url", _ref => {
|
59
|
-
let {
|
60
|
-
url
|
61
|
-
} = _ref;
|
62
|
-
if (url.includes(redirectUri)) {
|
63
|
-
authRedirectUrl = url;
|
64
|
-
}
|
65
|
-
});
|
66
|
-
const operationIsAborted = signal ? (0, _misc.createAbortPromiseFromSignal)(signal) : undefined;
|
67
|
-
await _reactNative.Linking.openURL(authUrl);
|
68
|
-
|
69
|
-
/*
|
70
|
-
* Waits for 120 seconds for the identificationRedirectUrl variable to be set
|
71
|
-
* by the custom url handler. If the timeout is exceeded, throw an exception
|
72
|
-
*/
|
73
|
-
const unitAuthRedirectIsNotUndefined = (0, _misc.until)(() => authRedirectUrl !== undefined, 120);
|
39
|
+
return {
|
40
|
+
authUrl
|
41
|
+
};
|
42
|
+
};
|
74
43
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if (winner === "OPERATION_ABORTED") {
|
85
|
-
throw new _errors2.OperationAbortedError("DefaultQueryModeAuthorization");
|
86
|
-
}
|
87
|
-
if (authRedirectUrl === undefined) {
|
88
|
-
throw new _errors2.AuthorizationError("Invalid authentication redirect url");
|
89
|
-
}
|
90
|
-
}
|
44
|
+
/**
|
45
|
+
* WARNING: This function must be called after obtaining the authorization redirect URL from the webviews (SPID and CIE L3) or browser for CIEID.
|
46
|
+
* Complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
47
|
+
* This function parses the authorization redirect URL to extract the authorization response.
|
48
|
+
* @param authRedirectUrl The URL to which the end user should be redirected to start the authentication flow
|
49
|
+
* @returns the authorization response which contains code, state and iss
|
50
|
+
*/
|
51
|
+
exports.buildAuthorizationUrl = buildAuthorizationUrl;
|
52
|
+
const completeUserAuthorizationWithQueryMode = async authRedirectUrl => {
|
91
53
|
const query = (0, _parseUrl.default)(authRedirectUrl).query;
|
92
54
|
return parseAuthorizationResponse(query);
|
93
55
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["_auth","require","_misc","_parseUrl","_interopRequireDefault","_errors","
|
1
|
+
{"version":3,"names":["_auth","require","_misc","_parseUrl","_interopRequireDefault","_errors","_ioReactNativeJwt","_types","_reactNativeUuid","_types2","_decoder","_errors2","obj","__esModule","default","buildAuthorizationUrl","issuerRequestUri","clientId","issuerConf","idpHint","authzRequestEndpoint","oauth_authorization_server","authorization_endpoint","params","URLSearchParams","client_id","request_uri","idphint","authUrl","exports","completeUserAuthorizationWithQueryMode","authRedirectUrl","query","parseUrl","parseAuthorizationResponse","getRequestedCredentialToBePresented","appFetch","arguments","length","undefined","fetch","requestObject","toString","method","then","hasStatusOrThrow","IssuerResponseError","res","text","jws","decode","reqObj","RequestObject","safeParse","payload","success","ValidationFailed","message","reason","error","data","completeUserAuthorizationWithFormPostJwtMode","ctx","wiaCryptoContext","pidCryptoContext","pid","walletInstanceAttestation","wiaWpToken","SignJWT","setProtectedHeader","alg","typ","setPayload","vp","jti","uuid","v4","nonce","setIssuedAt","setExpirationTime","setAudience","response_uri","sign","pidWpToken","presentationSubmission","definition_id","id","descriptor_map","path","format","authzResponsePayload","encodeBase64","JSON","stringify","state","presentation_submission","vp_token","body","response","resUriRes","headers","reqUri","json","responseUri","ResponseUriResultShape","redirect_uri","getJwtFromFormPost","cbRes","decodedJwt","authRes","authResParsed","AuthorizationResultShape","authErr","AuthorizationErrorShape","AuthorizationError","AuthorizationIdpError","error_description"],"sourceRoot":"../../../../src","sources":["credential/issuance/04-complete-user-authorization.ts"],"mappings":"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"}
|
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "authorizeAccess", {
|
|
10
10
|
return _authorizeAccess.authorizeAccess;
|
11
11
|
}
|
12
12
|
});
|
13
|
+
Object.defineProperty(exports, "buildAuthorizationUrl", {
|
14
|
+
enumerable: true,
|
15
|
+
get: function () {
|
16
|
+
return _completeUserAuthorization.buildAuthorizationUrl;
|
17
|
+
}
|
18
|
+
});
|
13
19
|
Object.defineProperty(exports, "completeUserAuthorizationWithFormPostJwtMode", {
|
14
20
|
enumerable: true,
|
15
21
|
get: function () {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["_evaluateIssuerTrust","require","_startUserAuthorization","_completeUserAuthorization","_authorizeAccess","_obtainCredential","_verifyAndParseCredential","Errors","_interopRequireWildcard","exports","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set"],"sourceRoot":"../../../../src","sources":["credential/issuance/index.ts"],"mappings":"
|
1
|
+
{"version":3,"names":["_evaluateIssuerTrust","require","_startUserAuthorization","_completeUserAuthorization","_authorizeAccess","_obtainCredential","_verifyAndParseCredential","Errors","_interopRequireWildcard","exports","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set"],"sourceRoot":"../../../../src","sources":["credential/issuance/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,oBAAA,GAAAC,OAAA;AAIA,IAAAC,uBAAA,GAAAD,OAAA;AAIA,IAAAE,0BAAA,GAAAF,OAAA;AAWA,IAAAG,gBAAA,GAAAH,OAAA;AACA,IAAAI,iBAAA,GAAAJ,OAAA;AAIA,IAAAK,yBAAA,GAAAL,OAAA;AAIA,IAAAM,MAAA,GAAAC,uBAAA,CAAAP,OAAA;AAAmCQ,OAAA,CAAAF,MAAA,GAAAA,MAAA;AAAA,SAAAG,yBAAAC,WAAA,eAAAC,OAAA,kCAAAC,iBAAA,OAAAD,OAAA,QAAAE,gBAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,WAAA,WAAAA,WAAA,GAAAG,gBAAA,GAAAD,iBAAA,KAAAF,WAAA;AAAA,SAAAH,wBAAAO,GAAA,EAAAJ,WAAA,SAAAA,WAAA,IAAAI,GAAA,IAAAA,GAAA,CAAAC,UAAA,WAAAD,GAAA,QAAAA,GAAA,oBAAAA,GAAA,wBAAAA,GAAA,4BAAAE,OAAA,EAAAF,GAAA,UAAAG,KAAA,GAAAR,wBAAA,CAAAC,WAAA,OAAAO,KAAA,IAAAA,KAAA,CAAAC,GAAA,CAAAJ,GAAA,YAAAG,KAAA,CAAAE,GAAA,CAAAL,GAAA,SAAAM,MAAA,WAAAC,qBAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,GAAA,IAAAX,GAAA,QAAAW,GAAA,kBAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAd,GAAA,EAAAW,GAAA,SAAAI,IAAA,GAAAR,qBAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAV,GAAA,EAAAW,GAAA,cAAAI,IAAA,KAAAA,IAAA,CAAAV,GAAA,IAAAU,IAAA,CAAAC,GAAA,KAAAR,MAAA,CAAAC,cAAA,CAAAH,MAAA,EAAAK,GAAA,EAAAI,IAAA,YAAAT,MAAA,CAAAK,GAAA,IAAAX,GAAA,CAAAW,GAAA,SAAAL,MAAA,CAAAJ,OAAA,GAAAF,GAAA,MAAAG,KAAA,IAAAA,KAAA,CAAAa,GAAA,CAAAhB,GAAA,EAAAM,MAAA,YAAAA,MAAA"}
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
4
4
|
value: true
|
5
5
|
});
|
6
|
-
exports.
|
6
|
+
exports.safeJsonParse = exports.parseRawHttpResponse = exports.hasStatusOrThrow = exports.getCredentialHashWithouDiscloures = exports.generateRandomAlphaNumericString = void 0;
|
7
7
|
var _errors = require("./errors");
|
8
8
|
var _jsSha = require("js-sha256");
|
9
9
|
/**
|
@@ -26,9 +26,18 @@ const hasStatusOrThrow = (status, customError) => async res => {
|
|
26
26
|
return res;
|
27
27
|
};
|
28
28
|
|
29
|
+
/**
|
30
|
+
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
31
|
+
*/
|
32
|
+
exports.hasStatusOrThrow = hasStatusOrThrow;
|
33
|
+
const parseRawHttpResponse = response => {
|
34
|
+
var _response$headers$get;
|
35
|
+
return (_response$headers$get = response.headers.get("content-type")) !== null && _response$headers$get !== void 0 && _response$headers$get.includes("application/json") ? response.json() : response.text();
|
36
|
+
};
|
37
|
+
|
29
38
|
// extract a type from an async function output
|
30
39
|
// helpful to bind the input of a function to the output of another
|
31
|
-
exports.
|
40
|
+
exports.parseRawHttpResponse = parseRawHttpResponse;
|
32
41
|
/**
|
33
42
|
* TODO [SIW-1310]: replace this function with a cryptographically secure one.
|
34
43
|
* @param size - The size of the string to generate
|
@@ -36,39 +45,13 @@ exports.hasStatusOrThrow = hasStatusOrThrow;
|
|
36
45
|
*/
|
37
46
|
const generateRandomAlphaNumericString = size => Array.from(Array(size), () => Math.floor(Math.random() * 36).toString(36)).join("");
|
38
47
|
|
39
|
-
/**
|
40
|
-
* Repeatedly checks a condition function until it returns true,
|
41
|
-
* then resolves the returned promise. If the condition function does not return true
|
42
|
-
* within the specified timeout, the promise is rejected.
|
43
|
-
*
|
44
|
-
* @param conditionFunction - A function that returns a boolean value.
|
45
|
-
* The promise resolves when this function returns true.
|
46
|
-
* @param timeout - An optional timeout in seconds. The promise is rejected if the
|
47
|
-
* condition function does not return true within this time.
|
48
|
-
* @returns A promise that resolves once the conditionFunction returns true or rejects if timed out.
|
49
|
-
*/
|
50
|
-
exports.generateRandomAlphaNumericString = generateRandomAlphaNumericString;
|
51
|
-
const until = (conditionFunction, timeoutSeconds) => new Promise((resolve, reject) => {
|
52
|
-
const start = Date.now();
|
53
|
-
const poll = () => {
|
54
|
-
if (conditionFunction()) {
|
55
|
-
resolve();
|
56
|
-
} else if (timeoutSeconds !== undefined && Date.now() - start >= timeoutSeconds * 1000) {
|
57
|
-
reject(new Error("Timeout exceeded"));
|
58
|
-
} else {
|
59
|
-
setTimeout(poll, 400);
|
60
|
-
}
|
61
|
-
};
|
62
|
-
poll();
|
63
|
-
});
|
64
|
-
|
65
48
|
/**
|
66
49
|
* Get the hash of a credential without discloures.
|
67
50
|
* A credential is a string like `header.body.sign~sd1~sd2....` where `~` is the separator between the credential and the discloures.
|
68
51
|
* @param credential - The credential to hash
|
69
52
|
* @returns The hash of the credential without discloures
|
70
53
|
*/
|
71
|
-
exports.
|
54
|
+
exports.generateRandomAlphaNumericString = generateRandomAlphaNumericString;
|
72
55
|
const getCredentialHashWithouDiscloures = async credential => {
|
73
56
|
const tildeIndex = credential.indexOf("~");
|
74
57
|
if (tildeIndex === -1) {
|
@@ -76,35 +59,13 @@ const getCredentialHashWithouDiscloures = async credential => {
|
|
76
59
|
}
|
77
60
|
return (0, _jsSha.sha256)(credential.slice(0, tildeIndex));
|
78
61
|
};
|
79
|
-
|
80
|
-
/**
|
81
|
-
* Creates a promise that waits until the provided signal is aborted.
|
82
|
-
* @returns {Object} An object with `listen` and `remove` methods to handle subscribing and unsubscribing.
|
83
|
-
*/
|
84
62
|
exports.getCredentialHashWithouDiscloures = getCredentialHashWithouDiscloures;
|
85
|
-
const
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
listener = () => resolve("OPERATION_ABORTED");
|
93
|
-
signal.addEventListener("abort", listener);
|
94
|
-
}),
|
95
|
-
remove: () => signal.removeEventListener("abort", listener)
|
96
|
-
};
|
97
|
-
};
|
98
|
-
exports.createAbortPromiseFromSignal = createAbortPromiseFromSignal;
|
99
|
-
const isDefined = x => Boolean(x);
|
100
|
-
|
101
|
-
/**
|
102
|
-
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
103
|
-
*/
|
104
|
-
exports.isDefined = isDefined;
|
105
|
-
const parseRawHttpResponse = response => {
|
106
|
-
var _response$headers$get;
|
107
|
-
return (_response$headers$get = response.headers.get("content-type")) !== null && _response$headers$get !== void 0 && _response$headers$get.includes("application/json") ? response.json() : response.text();
|
63
|
+
const safeJsonParse = (text, withDefault) => {
|
64
|
+
try {
|
65
|
+
return JSON.parse(text);
|
66
|
+
} catch (_) {
|
67
|
+
return withDefault ?? null;
|
68
|
+
}
|
108
69
|
};
|
109
|
-
exports.
|
70
|
+
exports.safeJsonParse = safeJsonParse;
|
110
71
|
//# sourceMappingURL=misc.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["_errors","require","_jsSha","hasStatusOrThrow","status","customError","res","ErrorClass","UnexpectedStatusCodeError","message","url","statusCode","reason","parseRawHttpResponse","exports","
|
1
|
+
{"version":3,"names":["_errors","require","_jsSha","hasStatusOrThrow","status","customError","res","ErrorClass","UnexpectedStatusCodeError","message","url","statusCode","reason","parseRawHttpResponse","exports","response","_response$headers$get","headers","get","includes","json","text","generateRandomAlphaNumericString","size","Array","from","Math","floor","random","toString","join","getCredentialHashWithouDiscloures","credential","tildeIndex","indexOf","IoWalletError","sha256","slice","safeJsonParse","withDefault","JSON","parse","_"],"sourceRoot":"../../../src","sources":["utils/misc.ts"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,gBAAgB,GAC3BA,CAACC,MAAc,EAAEC,WAA8C,KAC/D,MAAOC,GAAa,IAAwB;EAC1C,IAAIA,GAAG,CAACF,MAAM,KAAKA,MAAM,EAAE;IACzB,MAAMG,UAAU,GAAGF,WAAW,IAAIG,iCAAyB;IAC3D,MAAM,IAAID,UAAU,CAAC;MACnBE,OAAO,EAAG,iCAAgCL,MAAO,SAAQE,GAAG,CAACF,MAAO,UAASE,GAAG,CAACI,GAAI,EAAC;MACtFC,UAAU,EAAEL,GAAG,CAACF,MAAM;MACtBQ,MAAM,EAAE,MAAMC,oBAAoB,CAACP,GAAG,CAAC,CAAE;IAC3C,CAAC,CAAC;EACJ;;EACA,OAAOA,GAAG;AACZ,CAAC;;AAEH;AACA;AACA;AAFAQ,OAAA,CAAAX,gBAAA,GAAAA,gBAAA;AAGO,MAAMU,oBAAoB,GAC/BE,QAAkB;EAAA,IAAAC,qBAAA;EAAA,OAElB,CAAAA,qBAAA,GAAAD,QAAQ,CAACE,OAAO,CAACC,GAAG,CAAC,cAAc,CAAC,cAAAF,qBAAA,eAApCA,qBAAA,CAAsCG,QAAQ,CAAC,kBAAkB,CAAC,GAC7DJ,QAAQ,CAACK,IAAI,CAAC,CAAC,GAChBL,QAAQ,CAACM,IAAI,CAAC,CAAC;AAAA;;AAErB;AACA;AAAAP,OAAA,CAAAD,oBAAA,GAAAA,oBAAA;AAOA;AACA;AACA;AACA;AACA;AACO,MAAMS,gCAAgC,GAAIC,IAAY,IAC3DC,KAAK,CAACC,IAAI,CAACD,KAAK,CAACD,IAAI,CAAC,EAAE,MACtBG,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAACC,QAAQ,CAAC,EAAE,CAC5C,CAAC,CAACC,IAAI,CAAC,EAAE,CAAC;;AAEZ;AACA;AACA;AACA;AACA;AACA;AALAhB,OAAA,CAAAQ,gCAAA,GAAAA,gCAAA;AAMO,MAAMS,iCAAiC,GAAG,MAC/CC,UAAkB,IACE;EACpB,MAAMC,UAAU,GAAGD,UAAU,CAACE,OAAO,CAAC,GAAG,CAAC;EAC1C,IAAID,UAAU,KAAK,CAAC,CAAC,EAAE;IACrB,MAAM,IAAIE,qBAAa,CAAC,2BAA2B,CAAC;EACtD;EACA,OAAO,IAAAC,aAAM,EAACJ,UAAU,CAACK,KAAK,CAAC,CAAC,EAAEJ,UAAU,CAAC,CAAC;AAChD,CAAC;AAACnB,OAAA,CAAAiB,iCAAA,GAAAA,iCAAA;AAEK,MAAMO,aAAa,GAAGA,CAAIjB,IAAY,EAAEkB,WAAe,KAAe;EAC3E,IAAI;IACF,OAAOC,IAAI,CAACC,KAAK,CAACpB,IAAI,CAAC;EACzB,CAAC,CAAC,OAAOqB,CAAC,EAAE;IACV,OAAOH,WAAW,IAAI,IAAI;EAC5B;AACF,CAAC;AAACzB,OAAA,CAAAwB,aAAA,GAAAA,aAAA"}
|
@@ -51,7 +51,7 @@ const selectResponseMode = (issuerConf, credentialType) => {
|
|
51
51
|
* the application session identifier on the Wallet Instance side (state),
|
52
52
|
* the method (query or form_post.jwt) by which the Authorization Server
|
53
53
|
* should transmit the Authorization Response containing the authorization code issued upon the end user's authentication (response_mode)
|
54
|
-
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the
|
54
|
+
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the redirectUri of the Wallet Instance where the Authorization Response
|
55
55
|
* should be delivered. The redirect is achived by using a custom URL scheme that the Wallet Instance is registered to handle.
|
56
56
|
* @param issuerConf The issuer configuration
|
57
57
|
* @param credentialType The type of the credential to be requested returned by {@link selectCredentialDefinition}
|
@@ -1,39 +1,28 @@
|
|
1
1
|
import { AuthorizationErrorShape, AuthorizationResultShape } from "../../utils/auth";
|
2
|
-
import {
|
2
|
+
import { hasStatusOrThrow } from "../../utils/misc";
|
3
3
|
import parseUrl from "parse-url";
|
4
4
|
import { IssuerResponseError, ValidationFailed } from "../../utils/errors";
|
5
|
-
import { Linking } from "react-native";
|
6
5
|
import { decode, encodeBase64, SignJWT } from "@pagopa/io-react-native-jwt";
|
7
6
|
import { RequestObject } from "../presentation/types";
|
8
7
|
import uuid from "react-native-uuid";
|
9
8
|
import { ResponseUriResultShape } from "./types";
|
10
9
|
import { getJwtFromFormPost } from "../../utils/decoder";
|
11
|
-
import { AuthorizationError, AuthorizationIdpError
|
10
|
+
import { AuthorizationError, AuthorizationIdpError } from "./errors";
|
12
11
|
|
13
12
|
/**
|
14
13
|
* The interface of the phase to complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
15
14
|
*/
|
16
15
|
|
17
16
|
/**
|
18
|
-
* WARNING: This function must be called after {@link startUserAuthorization}. The
|
19
|
-
*
|
20
|
-
* It is used to complete the user authorization by catching the redirectSchema from the authorization server which then contains the authorization response.
|
21
|
-
* This function utilizes the authorization context to open an in-app browser capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
22
|
-
* If the 302 redirect happens and the redirectSchema is caught, the function will return the authorization response after parsing it from the query string.
|
17
|
+
* WARNING: This function must be called after {@link startUserAuthorization}. The generated authUrl must be used to open a browser or webview capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
18
|
+
* Builds the authorization URL to which the end user should be redirected to continue the authentication flow.
|
23
19
|
* @param issuerRequestUri the URI of the issuer where the request is sent
|
24
20
|
* @param clientId Identifies the current client across all the requests of the issuing flow returned by {@link startUserAuthorization}
|
25
21
|
* @param issuerConf The issuer configuration returned by {@link evaluateIssuerTrust}
|
26
|
-
* @param
|
27
|
-
*
|
28
|
-
* @param idphint Unique identifier of the SPID IDP selected by the user
|
29
|
-
* @param redirectUri The url to reach to complete the user authorization which is the custom URL scheme that the Wallet Instance is registered to handle, usually a custom URL or deeplink
|
30
|
-
* @param signal An optional {@link AbortSignal} to abort the operation when using the default browser
|
31
|
-
* @throws {AuthorizationError} if an error occurs during the authorization process
|
32
|
-
* @throws {AuthorizationIdpError} if an error occurs during the authorization process and the error is related to the IDP
|
33
|
-
* @throws {OperationAbortedError} if the caller aborts the operation via the provided signal
|
34
|
-
* @returns the authorization response which contains code, state and iss
|
22
|
+
* @param idpHint Unique identifier of the IDP selected by the user
|
23
|
+
* @returns An object containing the authorization URL
|
35
24
|
*/
|
36
|
-
export const
|
25
|
+
export const buildAuthorizationUrl = async (issuerRequestUri, clientId, issuerConf, idpHint) => {
|
37
26
|
const authzRequestEndpoint = issuerConf.oauth_authorization_server.authorization_endpoint;
|
38
27
|
const params = new URLSearchParams({
|
39
28
|
client_id: clientId,
|
@@ -41,47 +30,19 @@ export const completeUserAuthorizationWithQueryMode = async (issuerRequestUri, c
|
|
41
30
|
idphint: idpHint
|
42
31
|
});
|
43
32
|
const authUrl = `${authzRequestEndpoint}?${params}`;
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
throw new AuthorizationError(e.message);
|
49
|
-
});
|
50
|
-
} else {
|
51
|
-
// handler for redirectUri
|
52
|
-
const urlEventListener = Linking.addEventListener("url", _ref => {
|
53
|
-
let {
|
54
|
-
url
|
55
|
-
} = _ref;
|
56
|
-
if (url.includes(redirectUri)) {
|
57
|
-
authRedirectUrl = url;
|
58
|
-
}
|
59
|
-
});
|
60
|
-
const operationIsAborted = signal ? createAbortPromiseFromSignal(signal) : undefined;
|
61
|
-
await Linking.openURL(authUrl);
|
62
|
-
|
63
|
-
/*
|
64
|
-
* Waits for 120 seconds for the identificationRedirectUrl variable to be set
|
65
|
-
* by the custom url handler. If the timeout is exceeded, throw an exception
|
66
|
-
*/
|
67
|
-
const unitAuthRedirectIsNotUndefined = until(() => authRedirectUrl !== undefined, 120);
|
33
|
+
return {
|
34
|
+
authUrl
|
35
|
+
};
|
36
|
+
};
|
68
37
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
});
|
78
|
-
if (winner === "OPERATION_ABORTED") {
|
79
|
-
throw new OperationAbortedError("DefaultQueryModeAuthorization");
|
80
|
-
}
|
81
|
-
if (authRedirectUrl === undefined) {
|
82
|
-
throw new AuthorizationError("Invalid authentication redirect url");
|
83
|
-
}
|
84
|
-
}
|
38
|
+
/**
|
39
|
+
* WARNING: This function must be called after obtaining the authorization redirect URL from the webviews (SPID and CIE L3) or browser for CIEID.
|
40
|
+
* Complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
41
|
+
* This function parses the authorization redirect URL to extract the authorization response.
|
42
|
+
* @param authRedirectUrl The URL to which the end user should be redirected to start the authentication flow
|
43
|
+
* @returns the authorization response which contains code, state and iss
|
44
|
+
*/
|
45
|
+
export const completeUserAuthorizationWithQueryMode = async authRedirectUrl => {
|
85
46
|
const query = parseUrl(authRedirectUrl).query;
|
86
47
|
return parseAuthorizationResponse(query);
|
87
48
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["AuthorizationErrorShape","AuthorizationResultShape","
|
1
|
+
{"version":3,"names":["AuthorizationErrorShape","AuthorizationResultShape","hasStatusOrThrow","parseUrl","IssuerResponseError","ValidationFailed","decode","encodeBase64","SignJWT","RequestObject","uuid","ResponseUriResultShape","getJwtFromFormPost","AuthorizationError","AuthorizationIdpError","buildAuthorizationUrl","issuerRequestUri","clientId","issuerConf","idpHint","authzRequestEndpoint","oauth_authorization_server","authorization_endpoint","params","URLSearchParams","client_id","request_uri","idphint","authUrl","completeUserAuthorizationWithQueryMode","authRedirectUrl","query","parseAuthorizationResponse","getRequestedCredentialToBePresented","appFetch","arguments","length","undefined","fetch","requestObject","toString","method","then","res","text","jws","reqObj","safeParse","payload","success","message","reason","error","data","completeUserAuthorizationWithFormPostJwtMode","ctx","wiaCryptoContext","pidCryptoContext","pid","walletInstanceAttestation","wiaWpToken","setProtectedHeader","alg","typ","setPayload","vp","jti","v4","nonce","setIssuedAt","setExpirationTime","setAudience","response_uri","sign","pidWpToken","presentationSubmission","definition_id","id","descriptor_map","path","format","authzResponsePayload","JSON","stringify","state","presentation_submission","vp_token","body","response","resUriRes","headers","reqUri","json","responseUri","redirect_uri","cbRes","decodedJwt","authRes","authResParsed","authErr","error_description"],"sourceRoot":"../../../../src","sources":["credential/issuance/04-complete-user-authorization.ts"],"mappings":"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"}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { evaluateIssuerTrust } from "./02-evaluate-issuer-trust";
|
2
2
|
import { startUserAuthorization } from "./03-start-user-authorization";
|
3
|
-
import { completeUserAuthorizationWithQueryMode, completeUserAuthorizationWithFormPostJwtMode, parseAuthorizationResponse, getRequestedCredentialToBePresented } from "./04-complete-user-authorization";
|
3
|
+
import { completeUserAuthorizationWithQueryMode, completeUserAuthorizationWithFormPostJwtMode, parseAuthorizationResponse, buildAuthorizationUrl, getRequestedCredentialToBePresented } from "./04-complete-user-authorization";
|
4
4
|
import { authorizeAccess } from "./05-authorize-access";
|
5
5
|
import { obtainCredential } from "./06-obtain-credential";
|
6
6
|
import { verifyAndParseCredential } from "./07-verify-and-parse-credential";
|
7
7
|
import * as Errors from "./errors";
|
8
|
-
export { evaluateIssuerTrust, startUserAuthorization, completeUserAuthorizationWithQueryMode, getRequestedCredentialToBePresented, completeUserAuthorizationWithFormPostJwtMode, authorizeAccess, obtainCredential, verifyAndParseCredential, parseAuthorizationResponse, Errors };
|
8
|
+
export { evaluateIssuerTrust, startUserAuthorization, buildAuthorizationUrl, completeUserAuthorizationWithQueryMode, getRequestedCredentialToBePresented, completeUserAuthorizationWithFormPostJwtMode, authorizeAccess, obtainCredential, verifyAndParseCredential, parseAuthorizationResponse, Errors };
|
9
9
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["evaluateIssuerTrust","startUserAuthorization","completeUserAuthorizationWithQueryMode","completeUserAuthorizationWithFormPostJwtMode","parseAuthorizationResponse","getRequestedCredentialToBePresented","authorizeAccess","obtainCredential","verifyAndParseCredential","Errors"],"sourceRoot":"../../../../src","sources":["credential/issuance/index.ts"],"mappings":"AACA,SACEA,mBAAmB,QAEd,4BAA4B;AACnC,SACEC,sBAAsB,QAEjB,+BAA+B;AACtC,SACEC,sCAAsC,EACtCC,4CAA4C,EAC5CC,0BAA0B,
|
1
|
+
{"version":3,"names":["evaluateIssuerTrust","startUserAuthorization","completeUserAuthorizationWithQueryMode","completeUserAuthorizationWithFormPostJwtMode","parseAuthorizationResponse","buildAuthorizationUrl","getRequestedCredentialToBePresented","authorizeAccess","obtainCredential","verifyAndParseCredential","Errors"],"sourceRoot":"../../../../src","sources":["credential/issuance/index.ts"],"mappings":"AACA,SACEA,mBAAmB,QAEd,4BAA4B;AACnC,SACEC,sBAAsB,QAEjB,+BAA+B;AACtC,SACEC,sCAAsC,EACtCC,4CAA4C,EAC5CC,0BAA0B,EAC1BC,qBAAqB,EAKrBC,mCAAmC,QAC9B,kCAAkC;AACzC,SAASC,eAAe,QAA8B,uBAAuB;AAC7E,SACEC,gBAAgB,QAEX,wBAAwB;AAC/B,SACEC,wBAAwB,QAEnB,kCAAkC;AACzC,OAAO,KAAKC,MAAM,MAAM,UAAU;AAElC,SACEV,mBAAmB,EACnBC,sBAAsB,EACtBI,qBAAqB,EACrBH,sCAAsC,EACtCI,mCAAmC,EACnCH,4CAA4C,EAC5CI,eAAe,EACfC,gBAAgB,EAChBC,wBAAwB,EACxBL,0BAA0B,EAC1BM,MAAM"}
|
package/lib/module/utils/misc.js
CHANGED
@@ -21,6 +21,14 @@ export const hasStatusOrThrow = (status, customError) => async res => {
|
|
21
21
|
return res;
|
22
22
|
};
|
23
23
|
|
24
|
+
/**
|
25
|
+
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
26
|
+
*/
|
27
|
+
export const parseRawHttpResponse = response => {
|
28
|
+
var _response$headers$get;
|
29
|
+
return (_response$headers$get = response.headers.get("content-type")) !== null && _response$headers$get !== void 0 && _response$headers$get.includes("application/json") ? response.json() : response.text();
|
30
|
+
};
|
31
|
+
|
24
32
|
// extract a type from an async function output
|
25
33
|
// helpful to bind the input of a function to the output of another
|
26
34
|
/**
|
@@ -30,31 +38,6 @@ export const hasStatusOrThrow = (status, customError) => async res => {
|
|
30
38
|
*/
|
31
39
|
export const generateRandomAlphaNumericString = size => Array.from(Array(size), () => Math.floor(Math.random() * 36).toString(36)).join("");
|
32
40
|
|
33
|
-
/**
|
34
|
-
* Repeatedly checks a condition function until it returns true,
|
35
|
-
* then resolves the returned promise. If the condition function does not return true
|
36
|
-
* within the specified timeout, the promise is rejected.
|
37
|
-
*
|
38
|
-
* @param conditionFunction - A function that returns a boolean value.
|
39
|
-
* The promise resolves when this function returns true.
|
40
|
-
* @param timeout - An optional timeout in seconds. The promise is rejected if the
|
41
|
-
* condition function does not return true within this time.
|
42
|
-
* @returns A promise that resolves once the conditionFunction returns true or rejects if timed out.
|
43
|
-
*/
|
44
|
-
export const until = (conditionFunction, timeoutSeconds) => new Promise((resolve, reject) => {
|
45
|
-
const start = Date.now();
|
46
|
-
const poll = () => {
|
47
|
-
if (conditionFunction()) {
|
48
|
-
resolve();
|
49
|
-
} else if (timeoutSeconds !== undefined && Date.now() - start >= timeoutSeconds * 1000) {
|
50
|
-
reject(new Error("Timeout exceeded"));
|
51
|
-
} else {
|
52
|
-
setTimeout(poll, 400);
|
53
|
-
}
|
54
|
-
};
|
55
|
-
poll();
|
56
|
-
});
|
57
|
-
|
58
41
|
/**
|
59
42
|
* Get the hash of a credential without discloures.
|
60
43
|
* A credential is a string like `header.body.sign~sd1~sd2....` where `~` is the separator between the credential and the discloures.
|
@@ -68,31 +51,11 @@ export const getCredentialHashWithouDiscloures = async credential => {
|
|
68
51
|
}
|
69
52
|
return sha256(credential.slice(0, tildeIndex));
|
70
53
|
};
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
let listener;
|
78
|
-
return {
|
79
|
-
listen: () => new Promise(resolve => {
|
80
|
-
if (signal.aborted) {
|
81
|
-
return resolve("OPERATION_ABORTED");
|
82
|
-
}
|
83
|
-
listener = () => resolve("OPERATION_ABORTED");
|
84
|
-
signal.addEventListener("abort", listener);
|
85
|
-
}),
|
86
|
-
remove: () => signal.removeEventListener("abort", listener)
|
87
|
-
};
|
88
|
-
};
|
89
|
-
export const isDefined = x => Boolean(x);
|
90
|
-
|
91
|
-
/**
|
92
|
-
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
93
|
-
*/
|
94
|
-
export const parseRawHttpResponse = response => {
|
95
|
-
var _response$headers$get;
|
96
|
-
return (_response$headers$get = response.headers.get("content-type")) !== null && _response$headers$get !== void 0 && _response$headers$get.includes("application/json") ? response.json() : response.text();
|
54
|
+
export const safeJsonParse = (text, withDefault) => {
|
55
|
+
try {
|
56
|
+
return JSON.parse(text);
|
57
|
+
} catch (_) {
|
58
|
+
return withDefault ?? null;
|
59
|
+
}
|
97
60
|
};
|
98
61
|
//# sourceMappingURL=misc.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["IoWalletError","UnexpectedStatusCodeError","sha256","hasStatusOrThrow","status","customError","res","ErrorClass","message","url","statusCode","reason","parseRawHttpResponse","
|
1
|
+
{"version":3,"names":["IoWalletError","UnexpectedStatusCodeError","sha256","hasStatusOrThrow","status","customError","res","ErrorClass","message","url","statusCode","reason","parseRawHttpResponse","response","_response$headers$get","headers","get","includes","json","text","generateRandomAlphaNumericString","size","Array","from","Math","floor","random","toString","join","getCredentialHashWithouDiscloures","credential","tildeIndex","indexOf","slice","safeJsonParse","withDefault","JSON","parse","_"],"sourceRoot":"../../../src","sources":["utils/misc.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,yBAAyB,QAAQ,UAAU;AACnE,SAASC,MAAM,QAAQ,WAAW;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAgB,GAC3BA,CAACC,MAAc,EAAEC,WAA8C,KAC/D,MAAOC,GAAa,IAAwB;EAC1C,IAAIA,GAAG,CAACF,MAAM,KAAKA,MAAM,EAAE;IACzB,MAAMG,UAAU,GAAGF,WAAW,IAAIJ,yBAAyB;IAC3D,MAAM,IAAIM,UAAU,CAAC;MACnBC,OAAO,EAAG,iCAAgCJ,MAAO,SAAQE,GAAG,CAACF,MAAO,UAASE,GAAG,CAACG,GAAI,EAAC;MACtFC,UAAU,EAAEJ,GAAG,CAACF,MAAM;MACtBO,MAAM,EAAE,MAAMC,oBAAoB,CAACN,GAAG,CAAC,CAAE;IAC3C,CAAC,CAAC;EACJ;;EACA,OAAOA,GAAG;AACZ,CAAC;;AAEH;AACA;AACA;AACA,OAAO,MAAMM,oBAAoB,GAC/BC,QAAkB;EAAA,IAAAC,qBAAA;EAAA,OAElB,CAAAA,qBAAA,GAAAD,QAAQ,CAACE,OAAO,CAACC,GAAG,CAAC,cAAc,CAAC,cAAAF,qBAAA,eAApCA,qBAAA,CAAsCG,QAAQ,CAAC,kBAAkB,CAAC,GAC7DJ,QAAQ,CAACK,IAAI,CAAC,CAAC,GAChBL,QAAQ,CAACM,IAAI,CAAC,CAAC;AAAA;;AAErB;AACA;AAOA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gCAAgC,GAAIC,IAAY,IAC3DC,KAAK,CAACC,IAAI,CAACD,KAAK,CAACD,IAAI,CAAC,EAAE,MACtBG,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAACC,QAAQ,CAAC,EAAE,CAC5C,CAAC,CAACC,IAAI,CAAC,EAAE,CAAC;;AAEZ;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iCAAiC,GAAG,MAC/CC,UAAkB,IACE;EACpB,MAAMC,UAAU,GAAGD,UAAU,CAACE,OAAO,CAAC,GAAG,CAAC;EAC1C,IAAID,UAAU,KAAK,CAAC,CAAC,EAAE;IACrB,MAAM,IAAI/B,aAAa,CAAC,2BAA2B,CAAC;EACtD;EACA,OAAOE,MAAM,CAAC4B,UAAU,CAACG,KAAK,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,OAAO,MAAMG,aAAa,GAAGA,CAAIf,IAAY,EAAEgB,WAAe,KAAe;EAC3E,IAAI;IACF,OAAOC,IAAI,CAACC,KAAK,CAAClB,IAAI,CAAC;EACzB,CAAC,CAAC,OAAOmB,CAAC,EAAE;IACV,OAAOH,WAAW,IAAI,IAAI;EAC5B;AACF,CAAC"}
|
@@ -25,7 +25,7 @@ export type StartUserAuthorization = (issuerConf: Out<EvaluateIssuerTrust>["issu
|
|
25
25
|
* the application session identifier on the Wallet Instance side (state),
|
26
26
|
* the method (query or form_post.jwt) by which the Authorization Server
|
27
27
|
* should transmit the Authorization Response containing the authorization code issued upon the end user's authentication (response_mode)
|
28
|
-
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the
|
28
|
+
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the redirectUri of the Wallet Instance where the Authorization Response
|
29
29
|
* should be delivered. The redirect is achived by using a custom URL scheme that the Wallet Instance is registered to handle.
|
30
30
|
* @param issuerConf The issuer configuration
|
31
31
|
* @param credentialType The type of the credential to be requested returned by {@link selectCredentialDefinition}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { type
|
1
|
+
import { type AuthorizationResult } from "../../utils/auth";
|
2
2
|
import { type Out } from "../../utils/misc";
|
3
3
|
import type { StartUserAuthorization } from "./03-start-user-authorization";
|
4
4
|
import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
|
@@ -7,7 +7,7 @@ import { RequestObject } from "../presentation/types";
|
|
7
7
|
/**
|
8
8
|
* The interface of the phase to complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
9
9
|
*/
|
10
|
-
export type CompleteUserAuthorizationWithQueryMode = (
|
10
|
+
export type CompleteUserAuthorizationWithQueryMode = (authRedirectUrl: string) => Promise<AuthorizationResult>;
|
11
11
|
export type CompleteUserAuthorizationWithFormPostJwtMode = (requestObject: Out<GetRequestedCredentialToBePresented>, context: {
|
12
12
|
wiaCryptoContext: CryptoContext;
|
13
13
|
pidCryptoContext: CryptoContext;
|
@@ -16,23 +16,24 @@ export type CompleteUserAuthorizationWithFormPostJwtMode = (requestObject: Out<G
|
|
16
16
|
appFetch?: GlobalFetch["fetch"];
|
17
17
|
}) => Promise<AuthorizationResult>;
|
18
18
|
export type GetRequestedCredentialToBePresented = (issuerRequestUri: Out<StartUserAuthorization>["issuerRequestUri"], clientId: Out<StartUserAuthorization>["clientId"], issuerConf: Out<EvaluateIssuerTrust>["issuerConf"], appFetch?: GlobalFetch["fetch"]) => Promise<RequestObject>;
|
19
|
+
export type BuildAuthorizationUrl = (issuerRequestUri: Out<StartUserAuthorization>["issuerRequestUri"], clientId: Out<StartUserAuthorization>["clientId"], issuerConf: Out<EvaluateIssuerTrust>["issuerConf"], idpHint: string) => Promise<{
|
20
|
+
authUrl: string;
|
21
|
+
}>;
|
19
22
|
/**
|
20
|
-
* WARNING: This function must be called after {@link startUserAuthorization}. The
|
21
|
-
*
|
22
|
-
* It is used to complete the user authorization by catching the redirectSchema from the authorization server which then contains the authorization response.
|
23
|
-
* This function utilizes the authorization context to open an in-app browser capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
24
|
-
* If the 302 redirect happens and the redirectSchema is caught, the function will return the authorization response after parsing it from the query string.
|
23
|
+
* WARNING: This function must be called after {@link startUserAuthorization}. The generated authUrl must be used to open a browser or webview capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
24
|
+
* Builds the authorization URL to which the end user should be redirected to continue the authentication flow.
|
25
25
|
* @param issuerRequestUri the URI of the issuer where the request is sent
|
26
26
|
* @param clientId Identifies the current client across all the requests of the issuing flow returned by {@link startUserAuthorization}
|
27
27
|
* @param issuerConf The issuer configuration returned by {@link evaluateIssuerTrust}
|
28
|
-
* @param
|
29
|
-
*
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
*
|
34
|
-
*
|
35
|
-
*
|
28
|
+
* @param idpHint Unique identifier of the IDP selected by the user
|
29
|
+
* @returns An object containing the authorization URL
|
30
|
+
*/
|
31
|
+
export declare const buildAuthorizationUrl: BuildAuthorizationUrl;
|
32
|
+
/**
|
33
|
+
* WARNING: This function must be called after obtaining the authorization redirect URL from the webviews (SPID and CIE L3) or browser for CIEID.
|
34
|
+
* Complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
35
|
+
* This function parses the authorization redirect URL to extract the authorization response.
|
36
|
+
* @param authRedirectUrl The URL to which the end user should be redirected to start the authentication flow
|
36
37
|
* @returns the authorization response which contains code, state and iss
|
37
38
|
*/
|
38
39
|
export declare const completeUserAuthorizationWithQueryMode: CompleteUserAuthorizationWithQueryMode;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"04-complete-user-authorization.d.ts","sourceRoot":"","sources":["../../../../src/credential/issuance/04-complete-user-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,
|
1
|
+
{"version":3,"file":"04-complete-user-authorization.d.ts","sourceRoot":"","sources":["../../../../src/credential/issuance/04-complete-user-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAoB,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAG5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAMtD;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAAG,CACnD,eAAe,EAAE,MAAM,KACpB,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC,MAAM,MAAM,4CAA4C,GAAG,CACzD,aAAa,EAAE,GAAG,CAAC,mCAAmC,CAAC,EACvD,OAAO,EAAE;IACP,gBAAgB,EAAE,aAAa,CAAC;IAChC,gBAAgB,EAAE,aAAa,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CACjC,KACE,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC,MAAM,MAAM,mCAAmC,GAAG,CAChD,gBAAgB,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,kBAAkB,CAAC,EACjE,QAAQ,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,UAAU,CAAC,EACjD,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAClD,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KAC5B,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,MAAM,qBAAqB,GAAG,CAClC,gBAAgB,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,kBAAkB,CAAC,EACjE,QAAQ,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,UAAU,CAAC,EACjD,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAClD,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,qBAkBnC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sCAAsC,EAAE,sCAKlD,CAAC;AAEJ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mCAAmC,EAAE,mCAyB/C,CAAC;AAEJ;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4CAA4C,EAAE,4CAuGxD,CAAC;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,YAC5B,OAAO,KACf,mBAaF,CAAC"}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { type StartFlow } from "./01-start-flow";
|
2
2
|
import { evaluateIssuerTrust, type EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
|
3
3
|
import { startUserAuthorization, type StartUserAuthorization } from "./03-start-user-authorization";
|
4
|
-
import { completeUserAuthorizationWithQueryMode, completeUserAuthorizationWithFormPostJwtMode, parseAuthorizationResponse, type CompleteUserAuthorizationWithQueryMode, type CompleteUserAuthorizationWithFormPostJwtMode, type GetRequestedCredentialToBePresented, getRequestedCredentialToBePresented } from "./04-complete-user-authorization";
|
4
|
+
import { completeUserAuthorizationWithQueryMode, completeUserAuthorizationWithFormPostJwtMode, parseAuthorizationResponse, buildAuthorizationUrl, type CompleteUserAuthorizationWithQueryMode, type CompleteUserAuthorizationWithFormPostJwtMode, type GetRequestedCredentialToBePresented, type BuildAuthorizationUrl, getRequestedCredentialToBePresented } from "./04-complete-user-authorization";
|
5
5
|
import { authorizeAccess, type AuthorizeAccess } from "./05-authorize-access";
|
6
6
|
import { obtainCredential, type ObtainCredential } from "./06-obtain-credential";
|
7
7
|
import { verifyAndParseCredential, type VerifyAndParseCredential } from "./07-verify-and-parse-credential";
|
8
8
|
import * as Errors from "./errors";
|
9
|
-
export { evaluateIssuerTrust, startUserAuthorization, completeUserAuthorizationWithQueryMode, getRequestedCredentialToBePresented, completeUserAuthorizationWithFormPostJwtMode, authorizeAccess, obtainCredential, verifyAndParseCredential, parseAuthorizationResponse, Errors, };
|
10
|
-
export type { StartFlow, EvaluateIssuerTrust, StartUserAuthorization, CompleteUserAuthorizationWithQueryMode, GetRequestedCredentialToBePresented, CompleteUserAuthorizationWithFormPostJwtMode, AuthorizeAccess, ObtainCredential, VerifyAndParseCredential, };
|
9
|
+
export { evaluateIssuerTrust, startUserAuthorization, buildAuthorizationUrl, completeUserAuthorizationWithQueryMode, getRequestedCredentialToBePresented, completeUserAuthorizationWithFormPostJwtMode, authorizeAccess, obtainCredential, verifyAndParseCredential, parseAuthorizationResponse, Errors, };
|
10
|
+
export type { StartFlow, EvaluateIssuerTrust, StartUserAuthorization, BuildAuthorizationUrl, CompleteUserAuthorizationWithQueryMode, GetRequestedCredentialToBePresented, CompleteUserAuthorizationWithFormPostJwtMode, AuthorizeAccess, ObtainCredential, VerifyAndParseCredential, };
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/credential/issuance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sCAAsC,EACtC,4CAA4C,EAC5C,0BAA0B,EAC1B,KAAK,sCAAsC,EAC3C,KAAK,4CAA4C,EACjD,KAAK,mCAAmC,EACxC,mCAAmC,EACpC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sCAAsC,EACtC,mCAAmC,EACnC,4CAA4C,EAC5C,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,GACP,CAAC;AACF,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,sBAAsB,EACtB,sCAAsC,EACtC,mCAAmC,EACnC,4CAA4C,EAC5C,eAAe,EACf,gBAAgB,EAChB,wBAAwB,GACzB,CAAC"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/credential/issuance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sCAAsC,EACtC,4CAA4C,EAC5C,0BAA0B,EAC1B,qBAAqB,EACrB,KAAK,sCAAsC,EAC3C,KAAK,4CAA4C,EACjD,KAAK,mCAAmC,EACxC,KAAK,qBAAqB,EAC1B,mCAAmC,EACpC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sCAAsC,EACtC,mCAAmC,EACnC,4CAA4C,EAC5C,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,GACP,CAAC;AACF,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sCAAsC,EACtC,mCAAmC,EACnC,4CAA4C,EAC5C,eAAe,EACf,gBAAgB,EAChB,wBAAwB,GACzB,CAAC"}
|
@@ -7,6 +7,10 @@ import { UnexpectedStatusCodeError } from "./errors";
|
|
7
7
|
* @returns The given response object
|
8
8
|
*/
|
9
9
|
export declare const hasStatusOrThrow: (status: number, customError?: typeof UnexpectedStatusCodeError) => (res: Response) => Promise<Response>;
|
10
|
+
/**
|
11
|
+
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
12
|
+
*/
|
13
|
+
export declare const parseRawHttpResponse: <T extends Record<string, unknown>>(response: Response) => Promise<string> | Promise<T>;
|
10
14
|
export type Out<FN> = FN extends (...args: any[]) => Promise<any> ? Awaited<ReturnType<FN>> : FN extends (...args: any[]) => any ? ReturnType<FN> : never;
|
11
15
|
/**
|
12
16
|
* TODO [SIW-1310]: replace this function with a cryptographically secure one.
|
@@ -14,18 +18,6 @@ export type Out<FN> = FN extends (...args: any[]) => Promise<any> ? Awaited<Retu
|
|
14
18
|
* @returns A random alphanumeric string of the given size
|
15
19
|
*/
|
16
20
|
export declare const generateRandomAlphaNumericString: (size: number) => string;
|
17
|
-
/**
|
18
|
-
* Repeatedly checks a condition function until it returns true,
|
19
|
-
* then resolves the returned promise. If the condition function does not return true
|
20
|
-
* within the specified timeout, the promise is rejected.
|
21
|
-
*
|
22
|
-
* @param conditionFunction - A function that returns a boolean value.
|
23
|
-
* The promise resolves when this function returns true.
|
24
|
-
* @param timeout - An optional timeout in seconds. The promise is rejected if the
|
25
|
-
* condition function does not return true within this time.
|
26
|
-
* @returns A promise that resolves once the conditionFunction returns true or rejects if timed out.
|
27
|
-
*/
|
28
|
-
export declare const until: (conditionFunction: () => boolean, timeoutSeconds?: number) => Promise<void>;
|
29
21
|
/**
|
30
22
|
* Get the hash of a credential without discloures.
|
31
23
|
* A credential is a string like `header.body.sign~sd1~sd2....` where `~` is the separator between the credential and the discloures.
|
@@ -33,17 +25,5 @@ export declare const until: (conditionFunction: () => boolean, timeoutSeconds?:
|
|
33
25
|
* @returns The hash of the credential without discloures
|
34
26
|
*/
|
35
27
|
export declare const getCredentialHashWithouDiscloures: (credential: string) => Promise<string>;
|
36
|
-
|
37
|
-
* Creates a promise that waits until the provided signal is aborted.
|
38
|
-
* @returns {Object} An object with `listen` and `remove` methods to handle subscribing and unsubscribing.
|
39
|
-
*/
|
40
|
-
export declare const createAbortPromiseFromSignal: (signal: AbortSignal) => {
|
41
|
-
listen: () => Promise<"OPERATION_ABORTED">;
|
42
|
-
remove: () => void;
|
43
|
-
};
|
44
|
-
export declare const isDefined: <T>(x: "" | T | null | undefined) => x is T;
|
45
|
-
/**
|
46
|
-
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
47
|
-
*/
|
48
|
-
export declare const parseRawHttpResponse: <T extends Record<string, unknown>>(response: Response) => Promise<string> | Promise<T>;
|
28
|
+
export declare const safeJsonParse: <T>(text: string, withDefault?: T | undefined) => T | null;
|
49
29
|
//# sourceMappingURL=misc.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../src/utils/misc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGpE;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,WAClB,MAAM,gBAAgB,gCAAgC,WACnD,QAAQ,KAAG,QAAQ,QAAQ,CAUtC,CAAC;
|
1
|
+
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../src/utils/misc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGpE;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,WAClB,MAAM,gBAAgB,gCAAgC,WACnD,QAAQ,KAAG,QAAQ,QAAQ,CAUtC,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,oBAAoB,gDACrB,QAAQ,iCAIC,CAAC;AAItB,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAC7D,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,GACvB,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAClC,UAAU,CAAC,EAAE,CAAC,GACd,KAAK,CAAC;AAEV;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,SAAU,MAAM,WAGjD,CAAC;AAEb;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,eAChC,MAAM,KACjB,QAAQ,MAAM,CAMhB,CAAC;AAEF,eAAO,MAAM,aAAa,YAAa,MAAM,0CAM5C,CAAC"}
|
package/package.json
CHANGED
@@ -88,7 +88,7 @@ const selectResponseMode = (
|
|
88
88
|
* the application session identifier on the Wallet Instance side (state),
|
89
89
|
* the method (query or form_post.jwt) by which the Authorization Server
|
90
90
|
* should transmit the Authorization Response containing the authorization code issued upon the end user's authentication (response_mode)
|
91
|
-
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the
|
91
|
+
* to the Wallet Instance's Token Endpoint to obtain the Access Token, and the redirectUri of the Wallet Instance where the Authorization Response
|
92
92
|
* should be delivered. The redirect is achived by using a custom URL scheme that the Wallet Instance is registered to handle.
|
93
93
|
* @param issuerConf The issuer configuration
|
94
94
|
* @param credentialType The type of the credential to be requested returned by {@link selectCredentialDefinition}
|
@@ -1,21 +1,13 @@
|
|
1
1
|
import {
|
2
2
|
AuthorizationErrorShape,
|
3
3
|
AuthorizationResultShape,
|
4
|
-
type AuthorizationContext,
|
5
4
|
type AuthorizationResult,
|
6
5
|
} from "../../utils/auth";
|
7
|
-
import {
|
8
|
-
createAbortPromiseFromSignal,
|
9
|
-
hasStatusOrThrow,
|
10
|
-
isDefined,
|
11
|
-
until,
|
12
|
-
type Out,
|
13
|
-
} from "../../utils/misc";
|
6
|
+
import { hasStatusOrThrow, type Out } from "../../utils/misc";
|
14
7
|
import type { StartUserAuthorization } from "./03-start-user-authorization";
|
15
8
|
import parseUrl from "parse-url";
|
16
9
|
import { IssuerResponseError, ValidationFailed } from "../../utils/errors";
|
17
10
|
import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
|
18
|
-
import { Linking } from "react-native";
|
19
11
|
import {
|
20
12
|
decode,
|
21
13
|
encodeBase64,
|
@@ -26,23 +18,13 @@ import { RequestObject } from "../presentation/types";
|
|
26
18
|
import uuid from "react-native-uuid";
|
27
19
|
import { ResponseUriResultShape } from "./types";
|
28
20
|
import { getJwtFromFormPost } from "../../utils/decoder";
|
29
|
-
import {
|
30
|
-
AuthorizationError,
|
31
|
-
AuthorizationIdpError,
|
32
|
-
OperationAbortedError,
|
33
|
-
} from "./errors";
|
21
|
+
import { AuthorizationError, AuthorizationIdpError } from "./errors";
|
34
22
|
|
35
23
|
/**
|
36
24
|
* The interface of the phase to complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
37
25
|
*/
|
38
26
|
export type CompleteUserAuthorizationWithQueryMode = (
|
39
|
-
|
40
|
-
clientId: Out<StartUserAuthorization>["clientId"],
|
41
|
-
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
|
42
|
-
idpHint: string,
|
43
|
-
redirectUri: string,
|
44
|
-
authorizationContext?: AuthorizationContext,
|
45
|
-
signal?: AbortSignal
|
27
|
+
authRedirectUrl: string
|
46
28
|
) => Promise<AuthorizationResult>;
|
47
29
|
|
48
30
|
export type CompleteUserAuthorizationWithFormPostJwtMode = (
|
@@ -63,98 +45,55 @@ export type GetRequestedCredentialToBePresented = (
|
|
63
45
|
appFetch?: GlobalFetch["fetch"]
|
64
46
|
) => Promise<RequestObject>;
|
65
47
|
|
48
|
+
export type BuildAuthorizationUrl = (
|
49
|
+
issuerRequestUri: Out<StartUserAuthorization>["issuerRequestUri"],
|
50
|
+
clientId: Out<StartUserAuthorization>["clientId"],
|
51
|
+
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
|
52
|
+
idpHint: string
|
53
|
+
) => Promise<{
|
54
|
+
authUrl: string;
|
55
|
+
}>;
|
56
|
+
|
66
57
|
/**
|
67
|
-
* WARNING: This function must be called after {@link startUserAuthorization}. The
|
68
|
-
*
|
69
|
-
* It is used to complete the user authorization by catching the redirectSchema from the authorization server which then contains the authorization response.
|
70
|
-
* This function utilizes the authorization context to open an in-app browser capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
71
|
-
* If the 302 redirect happens and the redirectSchema is caught, the function will return the authorization response after parsing it from the query string.
|
58
|
+
* WARNING: This function must be called after {@link startUserAuthorization}. The generated authUrl must be used to open a browser or webview capable of catching the redirectSchema to perform a get request to the authorization endpoint.
|
59
|
+
* Builds the authorization URL to which the end user should be redirected to continue the authentication flow.
|
72
60
|
* @param issuerRequestUri the URI of the issuer where the request is sent
|
73
61
|
* @param clientId Identifies the current client across all the requests of the issuing flow returned by {@link startUserAuthorization}
|
74
62
|
* @param issuerConf The issuer configuration returned by {@link evaluateIssuerTrust}
|
75
|
-
* @param
|
76
|
-
*
|
77
|
-
* @param idphint Unique identifier of the SPID IDP selected by the user
|
78
|
-
* @param redirectUri The url to reach to complete the user authorization which is the custom URL scheme that the Wallet Instance is registered to handle, usually a custom URL or deeplink
|
79
|
-
* @param signal An optional {@link AbortSignal} to abort the operation when using the default browser
|
80
|
-
* @throws {AuthorizationError} if an error occurs during the authorization process
|
81
|
-
* @throws {AuthorizationIdpError} if an error occurs during the authorization process and the error is related to the IDP
|
82
|
-
* @throws {OperationAbortedError} if the caller aborts the operation via the provided signal
|
83
|
-
* @returns the authorization response which contains code, state and iss
|
63
|
+
* @param idpHint Unique identifier of the IDP selected by the user
|
64
|
+
* @returns An object containing the authorization URL
|
84
65
|
*/
|
85
|
-
export const
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
signal
|
94
|
-
) => {
|
95
|
-
const authzRequestEndpoint =
|
96
|
-
issuerConf.oauth_authorization_server.authorization_endpoint;
|
97
|
-
const params = new URLSearchParams({
|
98
|
-
client_id: clientId,
|
99
|
-
request_uri: issuerRequestUri,
|
100
|
-
idphint: idpHint,
|
101
|
-
});
|
102
|
-
const authUrl = `${authzRequestEndpoint}?${params}`;
|
103
|
-
var authRedirectUrl: string | undefined;
|
104
|
-
|
105
|
-
if (authorizationContext) {
|
106
|
-
const redirectSchema = new URL(redirectUri).protocol.replace(":", "");
|
107
|
-
authRedirectUrl = await authorizationContext
|
108
|
-
.authorize(authUrl, redirectSchema)
|
109
|
-
.catch((e) => {
|
110
|
-
throw new AuthorizationError(e.message);
|
111
|
-
});
|
112
|
-
} else {
|
113
|
-
// handler for redirectUri
|
114
|
-
const urlEventListener = Linking.addEventListener("url", ({ url }) => {
|
115
|
-
if (url.includes(redirectUri)) {
|
116
|
-
authRedirectUrl = url;
|
117
|
-
}
|
118
|
-
});
|
119
|
-
|
120
|
-
const operationIsAborted = signal
|
121
|
-
? createAbortPromiseFromSignal(signal)
|
122
|
-
: undefined;
|
123
|
-
await Linking.openURL(authUrl);
|
66
|
+
export const buildAuthorizationUrl: BuildAuthorizationUrl = async (
|
67
|
+
issuerRequestUri,
|
68
|
+
clientId,
|
69
|
+
issuerConf,
|
70
|
+
idpHint
|
71
|
+
) => {
|
72
|
+
const authzRequestEndpoint =
|
73
|
+
issuerConf.oauth_authorization_server.authorization_endpoint;
|
124
74
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
() => authRedirectUrl !== undefined,
|
131
|
-
120
|
132
|
-
);
|
133
|
-
|
134
|
-
/**
|
135
|
-
* Simultaneously listen for the abort signal (when provided) and the redirect url.
|
136
|
-
* The first event that occurs will resolve the promise.
|
137
|
-
* This is useful to properly cleanup when the caller aborts this operation.
|
138
|
-
*/
|
139
|
-
const winner = await Promise.race(
|
140
|
-
[operationIsAborted?.listen(), unitAuthRedirectIsNotUndefined].filter(
|
141
|
-
isDefined
|
142
|
-
)
|
143
|
-
).finally(() => {
|
144
|
-
urlEventListener.remove();
|
145
|
-
operationIsAborted?.remove();
|
146
|
-
});
|
75
|
+
const params = new URLSearchParams({
|
76
|
+
client_id: clientId,
|
77
|
+
request_uri: issuerRequestUri,
|
78
|
+
idphint: idpHint,
|
79
|
+
});
|
147
80
|
|
148
|
-
|
149
|
-
throw new OperationAbortedError("DefaultQueryModeAuthorization");
|
150
|
-
}
|
81
|
+
const authUrl = `${authzRequestEndpoint}?${params}`;
|
151
82
|
|
152
|
-
|
153
|
-
|
154
|
-
}
|
155
|
-
}
|
83
|
+
return { authUrl };
|
84
|
+
};
|
156
85
|
|
86
|
+
/**
|
87
|
+
* WARNING: This function must be called after obtaining the authorization redirect URL from the webviews (SPID and CIE L3) or browser for CIEID.
|
88
|
+
* Complete User authorization via strong identification when the response mode is "query" and the request credential is a PersonIdentificationData.
|
89
|
+
* This function parses the authorization redirect URL to extract the authorization response.
|
90
|
+
* @param authRedirectUrl The URL to which the end user should be redirected to start the authentication flow
|
91
|
+
* @returns the authorization response which contains code, state and iss
|
92
|
+
*/
|
93
|
+
export const completeUserAuthorizationWithQueryMode: CompleteUserAuthorizationWithQueryMode =
|
94
|
+
async (authRedirectUrl) => {
|
157
95
|
const query = parseUrl(authRedirectUrl).query;
|
96
|
+
|
158
97
|
return parseAuthorizationResponse(query);
|
159
98
|
};
|
160
99
|
|
@@ -11,9 +11,11 @@ import {
|
|
11
11
|
completeUserAuthorizationWithQueryMode,
|
12
12
|
completeUserAuthorizationWithFormPostJwtMode,
|
13
13
|
parseAuthorizationResponse,
|
14
|
+
buildAuthorizationUrl,
|
14
15
|
type CompleteUserAuthorizationWithQueryMode,
|
15
16
|
type CompleteUserAuthorizationWithFormPostJwtMode,
|
16
17
|
type GetRequestedCredentialToBePresented,
|
18
|
+
type BuildAuthorizationUrl,
|
17
19
|
getRequestedCredentialToBePresented,
|
18
20
|
} from "./04-complete-user-authorization";
|
19
21
|
import { authorizeAccess, type AuthorizeAccess } from "./05-authorize-access";
|
@@ -30,6 +32,7 @@ import * as Errors from "./errors";
|
|
30
32
|
export {
|
31
33
|
evaluateIssuerTrust,
|
32
34
|
startUserAuthorization,
|
35
|
+
buildAuthorizationUrl,
|
33
36
|
completeUserAuthorizationWithQueryMode,
|
34
37
|
getRequestedCredentialToBePresented,
|
35
38
|
completeUserAuthorizationWithFormPostJwtMode,
|
@@ -43,6 +46,7 @@ export type {
|
|
43
46
|
StartFlow,
|
44
47
|
EvaluateIssuerTrust,
|
45
48
|
StartUserAuthorization,
|
49
|
+
BuildAuthorizationUrl,
|
46
50
|
CompleteUserAuthorizationWithQueryMode,
|
47
51
|
GetRequestedCredentialToBePresented,
|
48
52
|
CompleteUserAuthorizationWithFormPostJwtMode,
|
package/src/utils/misc.ts
CHANGED
@@ -22,6 +22,16 @@ export const hasStatusOrThrow =
|
|
22
22
|
return res;
|
23
23
|
};
|
24
24
|
|
25
|
+
/**
|
26
|
+
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
27
|
+
*/
|
28
|
+
export const parseRawHttpResponse = <T extends Record<string, unknown>>(
|
29
|
+
response: Response
|
30
|
+
) =>
|
31
|
+
response.headers.get("content-type")?.includes("application/json")
|
32
|
+
? (response.json() as Promise<T>)
|
33
|
+
: response.text();
|
34
|
+
|
25
35
|
// extract a type from an async function output
|
26
36
|
// helpful to bind the input of a function to the output of another
|
27
37
|
export type Out<FN> = FN extends (...args: any[]) => Promise<any>
|
@@ -40,39 +50,6 @@ export const generateRandomAlphaNumericString = (size: number) =>
|
|
40
50
|
Math.floor(Math.random() * 36).toString(36)
|
41
51
|
).join("");
|
42
52
|
|
43
|
-
/**
|
44
|
-
* Repeatedly checks a condition function until it returns true,
|
45
|
-
* then resolves the returned promise. If the condition function does not return true
|
46
|
-
* within the specified timeout, the promise is rejected.
|
47
|
-
*
|
48
|
-
* @param conditionFunction - A function that returns a boolean value.
|
49
|
-
* The promise resolves when this function returns true.
|
50
|
-
* @param timeout - An optional timeout in seconds. The promise is rejected if the
|
51
|
-
* condition function does not return true within this time.
|
52
|
-
* @returns A promise that resolves once the conditionFunction returns true or rejects if timed out.
|
53
|
-
*/
|
54
|
-
export const until = (
|
55
|
-
conditionFunction: () => boolean,
|
56
|
-
timeoutSeconds?: number
|
57
|
-
): Promise<void> =>
|
58
|
-
new Promise<void>((resolve, reject) => {
|
59
|
-
const start = Date.now();
|
60
|
-
const poll = () => {
|
61
|
-
if (conditionFunction()) {
|
62
|
-
resolve();
|
63
|
-
} else if (
|
64
|
-
timeoutSeconds !== undefined &&
|
65
|
-
Date.now() - start >= timeoutSeconds * 1000
|
66
|
-
) {
|
67
|
-
reject(new Error("Timeout exceeded"));
|
68
|
-
} else {
|
69
|
-
setTimeout(poll, 400);
|
70
|
-
}
|
71
|
-
};
|
72
|
-
|
73
|
-
poll();
|
74
|
-
});
|
75
|
-
|
76
53
|
/**
|
77
54
|
* Get the hash of a credential without discloures.
|
78
55
|
* A credential is a string like `header.body.sign~sd1~sd2....` where `~` is the separator between the credential and the discloures.
|
@@ -89,34 +66,10 @@ export const getCredentialHashWithouDiscloures = async (
|
|
89
66
|
return sha256(credential.slice(0, tildeIndex));
|
90
67
|
};
|
91
68
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
return {
|
99
|
-
listen: () =>
|
100
|
-
new Promise<"OPERATION_ABORTED">((resolve) => {
|
101
|
-
if (signal.aborted) {
|
102
|
-
return resolve("OPERATION_ABORTED");
|
103
|
-
}
|
104
|
-
listener = () => resolve("OPERATION_ABORTED");
|
105
|
-
signal.addEventListener("abort", listener);
|
106
|
-
}),
|
107
|
-
remove: () => signal.removeEventListener("abort", listener),
|
108
|
-
};
|
69
|
+
export const safeJsonParse = <T>(text: string, withDefault?: T): T | null => {
|
70
|
+
try {
|
71
|
+
return JSON.parse(text);
|
72
|
+
} catch (_) {
|
73
|
+
return withDefault ?? null;
|
74
|
+
}
|
109
75
|
};
|
110
|
-
|
111
|
-
export const isDefined = <T>(x: T | undefined | null | ""): x is T =>
|
112
|
-
Boolean(x);
|
113
|
-
|
114
|
-
/**
|
115
|
-
* Utility function to parse a raw HTTP response as JSON if supported, otherwise as text.
|
116
|
-
*/
|
117
|
-
export const parseRawHttpResponse = <T extends Record<string, unknown>>(
|
118
|
-
response: Response
|
119
|
-
) =>
|
120
|
-
response.headers.get("content-type")?.includes("application/json")
|
121
|
-
? (response.json() as Promise<T>)
|
122
|
-
: response.text();
|