@itwin/map-layers-auth 4.3.0-dev.9 → 4.4.0-dev.1
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/CHANGELOG.md +33 -1
- package/lib/cjs/ArcGis/ArcGisAccessClient.d.ts +4 -2
- package/lib/cjs/ArcGis/ArcGisAccessClient.d.ts.map +1 -1
- package/lib/cjs/ArcGis/ArcGisAccessClient.js +46 -33
- package/lib/cjs/ArcGis/ArcGisAccessClient.js.map +1 -1
- package/lib/esm/ArcGis/ArcGisAccessClient.d.ts +4 -2
- package/lib/esm/ArcGis/ArcGisAccessClient.d.ts.map +1 -1
- package/lib/esm/ArcGis/ArcGisAccessClient.js +46 -33
- package/lib/esm/ArcGis/ArcGisAccessClient.js.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
# Change Log - @itwin/map-layers-auth
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 30 Nov 2023 17:07:27 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 4.2.4
|
|
6
|
+
Mon, 20 Nov 2023 16:14:45 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 4.2.3
|
|
11
|
+
Mon, 06 Nov 2023 14:01:52 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
14
|
+
|
|
15
|
+
## 4.2.2
|
|
16
|
+
Thu, 02 Nov 2023 15:36:21 GMT
|
|
17
|
+
|
|
18
|
+
### Updates
|
|
19
|
+
|
|
20
|
+
- Fix legacy token flow for ArcGIS services not supporting Oauth2.
|
|
21
|
+
|
|
22
|
+
## 4.2.1
|
|
23
|
+
Tue, 24 Oct 2023 15:09:13 GMT
|
|
24
|
+
|
|
25
|
+
_Version update only_
|
|
26
|
+
|
|
27
|
+
## 4.2.0
|
|
28
|
+
Tue, 17 Oct 2023 15:14:32 GMT
|
|
29
|
+
|
|
30
|
+
_Version update only_
|
|
4
31
|
|
|
5
32
|
## 4.1.9
|
|
6
33
|
Tue, 10 Oct 2023 18:48:12 GMT
|
|
@@ -98,6 +125,11 @@ Mon, 22 May 2023 15:34:14 GMT
|
|
|
98
125
|
- Update to eslint@8
|
|
99
126
|
- Upgrade TypeScript compile target to es2021.
|
|
100
127
|
|
|
128
|
+
## 3.7.17
|
|
129
|
+
Mon, 20 Nov 2023 18:24:23 GMT
|
|
130
|
+
|
|
131
|
+
_Version update only_
|
|
132
|
+
|
|
101
133
|
## 3.7.16
|
|
102
134
|
Mon, 16 Oct 2023 12:49:08 GMT
|
|
103
135
|
|
|
@@ -35,6 +35,8 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
35
35
|
private initOauthCallbackFunction;
|
|
36
36
|
unInitialize(): void;
|
|
37
37
|
getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined>;
|
|
38
|
+
/** @internal */
|
|
39
|
+
static validateOAuth2Endpoint(endpointUrl: string): Promise<boolean>;
|
|
38
40
|
getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined>;
|
|
39
41
|
invalidateToken(token: MapLayerAccessToken): boolean;
|
|
40
42
|
get redirectUri(): string | undefined;
|
|
@@ -47,8 +49,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
47
49
|
removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId): void;
|
|
48
50
|
/** @internal */
|
|
49
51
|
private getOAuthTokenForMapLayerUrl;
|
|
50
|
-
private
|
|
51
|
-
private _oauthTokenEndPointsCache;
|
|
52
|
+
private _endPointsCache;
|
|
52
53
|
/**
|
|
53
54
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
54
55
|
* @internal
|
|
@@ -64,6 +65,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
64
65
|
* @internal
|
|
65
66
|
*/
|
|
66
67
|
private isArcGisHostValid;
|
|
68
|
+
private validateEndpointUrl;
|
|
67
69
|
/**
|
|
68
70
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
69
71
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArcGisAccessClient.d.ts","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMnI,YAAY;AACZ,MAAM,WAAW,wBAAwB;IAGvC,cAAc,EAAE,MAAM,CAAC;IAGvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,YAAY;AACZ,MAAM,WAAW,oBAAoB;IAEnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,mBAAmB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClD;AAED;;;;EAIE;AACF,MAAM,WAAW,iBAAiB;IAIhC,WAAW,EAAE,MAAM,CAAC;IAGpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,SAAS,EAAE,oBAAoB,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"ArcGisAccessClient.d.ts","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMnI,YAAY;AACZ,MAAM,WAAW,wBAAwB;IAGvC,cAAc,EAAE,MAAM,CAAC;IAGvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,YAAY;AACZ,MAAM,WAAW,oBAAoB;IAEnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,mBAAmB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClD;AAED;;;;EAIE;AACF,MAAM,WAAW,iBAAiB;IAIhC,WAAW,EAAE,MAAM,CAAC;IAGpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,SAAS,EAAE,oBAAoB,CAAC;CACjC;AASD,YAAY;AACZ,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,SAAgB,iBAAiB,kDAAiB;IAClD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAAmC;IAGrD,OAAO,CAAC,iBAAiB,CAAS;;IAK3B,UAAU,CAAC,WAAW,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAW3D,OAAO,CAAC,yBAAyB;IAoC1B,YAAY;IAMN,cAAc,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAgBxG,gBAAgB;WACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpE,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAQ9F,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO;IAQ3D,IAAW,WAAW,uBAErB;IAEM,6BAA6B,CAAC,GAAG,EAAE,MAAM;IA0BhD,IAAW,UAAU,uBAEpB;IAED,IAAW,oBAAoB,IAIW,MAAM,GAAG,SAAS,CAF3D;IAED,IAAW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAK3D;IAED,IAAW,yBAAyB,2CAEnC;IAEM,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAiB9D,wBAAwB,CAAC,QAAQ,EAAE,wBAAwB;IASlE,gBAAgB;YACF,2BAA2B;IAezC,OAAO,CAAC,eAAe,CAA+C;IAEtE;;;KAGC;IACD,OAAO,CAAC,aAAa;IAKrB;;;KAGC;YACa,cAAc;IAO5B;;;MAGE;IACF,OAAO,CAAC,iBAAiB;YAQX,mBAAmB;IAYjC;;;KAGC;YACa,iBAAiB;IA8D/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
|
|
@@ -19,11 +19,10 @@ class ArcGisAccessClient {
|
|
|
19
19
|
this.onOAuthProcessEnd = new core_bentley_1.BeEvent();
|
|
20
20
|
// Should be kept to 'false'. Debugging purposes only.
|
|
21
21
|
this._forceLegacyToken = false;
|
|
22
|
-
//
|
|
22
|
+
// Mapping between a map-layer URL and its corresponding Oauth endpoint
|
|
23
23
|
// i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
|
|
24
24
|
// => https://hostname/portal/sharing/oauth2/authorize
|
|
25
|
-
this.
|
|
26
|
-
this._oauthTokenEndPointsCache = new Map();
|
|
25
|
+
this._endPointsCache = new Map();
|
|
27
26
|
}
|
|
28
27
|
initialize(oAuthConfig) {
|
|
29
28
|
if (oAuthConfig) {
|
|
@@ -84,20 +83,16 @@ class ArcGisAccessClient {
|
|
|
84
83
|
}
|
|
85
84
|
return undefined;
|
|
86
85
|
}
|
|
86
|
+
/** @internal */
|
|
87
|
+
static async validateOAuth2Endpoint(endpointUrl) {
|
|
88
|
+
const data = await fetch(endpointUrl, { method: "GET" });
|
|
89
|
+
return data.status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
|
|
90
|
+
}
|
|
87
91
|
async getTokenServiceEndPoint(mapLayerUrl) {
|
|
88
|
-
let tokenEndpoint;
|
|
89
92
|
if (!this._forceLegacyToken) {
|
|
90
|
-
|
|
91
|
-
// we could not make a reliable validation.
|
|
92
|
-
try {
|
|
93
|
-
tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
|
|
94
|
-
if (tokenEndpoint) {
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
}
|
|
93
|
+
return this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
|
|
99
94
|
}
|
|
100
|
-
return
|
|
95
|
+
return undefined;
|
|
101
96
|
}
|
|
102
97
|
invalidateToken(token) {
|
|
103
98
|
let found = ArcGisTokenManager_1.ArcGisTokenManager.invalidateToken(token);
|
|
@@ -187,22 +182,18 @@ class ArcGisAccessClient {
|
|
|
187
182
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
188
183
|
* @internal
|
|
189
184
|
*/
|
|
190
|
-
cacheEndpoint(url,
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
this._oauthTokenEndPointsCache.set(url, obj);
|
|
196
|
-
}
|
|
185
|
+
cacheEndpoint(url, endpointType, endPoint) {
|
|
186
|
+
const entry = endpointType === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? { authorizeEndpoint: endPoint } : { tokenEndpoint: endPoint };
|
|
187
|
+
this._endPointsCache.set(url, entry);
|
|
197
188
|
}
|
|
198
189
|
/**
|
|
199
190
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
200
191
|
* @internal
|
|
201
192
|
*/
|
|
202
|
-
async createEndpoint(
|
|
193
|
+
async createEndpoint(mapLayerUrl, oauthEndpointUrl, endpointType) {
|
|
203
194
|
// Validate the URL we just composed
|
|
204
|
-
const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(
|
|
205
|
-
this.cacheEndpoint(
|
|
195
|
+
const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(oauthEndpointUrl, this.constructLoginUrl(oauthEndpointUrl, false), false);
|
|
196
|
+
this.cacheEndpoint(mapLayerUrl, endpointType, oauthEndpoint);
|
|
206
197
|
return oauthEndpoint;
|
|
207
198
|
}
|
|
208
199
|
/**
|
|
@@ -215,18 +206,30 @@ class ArcGisAccessClient {
|
|
|
215
206
|
];
|
|
216
207
|
return allowedHosts.some((host) => url.hostname.toLowerCase().endsWith(host));
|
|
217
208
|
}
|
|
209
|
+
async validateEndpointUrl(url) {
|
|
210
|
+
let valid;
|
|
211
|
+
try {
|
|
212
|
+
valid = await ArcGisAccessClient.validateOAuth2Endpoint(url.toString());
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// If we reach here, this means we could not validate properly the endpoint;
|
|
216
|
+
// we cannot conclude the endpoint is invalid though; it might happen endpoint doesn't support CORS requests,
|
|
217
|
+
// but still valid for Oauth process.
|
|
218
|
+
}
|
|
219
|
+
return valid;
|
|
220
|
+
}
|
|
218
221
|
/**
|
|
219
222
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
220
223
|
* @internal
|
|
221
224
|
*/
|
|
222
|
-
async getOAuth2Endpoint(
|
|
225
|
+
async getOAuth2Endpoint(mapLayerUrl, endpointType) {
|
|
223
226
|
// Return from cache if available
|
|
224
|
-
const cachedEndpoint =
|
|
227
|
+
const cachedEndpoint = this._endPointsCache.get(mapLayerUrl);
|
|
225
228
|
if (cachedEndpoint !== undefined) {
|
|
226
|
-
return cachedEndpoint;
|
|
229
|
+
return (endpointType === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? cachedEndpoint.authorizeEndpoint : cachedEndpoint.authorizeEndpoint);
|
|
227
230
|
}
|
|
228
231
|
const endpointStr = (endpointType === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? "authorize" : "token");
|
|
229
|
-
const urlObj = new URL(
|
|
232
|
+
const urlObj = new URL(mapLayerUrl);
|
|
230
233
|
if (this.isArcGisHostValid(urlObj)) {
|
|
231
234
|
// ArcGIS Online (fixed)
|
|
232
235
|
// Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/
|
|
@@ -243,24 +246,34 @@ class ArcGisAccessClient {
|
|
|
243
246
|
if (restUrlFromTokenService === undefined) {
|
|
244
247
|
// We could not derive the token endpoint from 'tokenServicesUrl'.
|
|
245
248
|
// ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
|
|
246
|
-
const regExMatch =
|
|
249
|
+
const regExMatch = mapLayerUrl.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
|
|
247
250
|
if (regExMatch !== null && regExMatch.length >= 2) {
|
|
248
251
|
const subdirectory = regExMatch[1];
|
|
249
252
|
const port = (urlObj.port !== "80" && urlObj.port !== "443") ? `:${urlObj.port}` : "";
|
|
250
253
|
const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);
|
|
251
254
|
// Check again the URL we just composed
|
|
252
|
-
|
|
255
|
+
const isValidUrl = await this.validateEndpointUrl(newUrlObj.toString());
|
|
256
|
+
if (isValidUrl === undefined || isValidUrl) {
|
|
257
|
+
const endpoint = await this.createEndpoint(mapLayerUrl, newUrlObj.toString(), endpointType);
|
|
258
|
+
if (endpoint)
|
|
259
|
+
return endpoint;
|
|
260
|
+
}
|
|
253
261
|
}
|
|
254
262
|
}
|
|
255
263
|
else {
|
|
256
|
-
const
|
|
257
|
-
if (
|
|
258
|
-
|
|
264
|
+
const isValidUrl = await this.validateEndpointUrl(restUrlFromTokenService.toString());
|
|
265
|
+
if (isValidUrl === undefined || isValidUrl) {
|
|
266
|
+
const endpoint = await this.createEndpoint(mapLayerUrl, `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);
|
|
267
|
+
if (endpoint)
|
|
268
|
+
return endpoint;
|
|
269
|
+
}
|
|
259
270
|
}
|
|
260
271
|
}
|
|
261
272
|
catch {
|
|
262
273
|
}
|
|
263
274
|
}
|
|
275
|
+
// If we reach here, we were not successful creating an endpoint
|
|
276
|
+
this._endPointsCache.set(mapLayerUrl, {}); // Cache an empty entry, and avoid making repeated failing requests.
|
|
264
277
|
return undefined; // we could not find any valid oauth2 endpoint
|
|
265
278
|
}
|
|
266
279
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArcGisAccessClient.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, BeEvent } from \"@itwin/core-bentley\";\r\nimport { MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerTokenEndpoint } from \"@itwin/core-frontend\";\r\nimport { ArcGisOAuth2Token, ArcGisTokenClientType } from \"./ArcGisTokenGenerator\";\r\nimport { ArcGisOAuth2Endpoint, ArcGisOAuth2EndpointType } from \"./ArcGisOAuth2Endpoint\";\r\nimport { ArcGisTokenManager } from \"./ArcGisTokenManager\";\r\nimport { ArcGisUrl } from \"./ArcGisUrl\";\r\n\r\n/** @beta */\r\nexport interface ArcGisEnterpriseClientId {\r\n /* Oauth API endpoint base URL (i.e. https://hostname/portal/sharing/oauth2/authorize)\r\n used to identify uniquely each enterprise server. */\r\n serviceBaseUrl: string;\r\n\r\n /* Application's clientId for this enterprise server.*/\r\n clientId: string;\r\n}\r\n\r\n/** @beta */\r\nexport interface ArcGisOAuthClientIds {\r\n /* Application's OAuth clientId in ArcGIS online */\r\n arcgisOnlineClientId?: string;\r\n\r\n /* Application's OAuth clientId for each enterprise server used. */\r\n enterpriseClientIds?: ArcGisEnterpriseClientId[];\r\n}\r\n\r\n/** @beta\r\n * ArcGIS OAuth configurations parameters.\r\n * See https://developers.arcgis.com/documentation/mapping-apis-and-services/security/arcgis-identity/serverless-web-apps/\r\n * more details.\r\n*/\r\nexport interface ArcGisOAuthConfig {\r\n /* URL to which a user is sent once they complete sign in authorization.\r\n Must match a URI you define in the developer dashboard, otherwise, the authorization will be rejected.\r\n */\r\n redirectUri: string;\r\n\r\n /* Optional expiration after which the token will expire. Defined in minutes with a maximum of two weeks (20160 minutes)*/\r\n tokenExpiration?: number;\r\n\r\n /* Application client Ids */\r\n clientIds: ArcGisOAuthClientIds;\r\n}\r\n\r\n/** @beta */\r\nexport class ArcGisAccessClient implements MapLayerAccessClient {\r\n public readonly onOAuthProcessEnd = new BeEvent();\r\n private _redirectUri: string | undefined;\r\n private _expiration: number | undefined;\r\n private _clientIds: ArcGisOAuthClientIds | undefined;\r\n\r\n // Should be kept to 'false'. Debugging purposes only.\r\n private _forceLegacyToken = false;\r\n\r\n public constructor() {\r\n }\r\n\r\n public initialize(oAuthConfig?: ArcGisOAuthConfig): boolean {\r\n if (oAuthConfig) {\r\n this._redirectUri = oAuthConfig.redirectUri;\r\n this._expiration = oAuthConfig.tokenExpiration;\r\n this._clientIds = oAuthConfig.clientIds;\r\n\r\n this.initOauthCallbackFunction();\r\n }\r\n return true;\r\n }\r\n\r\n private initOauthCallbackFunction() {\r\n (window as any).arcGisOAuth2Callback = (redirectLocation?: Location) => {\r\n let eventSuccess = false;\r\n let stateData;\r\n\r\n if (redirectLocation && redirectLocation.hash.length > 0) {\r\n const locationHash = redirectLocation.hash;\r\n const hashParams = new URLSearchParams(locationHash.substring(1));\r\n const token = hashParams.get(\"access_token\") ?? undefined;\r\n const expiresInStr = hashParams.get(\"expires_in\") ?? undefined;\r\n const userName = hashParams.get(\"username\") ?? undefined;\r\n const ssl = hashParams.get(\"ssl\") === \"true\";\r\n const stateStr = hashParams.get(\"state\") ?? undefined;\r\n const persist = hashParams.get(\"persist\") === \"true\";\r\n if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {\r\n let endpointOrigin;\r\n try {\r\n const state = JSON.parse(stateStr);\r\n stateData = state?.customData;\r\n endpointOrigin = state?.endpointOrigin;\r\n\r\n } catch {\r\n }\r\n const expiresIn = Number(expiresInStr);\r\n const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)\r\n if (endpointOrigin !== undefined) {\r\n ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });\r\n eventSuccess = true;\r\n }\r\n\r\n }\r\n }\r\n this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);\r\n };\r\n }\r\n\r\n public unInitialize() {\r\n this._redirectUri = undefined;\r\n this._expiration = undefined;\r\n (window as any).arcGisOAuth2Callback = undefined;\r\n }\r\n\r\n public async getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined> {\r\n // First lookup Oauth2 tokens, otherwise check try \"legacy tokens\" if credentials were provided\r\n\r\n if (!this._forceLegacyToken) {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n }\r\n\r\n if (params.userName && params.password) {\r\n return ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public async getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined> {\r\n let tokenEndpoint: ArcGisOAuth2Endpoint | undefined;\r\n if (!this._forceLegacyToken) {\r\n // Note: we used to validate the endpoint by making a request, but because of CORS isssues with some servers\r\n // we could not make a reliable validation.\r\n try {\r\n tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (tokenEndpoint) {\r\n\r\n }\r\n } catch {\r\n\r\n }\r\n }\r\n\r\n return tokenEndpoint;\r\n }\r\n\r\n public invalidateToken(token: MapLayerAccessToken): boolean {\r\n let found = ArcGisTokenManager.invalidateToken(token);\r\n if (!found) {\r\n found = ArcGisTokenManager.invalidateOAuth2Token(token);\r\n }\r\n return found;\r\n }\r\n\r\n public get redirectUri() {\r\n return this._redirectUri;\r\n }\r\n\r\n public getMatchingEnterpriseClientId(url: string) {\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n\r\n let clientId: string | undefined;\r\n let defaultClientId: string | undefined;\r\n for (const entry of clientIds) {\r\n if (entry.serviceBaseUrl === \"\") {\r\n defaultClientId = entry.clientId;\r\n } else {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\r\n }\r\n }\r\n\r\n // If we could not find a match with serviceBaseUrl, and a default clientId\r\n // was specified (i.e empty url), then use default clientId\r\n if (clientId === undefined && defaultClientId !== undefined) {\r\n clientId = defaultClientId;\r\n }\r\n return clientId;\r\n }\r\n\r\n public get expiration() {\r\n return this._expiration;\r\n }\r\n\r\n public get arcGisOnlineClientId() {\r\n return this._clientIds?.arcgisOnlineClientId;\r\n }\r\n\r\n public set arcGisOnlineClientId(clientId: string | undefined) {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = { arcgisOnlineClientId: clientId };\r\n }\r\n this._clientIds.arcgisOnlineClientId = clientId;\r\n }\r\n\r\n public get arcGisEnterpriseClientIds() {\r\n return this._clientIds?.enterpriseClientIds;\r\n }\r\n\r\n public setEnterpriseClientId(serviceBaseUrl: string, clientId: string) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);\r\n if (foundIdx !== -1) {\r\n this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;\r\n } else {\r\n this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });\r\n }\r\n } else {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = {};\r\n }\r\n this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];\r\n }\r\n }\r\n\r\n public removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n this._clientIds.enterpriseClientIds = this._clientIds?.enterpriseClientIds?.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);\r\n }\r\n\r\n }\r\n\r\n /// //////////\r\n /** @internal */\r\n private async getOAuthTokenForMapLayerUrl(mapLayerUrl: string): Promise<ArcGisOAuth2Token | undefined> {\r\n try {\r\n const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (oauthEndpoint !== undefined) {\r\n const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());\r\n return ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);\r\n }\r\n } catch { }\r\n return undefined;\r\n }\r\n\r\n // Derive the Oauth URL from a typical MapLayerURL\r\n // i.e. \t https://hostname/server/rest/services/NewYork/NewYork3857/MapServer\r\n // => https://hostname/portal/sharing/oauth2/authorize\r\n private _oauthAuthorizeEndPointsCache = new Map<string, any>();\r\n private _oauthTokenEndPointsCache = new Map<string, any>();\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private cacheEndpoint(url: string, endpoint: ArcGisOAuth2EndpointType, obj: ArcGisOAuth2Endpoint) {\r\n if (endpoint === ArcGisOAuth2EndpointType.Authorize) {\r\n this._oauthAuthorizeEndPointsCache.set(url, obj);\r\n } else {\r\n this._oauthTokenEndPointsCache.set(url, obj);\r\n }\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async createEndpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Validate the URL we just composed\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(url, this.constructLoginUrl(url, false), false);\r\n this.cacheEndpoint(url, endpoint, oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n\r\n /**\r\n * Returns whether the ArcGis host is valid\r\n * @internal\r\n */\r\n private isArcGisHostValid(url: URL): boolean {\r\n const allowedHosts = [\r\n \"arcgis.com\",\r\n ];\r\n\r\n return allowedHosts.some((host: string) => url.hostname.toLowerCase().endsWith(host));\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async getOAuth2Endpoint(url: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Return from cache if available\r\n const cachedEndpoint = (endpointType === ArcGisOAuth2EndpointType.Authorize ? this._oauthAuthorizeEndPointsCache.get(url) : this._oauthTokenEndPointsCache.get(url));\r\n if (cachedEndpoint !== undefined) {\r\n return cachedEndpoint;\r\n }\r\n\r\n const endpointStr = (endpointType === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n\r\n const urlObj = new URL(url);\r\n\r\n if (this.isArcGisHostValid(urlObj)) {\r\n // ArcGIS Online (fixed)\r\n // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/\r\n\r\n if (this.arcGisOnlineClientId === undefined) {\r\n return undefined;\r\n }\r\n\r\n const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;\r\n return new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, true), true);\r\n } else {\r\n\r\n // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'\r\n try {\r\n const restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n if (restUrlFromTokenService === undefined) {\r\n // We could not derive the token endpoint from 'tokenServicesUrl'.\r\n // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize\r\n const regExMatch = url.match(new RegExp(/([^&\\/]+)\\/rest\\/services\\/.*/, \"i\"));\r\n if (regExMatch !== null && regExMatch.length >= 2) {\r\n const subdirectory = regExMatch[1];\r\n const port = (urlObj.port !== \"80\" && urlObj.port !== \"443\") ? `:${urlObj.port}` : \"\";\r\n const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);\r\n\r\n // Check again the URL we just composed\r\n return await this.createEndpoint(newUrlObj.toString(), endpointType);\r\n }\r\n } else {\r\n const endpoint = await this.createEndpoint(`${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n } catch {\r\n\r\n }\r\n\r\n }\r\n return undefined; // we could not find any valid oauth2 endpoint\r\n }\r\n\r\n /**\r\n * Construct the complete Authorize url to starts the Oauth process\r\n * @internal\r\n */\r\n private constructLoginUrl(url: string, isArcgisOnline: boolean) {\r\n const urlObj = new URL(url);\r\n\r\n // Set the client id\r\n if (isArcgisOnline) {\r\n const clientId = this.arcGisOnlineClientId;\r\n assert(clientId !== undefined);\r\n if (clientId !== undefined) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n\r\n } else {\r\n const clientId = this.getMatchingEnterpriseClientId(url);\r\n assert(clientId !== undefined);\r\n if (undefined !== clientId) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n }\r\n\r\n urlObj.searchParams.set(\"response_type\", \"token\");\r\n if (this.expiration !== undefined) {\r\n urlObj.searchParams.set(\"expiration\", `${this.expiration}`);\r\n }\r\n\r\n if (this.redirectUri)\r\n urlObj.searchParams.set(\"redirect_uri\", this.redirectUri);\r\n\r\n return urlObj.toString();\r\n }\r\n\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ArcGisAccessClient.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, BeEvent } from \"@itwin/core-bentley\";\r\nimport { MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerTokenEndpoint } from \"@itwin/core-frontend\";\r\nimport { ArcGisOAuth2Token, ArcGisTokenClientType } from \"./ArcGisTokenGenerator\";\r\nimport { ArcGisOAuth2Endpoint, ArcGisOAuth2EndpointType } from \"./ArcGisOAuth2Endpoint\";\r\nimport { ArcGisTokenManager } from \"./ArcGisTokenManager\";\r\nimport { ArcGisUrl } from \"./ArcGisUrl\";\r\n\r\n/** @beta */\r\nexport interface ArcGisEnterpriseClientId {\r\n /* Oauth API endpoint base URL (i.e. https://hostname/portal/sharing/oauth2/authorize)\r\n used to identify uniquely each enterprise server. */\r\n serviceBaseUrl: string;\r\n\r\n /* Application's clientId for this enterprise server.*/\r\n clientId: string;\r\n}\r\n\r\n/** @beta */\r\nexport interface ArcGisOAuthClientIds {\r\n /* Application's OAuth clientId in ArcGIS online */\r\n arcgisOnlineClientId?: string;\r\n\r\n /* Application's OAuth clientId for each enterprise server used. */\r\n enterpriseClientIds?: ArcGisEnterpriseClientId[];\r\n}\r\n\r\n/** @beta\r\n * ArcGIS OAuth configurations parameters.\r\n * See https://developers.arcgis.com/documentation/mapping-apis-and-services/security/arcgis-identity/serverless-web-apps/\r\n * more details.\r\n*/\r\nexport interface ArcGisOAuthConfig {\r\n /* URL to which a user is sent once they complete sign in authorization.\r\n Must match a URI you define in the developer dashboard, otherwise, the authorization will be rejected.\r\n */\r\n redirectUri: string;\r\n\r\n /* Optional expiration after which the token will expire. Defined in minutes with a maximum of two weeks (20160 minutes)*/\r\n tokenExpiration?: number;\r\n\r\n /* Application client Ids */\r\n clientIds: ArcGisOAuthClientIds;\r\n}\r\n\r\ninterface EndPointsCacheEntry {\r\n authorizeEndpoint?: ArcGisOAuth2Endpoint;\r\n tokenEndpoint?: ArcGisOAuth2Endpoint;\r\n}\r\n\r\ntype MapLayerUrl = string;\r\n\r\n/** @beta */\r\nexport class ArcGisAccessClient implements MapLayerAccessClient {\r\n public readonly onOAuthProcessEnd = new BeEvent();\r\n private _redirectUri: string | undefined;\r\n private _expiration: number | undefined;\r\n private _clientIds: ArcGisOAuthClientIds | undefined;\r\n\r\n // Should be kept to 'false'. Debugging purposes only.\r\n private _forceLegacyToken = false;\r\n\r\n public constructor() {\r\n }\r\n\r\n public initialize(oAuthConfig?: ArcGisOAuthConfig): boolean {\r\n if (oAuthConfig) {\r\n this._redirectUri = oAuthConfig.redirectUri;\r\n this._expiration = oAuthConfig.tokenExpiration;\r\n this._clientIds = oAuthConfig.clientIds;\r\n\r\n this.initOauthCallbackFunction();\r\n }\r\n return true;\r\n }\r\n\r\n private initOauthCallbackFunction() {\r\n (window as any).arcGisOAuth2Callback = (redirectLocation?: Location) => {\r\n let eventSuccess = false;\r\n let stateData;\r\n\r\n if (redirectLocation && redirectLocation.hash.length > 0) {\r\n const locationHash = redirectLocation.hash;\r\n const hashParams = new URLSearchParams(locationHash.substring(1));\r\n const token = hashParams.get(\"access_token\") ?? undefined;\r\n const expiresInStr = hashParams.get(\"expires_in\") ?? undefined;\r\n const userName = hashParams.get(\"username\") ?? undefined;\r\n const ssl = hashParams.get(\"ssl\") === \"true\";\r\n const stateStr = hashParams.get(\"state\") ?? undefined;\r\n const persist = hashParams.get(\"persist\") === \"true\";\r\n if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {\r\n let endpointOrigin;\r\n try {\r\n const state = JSON.parse(stateStr);\r\n stateData = state?.customData;\r\n endpointOrigin = state?.endpointOrigin;\r\n\r\n } catch {\r\n }\r\n const expiresIn = Number(expiresInStr);\r\n const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)\r\n if (endpointOrigin !== undefined) {\r\n ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });\r\n eventSuccess = true;\r\n }\r\n\r\n }\r\n }\r\n this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);\r\n };\r\n }\r\n\r\n public unInitialize() {\r\n this._redirectUri = undefined;\r\n this._expiration = undefined;\r\n (window as any).arcGisOAuth2Callback = undefined;\r\n }\r\n\r\n public async getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined> {\r\n // First lookup Oauth2 tokens, otherwise check try \"legacy tokens\" if credentials were provided\r\n\r\n if (!this._forceLegacyToken) {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n }\r\n\r\n if (params.userName && params.password) {\r\n return ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /** @internal */\r\n public static async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean> {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n return data.status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\r\n }\r\n\r\n public async getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined> {\r\n if (!this._forceLegacyToken) {\r\n return this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public invalidateToken(token: MapLayerAccessToken): boolean {\r\n let found = ArcGisTokenManager.invalidateToken(token);\r\n if (!found) {\r\n found = ArcGisTokenManager.invalidateOAuth2Token(token);\r\n }\r\n return found;\r\n }\r\n\r\n public get redirectUri() {\r\n return this._redirectUri;\r\n }\r\n\r\n public getMatchingEnterpriseClientId(url: string) {\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n\r\n let clientId: string | undefined;\r\n let defaultClientId: string | undefined;\r\n for (const entry of clientIds) {\r\n if (entry.serviceBaseUrl === \"\") {\r\n defaultClientId = entry.clientId;\r\n } else {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\r\n }\r\n }\r\n\r\n // If we could not find a match with serviceBaseUrl, and a default clientId\r\n // was specified (i.e empty url), then use default clientId\r\n if (clientId === undefined && defaultClientId !== undefined) {\r\n clientId = defaultClientId;\r\n }\r\n return clientId;\r\n }\r\n\r\n public get expiration() {\r\n return this._expiration;\r\n }\r\n\r\n public get arcGisOnlineClientId() {\r\n return this._clientIds?.arcgisOnlineClientId;\r\n }\r\n\r\n public set arcGisOnlineClientId(clientId: string | undefined) {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = { arcgisOnlineClientId: clientId };\r\n }\r\n this._clientIds.arcgisOnlineClientId = clientId;\r\n }\r\n\r\n public get arcGisEnterpriseClientIds() {\r\n return this._clientIds?.enterpriseClientIds;\r\n }\r\n\r\n public setEnterpriseClientId(serviceBaseUrl: string, clientId: string) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);\r\n if (foundIdx !== -1) {\r\n this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;\r\n } else {\r\n this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });\r\n }\r\n } else {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = {};\r\n }\r\n this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];\r\n }\r\n }\r\n\r\n public removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n this._clientIds.enterpriseClientIds = this._clientIds?.enterpriseClientIds?.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);\r\n }\r\n\r\n }\r\n\r\n /// //////////\r\n /** @internal */\r\n private async getOAuthTokenForMapLayerUrl(mapLayerUrl: string): Promise<ArcGisOAuth2Token | undefined> {\r\n try {\r\n const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (oauthEndpoint !== undefined) {\r\n const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());\r\n return ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);\r\n }\r\n } catch { }\r\n return undefined;\r\n }\r\n\r\n // Mapping between a map-layer URL and its corresponding Oauth endpoint\r\n // i.e. \t https://hostname/server/rest/services/NewYork/NewYork3857/MapServer\r\n // => https://hostname/portal/sharing/oauth2/authorize\r\n\r\n private _endPointsCache = new Map<MapLayerUrl, EndPointsCacheEntry>();\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private cacheEndpoint(url: MapLayerUrl, endpointType: ArcGisOAuth2EndpointType, endPoint: ArcGisOAuth2Endpoint) {\r\n const entry = endpointType === ArcGisOAuth2EndpointType.Authorize ? {authorizeEndpoint: endPoint} : {tokenEndpoint: endPoint};\r\n this._endPointsCache.set(url, entry);\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async createEndpoint(mapLayerUrl: MapLayerUrl, oauthEndpointUrl: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Validate the URL we just composed\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauthEndpointUrl, this.constructLoginUrl(oauthEndpointUrl, false), false);\r\n this.cacheEndpoint(mapLayerUrl, endpointType, oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n\r\n /**\r\n * Returns whether the ArcGis host is valid\r\n * @internal\r\n */\r\n private isArcGisHostValid(url: URL): boolean {\r\n const allowedHosts = [\r\n \"arcgis.com\",\r\n ];\r\n\r\n return allowedHosts.some((host: string) => url.hostname.toLowerCase().endsWith(host));\r\n }\r\n\r\n private async validateEndpointUrl(url: string) {\r\n let valid: boolean|undefined;\r\n try {\r\n valid = await ArcGisAccessClient.validateOAuth2Endpoint(url.toString());\r\n } catch {\r\n // If we reach here, this means we could not validate properly the endpoint;\r\n // we cannot conclude the endpoint is invalid though; it might happen endpoint doesn't support CORS requests,\r\n // but still valid for Oauth process.\r\n }\r\n return valid;\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async getOAuth2Endpoint(mapLayerUrl: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Return from cache if available\r\n const cachedEndpoint = this._endPointsCache.get(mapLayerUrl);\r\n if (cachedEndpoint !== undefined) {\r\n return (endpointType === ArcGisOAuth2EndpointType.Authorize ? cachedEndpoint.authorizeEndpoint : cachedEndpoint.authorizeEndpoint);\r\n }\r\n\r\n const endpointStr = (endpointType === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n\r\n const urlObj = new URL(mapLayerUrl);\r\n\r\n if (this.isArcGisHostValid(urlObj)) {\r\n // ArcGIS Online (fixed)\r\n // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/\r\n\r\n if (this.arcGisOnlineClientId === undefined) {\r\n return undefined;\r\n }\r\n\r\n const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;\r\n return new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, true), true);\r\n } else {\r\n\r\n // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'\r\n try {\r\n const restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n\r\n if (restUrlFromTokenService === undefined) {\r\n // We could not derive the token endpoint from 'tokenServicesUrl'.\r\n // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize\r\n const regExMatch = mapLayerUrl.match(new RegExp(/([^&\\/]+)\\/rest\\/services\\/.*/, \"i\"));\r\n if (regExMatch !== null && regExMatch.length >= 2) {\r\n const subdirectory = regExMatch[1];\r\n const port = (urlObj.port !== \"80\" && urlObj.port !== \"443\") ? `:${urlObj.port}` : \"\";\r\n const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);\r\n\r\n // Check again the URL we just composed\r\n const isValidUrl = await this.validateEndpointUrl(newUrlObj.toString());\r\n if (isValidUrl === undefined || isValidUrl ) {\r\n const endpoint = await this.createEndpoint(mapLayerUrl, newUrlObj.toString(), endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n }\r\n } else {\r\n const isValidUrl = await this.validateEndpointUrl(restUrlFromTokenService.toString());\r\n if (isValidUrl === undefined || isValidUrl ) {\r\n const endpoint = await this.createEndpoint(mapLayerUrl, `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n }\r\n } catch {\r\n }\r\n }\r\n\r\n // If we reach here, we were not successful creating an endpoint\r\n this._endPointsCache.set(mapLayerUrl, {}); // Cache an empty entry, and avoid making repeated failing requests.\r\n\r\n return undefined; // we could not find any valid oauth2 endpoint\r\n }\r\n\r\n /**\r\n * Construct the complete Authorize url to starts the Oauth process\r\n * @internal\r\n */\r\n private constructLoginUrl(url: string, isArcgisOnline: boolean) {\r\n const urlObj = new URL(url);\r\n\r\n // Set the client id\r\n if (isArcgisOnline) {\r\n const clientId = this.arcGisOnlineClientId;\r\n assert(clientId !== undefined);\r\n if (clientId !== undefined) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n\r\n } else {\r\n const clientId = this.getMatchingEnterpriseClientId(url);\r\n assert(clientId !== undefined);\r\n if (undefined !== clientId) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n }\r\n\r\n urlObj.searchParams.set(\"response_type\", \"token\");\r\n if (this.expiration !== undefined) {\r\n urlObj.searchParams.set(\"expiration\", `${this.expiration}`);\r\n }\r\n\r\n if (this.redirectUri)\r\n urlObj.searchParams.set(\"redirect_uri\", this.redirectUri);\r\n\r\n return urlObj.toString();\r\n }\r\n\r\n}\r\n"]}
|
|
@@ -35,6 +35,8 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
35
35
|
private initOauthCallbackFunction;
|
|
36
36
|
unInitialize(): void;
|
|
37
37
|
getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined>;
|
|
38
|
+
/** @internal */
|
|
39
|
+
static validateOAuth2Endpoint(endpointUrl: string): Promise<boolean>;
|
|
38
40
|
getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined>;
|
|
39
41
|
invalidateToken(token: MapLayerAccessToken): boolean;
|
|
40
42
|
get redirectUri(): string | undefined;
|
|
@@ -47,8 +49,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
47
49
|
removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId): void;
|
|
48
50
|
/** @internal */
|
|
49
51
|
private getOAuthTokenForMapLayerUrl;
|
|
50
|
-
private
|
|
51
|
-
private _oauthTokenEndPointsCache;
|
|
52
|
+
private _endPointsCache;
|
|
52
53
|
/**
|
|
53
54
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
54
55
|
* @internal
|
|
@@ -64,6 +65,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
|
|
|
64
65
|
* @internal
|
|
65
66
|
*/
|
|
66
67
|
private isArcGisHostValid;
|
|
68
|
+
private validateEndpointUrl;
|
|
67
69
|
/**
|
|
68
70
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
69
71
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArcGisAccessClient.d.ts","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMnI,YAAY;AACZ,MAAM,WAAW,wBAAwB;IAGvC,cAAc,EAAE,MAAM,CAAC;IAGvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,YAAY;AACZ,MAAM,WAAW,oBAAoB;IAEnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,mBAAmB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClD;AAED;;;;EAIE;AACF,MAAM,WAAW,iBAAiB;IAIhC,WAAW,EAAE,MAAM,CAAC;IAGpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,SAAS,EAAE,oBAAoB,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"ArcGisAccessClient.d.ts","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMnI,YAAY;AACZ,MAAM,WAAW,wBAAwB;IAGvC,cAAc,EAAE,MAAM,CAAC;IAGvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,YAAY;AACZ,MAAM,WAAW,oBAAoB;IAEnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,mBAAmB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClD;AAED;;;;EAIE;AACF,MAAM,WAAW,iBAAiB;IAIhC,WAAW,EAAE,MAAM,CAAC;IAGpB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,SAAS,EAAE,oBAAoB,CAAC;CACjC;AASD,YAAY;AACZ,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,SAAgB,iBAAiB,kDAAiB;IAClD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAAmC;IAGrD,OAAO,CAAC,iBAAiB,CAAS;;IAK3B,UAAU,CAAC,WAAW,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAW3D,OAAO,CAAC,yBAAyB;IAoC1B,YAAY;IAMN,cAAc,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAgBxG,gBAAgB;WACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpE,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAQ9F,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO;IAQ3D,IAAW,WAAW,uBAErB;IAEM,6BAA6B,CAAC,GAAG,EAAE,MAAM;IA0BhD,IAAW,UAAU,uBAEpB;IAED,IAAW,oBAAoB,IAIW,MAAM,GAAG,SAAS,CAF3D;IAED,IAAW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAK3D;IAED,IAAW,yBAAyB,2CAEnC;IAEM,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAiB9D,wBAAwB,CAAC,QAAQ,EAAE,wBAAwB;IASlE,gBAAgB;YACF,2BAA2B;IAezC,OAAO,CAAC,eAAe,CAA+C;IAEtE;;;KAGC;IACD,OAAO,CAAC,aAAa;IAKrB;;;KAGC;YACa,cAAc;IAO5B;;;MAGE;IACF,OAAO,CAAC,iBAAiB;YAQX,mBAAmB;IAYjC;;;KAGC;YACa,iBAAiB;IA8D/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
|
|
@@ -16,11 +16,10 @@ export class ArcGisAccessClient {
|
|
|
16
16
|
this.onOAuthProcessEnd = new BeEvent();
|
|
17
17
|
// Should be kept to 'false'. Debugging purposes only.
|
|
18
18
|
this._forceLegacyToken = false;
|
|
19
|
-
//
|
|
19
|
+
// Mapping between a map-layer URL and its corresponding Oauth endpoint
|
|
20
20
|
// i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
|
|
21
21
|
// => https://hostname/portal/sharing/oauth2/authorize
|
|
22
|
-
this.
|
|
23
|
-
this._oauthTokenEndPointsCache = new Map();
|
|
22
|
+
this._endPointsCache = new Map();
|
|
24
23
|
}
|
|
25
24
|
initialize(oAuthConfig) {
|
|
26
25
|
if (oAuthConfig) {
|
|
@@ -81,20 +80,16 @@ export class ArcGisAccessClient {
|
|
|
81
80
|
}
|
|
82
81
|
return undefined;
|
|
83
82
|
}
|
|
83
|
+
/** @internal */
|
|
84
|
+
static async validateOAuth2Endpoint(endpointUrl) {
|
|
85
|
+
const data = await fetch(endpointUrl, { method: "GET" });
|
|
86
|
+
return data.status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
|
|
87
|
+
}
|
|
84
88
|
async getTokenServiceEndPoint(mapLayerUrl) {
|
|
85
|
-
let tokenEndpoint;
|
|
86
89
|
if (!this._forceLegacyToken) {
|
|
87
|
-
|
|
88
|
-
// we could not make a reliable validation.
|
|
89
|
-
try {
|
|
90
|
-
tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);
|
|
91
|
-
if (tokenEndpoint) {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
}
|
|
90
|
+
return this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);
|
|
96
91
|
}
|
|
97
|
-
return
|
|
92
|
+
return undefined;
|
|
98
93
|
}
|
|
99
94
|
invalidateToken(token) {
|
|
100
95
|
let found = ArcGisTokenManager.invalidateToken(token);
|
|
@@ -184,22 +179,18 @@ export class ArcGisAccessClient {
|
|
|
184
179
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
185
180
|
* @internal
|
|
186
181
|
*/
|
|
187
|
-
cacheEndpoint(url,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
this._oauthTokenEndPointsCache.set(url, obj);
|
|
193
|
-
}
|
|
182
|
+
cacheEndpoint(url, endpointType, endPoint) {
|
|
183
|
+
const entry = endpointType === ArcGisOAuth2EndpointType.Authorize ? { authorizeEndpoint: endPoint } : { tokenEndpoint: endPoint };
|
|
184
|
+
this._endPointsCache.set(url, entry);
|
|
194
185
|
}
|
|
195
186
|
/**
|
|
196
187
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
197
188
|
* @internal
|
|
198
189
|
*/
|
|
199
|
-
async createEndpoint(
|
|
190
|
+
async createEndpoint(mapLayerUrl, oauthEndpointUrl, endpointType) {
|
|
200
191
|
// Validate the URL we just composed
|
|
201
|
-
const oauthEndpoint = new ArcGisOAuth2Endpoint(
|
|
202
|
-
this.cacheEndpoint(
|
|
192
|
+
const oauthEndpoint = new ArcGisOAuth2Endpoint(oauthEndpointUrl, this.constructLoginUrl(oauthEndpointUrl, false), false);
|
|
193
|
+
this.cacheEndpoint(mapLayerUrl, endpointType, oauthEndpoint);
|
|
203
194
|
return oauthEndpoint;
|
|
204
195
|
}
|
|
205
196
|
/**
|
|
@@ -212,18 +203,30 @@ export class ArcGisAccessClient {
|
|
|
212
203
|
];
|
|
213
204
|
return allowedHosts.some((host) => url.hostname.toLowerCase().endsWith(host));
|
|
214
205
|
}
|
|
206
|
+
async validateEndpointUrl(url) {
|
|
207
|
+
let valid;
|
|
208
|
+
try {
|
|
209
|
+
valid = await ArcGisAccessClient.validateOAuth2Endpoint(url.toString());
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// If we reach here, this means we could not validate properly the endpoint;
|
|
213
|
+
// we cannot conclude the endpoint is invalid though; it might happen endpoint doesn't support CORS requests,
|
|
214
|
+
// but still valid for Oauth process.
|
|
215
|
+
}
|
|
216
|
+
return valid;
|
|
217
|
+
}
|
|
215
218
|
/**
|
|
216
219
|
* Get OAuth2 endpoint that must be cause to get the Oauth2 token
|
|
217
220
|
* @internal
|
|
218
221
|
*/
|
|
219
|
-
async getOAuth2Endpoint(
|
|
222
|
+
async getOAuth2Endpoint(mapLayerUrl, endpointType) {
|
|
220
223
|
// Return from cache if available
|
|
221
|
-
const cachedEndpoint =
|
|
224
|
+
const cachedEndpoint = this._endPointsCache.get(mapLayerUrl);
|
|
222
225
|
if (cachedEndpoint !== undefined) {
|
|
223
|
-
return cachedEndpoint;
|
|
226
|
+
return (endpointType === ArcGisOAuth2EndpointType.Authorize ? cachedEndpoint.authorizeEndpoint : cachedEndpoint.authorizeEndpoint);
|
|
224
227
|
}
|
|
225
228
|
const endpointStr = (endpointType === ArcGisOAuth2EndpointType.Authorize ? "authorize" : "token");
|
|
226
|
-
const urlObj = new URL(
|
|
229
|
+
const urlObj = new URL(mapLayerUrl);
|
|
227
230
|
if (this.isArcGisHostValid(urlObj)) {
|
|
228
231
|
// ArcGIS Online (fixed)
|
|
229
232
|
// Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/
|
|
@@ -240,24 +243,34 @@ export class ArcGisAccessClient {
|
|
|
240
243
|
if (restUrlFromTokenService === undefined) {
|
|
241
244
|
// We could not derive the token endpoint from 'tokenServicesUrl'.
|
|
242
245
|
// ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
|
|
243
|
-
const regExMatch =
|
|
246
|
+
const regExMatch = mapLayerUrl.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
|
|
244
247
|
if (regExMatch !== null && regExMatch.length >= 2) {
|
|
245
248
|
const subdirectory = regExMatch[1];
|
|
246
249
|
const port = (urlObj.port !== "80" && urlObj.port !== "443") ? `:${urlObj.port}` : "";
|
|
247
250
|
const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);
|
|
248
251
|
// Check again the URL we just composed
|
|
249
|
-
|
|
252
|
+
const isValidUrl = await this.validateEndpointUrl(newUrlObj.toString());
|
|
253
|
+
if (isValidUrl === undefined || isValidUrl) {
|
|
254
|
+
const endpoint = await this.createEndpoint(mapLayerUrl, newUrlObj.toString(), endpointType);
|
|
255
|
+
if (endpoint)
|
|
256
|
+
return endpoint;
|
|
257
|
+
}
|
|
250
258
|
}
|
|
251
259
|
}
|
|
252
260
|
else {
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
255
|
-
|
|
261
|
+
const isValidUrl = await this.validateEndpointUrl(restUrlFromTokenService.toString());
|
|
262
|
+
if (isValidUrl === undefined || isValidUrl) {
|
|
263
|
+
const endpoint = await this.createEndpoint(mapLayerUrl, `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);
|
|
264
|
+
if (endpoint)
|
|
265
|
+
return endpoint;
|
|
266
|
+
}
|
|
256
267
|
}
|
|
257
268
|
}
|
|
258
269
|
catch {
|
|
259
270
|
}
|
|
260
271
|
}
|
|
272
|
+
// If we reach here, we were not successful creating an endpoint
|
|
273
|
+
this._endPointsCache.set(mapLayerUrl, {}); // Cache an empty entry, and avoid making repeated failing requests.
|
|
261
274
|
return undefined; // we could not find any valid oauth2 endpoint
|
|
262
275
|
}
|
|
263
276
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArcGisAccessClient.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, BeEvent } from \"@itwin/core-bentley\";\r\nimport { MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerTokenEndpoint } from \"@itwin/core-frontend\";\r\nimport { ArcGisOAuth2Token, ArcGisTokenClientType } from \"./ArcGisTokenGenerator\";\r\nimport { ArcGisOAuth2Endpoint, ArcGisOAuth2EndpointType } from \"./ArcGisOAuth2Endpoint\";\r\nimport { ArcGisTokenManager } from \"./ArcGisTokenManager\";\r\nimport { ArcGisUrl } from \"./ArcGisUrl\";\r\n\r\n/** @beta */\r\nexport interface ArcGisEnterpriseClientId {\r\n /* Oauth API endpoint base URL (i.e. https://hostname/portal/sharing/oauth2/authorize)\r\n used to identify uniquely each enterprise server. */\r\n serviceBaseUrl: string;\r\n\r\n /* Application's clientId for this enterprise server.*/\r\n clientId: string;\r\n}\r\n\r\n/** @beta */\r\nexport interface ArcGisOAuthClientIds {\r\n /* Application's OAuth clientId in ArcGIS online */\r\n arcgisOnlineClientId?: string;\r\n\r\n /* Application's OAuth clientId for each enterprise server used. */\r\n enterpriseClientIds?: ArcGisEnterpriseClientId[];\r\n}\r\n\r\n/** @beta\r\n * ArcGIS OAuth configurations parameters.\r\n * See https://developers.arcgis.com/documentation/mapping-apis-and-services/security/arcgis-identity/serverless-web-apps/\r\n * more details.\r\n*/\r\nexport interface ArcGisOAuthConfig {\r\n /* URL to which a user is sent once they complete sign in authorization.\r\n Must match a URI you define in the developer dashboard, otherwise, the authorization will be rejected.\r\n */\r\n redirectUri: string;\r\n\r\n /* Optional expiration after which the token will expire. Defined in minutes with a maximum of two weeks (20160 minutes)*/\r\n tokenExpiration?: number;\r\n\r\n /* Application client Ids */\r\n clientIds: ArcGisOAuthClientIds;\r\n}\r\n\r\n/** @beta */\r\nexport class ArcGisAccessClient implements MapLayerAccessClient {\r\n public readonly onOAuthProcessEnd = new BeEvent();\r\n private _redirectUri: string | undefined;\r\n private _expiration: number | undefined;\r\n private _clientIds: ArcGisOAuthClientIds | undefined;\r\n\r\n // Should be kept to 'false'. Debugging purposes only.\r\n private _forceLegacyToken = false;\r\n\r\n public constructor() {\r\n }\r\n\r\n public initialize(oAuthConfig?: ArcGisOAuthConfig): boolean {\r\n if (oAuthConfig) {\r\n this._redirectUri = oAuthConfig.redirectUri;\r\n this._expiration = oAuthConfig.tokenExpiration;\r\n this._clientIds = oAuthConfig.clientIds;\r\n\r\n this.initOauthCallbackFunction();\r\n }\r\n return true;\r\n }\r\n\r\n private initOauthCallbackFunction() {\r\n (window as any).arcGisOAuth2Callback = (redirectLocation?: Location) => {\r\n let eventSuccess = false;\r\n let stateData;\r\n\r\n if (redirectLocation && redirectLocation.hash.length > 0) {\r\n const locationHash = redirectLocation.hash;\r\n const hashParams = new URLSearchParams(locationHash.substring(1));\r\n const token = hashParams.get(\"access_token\") ?? undefined;\r\n const expiresInStr = hashParams.get(\"expires_in\") ?? undefined;\r\n const userName = hashParams.get(\"username\") ?? undefined;\r\n const ssl = hashParams.get(\"ssl\") === \"true\";\r\n const stateStr = hashParams.get(\"state\") ?? undefined;\r\n const persist = hashParams.get(\"persist\") === \"true\";\r\n if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {\r\n let endpointOrigin;\r\n try {\r\n const state = JSON.parse(stateStr);\r\n stateData = state?.customData;\r\n endpointOrigin = state?.endpointOrigin;\r\n\r\n } catch {\r\n }\r\n const expiresIn = Number(expiresInStr);\r\n const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)\r\n if (endpointOrigin !== undefined) {\r\n ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });\r\n eventSuccess = true;\r\n }\r\n\r\n }\r\n }\r\n this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);\r\n };\r\n }\r\n\r\n public unInitialize() {\r\n this._redirectUri = undefined;\r\n this._expiration = undefined;\r\n (window as any).arcGisOAuth2Callback = undefined;\r\n }\r\n\r\n public async getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined> {\r\n // First lookup Oauth2 tokens, otherwise check try \"legacy tokens\" if credentials were provided\r\n\r\n if (!this._forceLegacyToken) {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n }\r\n\r\n if (params.userName && params.password) {\r\n return ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public async getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined> {\r\n let tokenEndpoint: ArcGisOAuth2Endpoint | undefined;\r\n if (!this._forceLegacyToken) {\r\n // Note: we used to validate the endpoint by making a request, but because of CORS isssues with some servers\r\n // we could not make a reliable validation.\r\n try {\r\n tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (tokenEndpoint) {\r\n\r\n }\r\n } catch {\r\n\r\n }\r\n }\r\n\r\n return tokenEndpoint;\r\n }\r\n\r\n public invalidateToken(token: MapLayerAccessToken): boolean {\r\n let found = ArcGisTokenManager.invalidateToken(token);\r\n if (!found) {\r\n found = ArcGisTokenManager.invalidateOAuth2Token(token);\r\n }\r\n return found;\r\n }\r\n\r\n public get redirectUri() {\r\n return this._redirectUri;\r\n }\r\n\r\n public getMatchingEnterpriseClientId(url: string) {\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n\r\n let clientId: string | undefined;\r\n let defaultClientId: string | undefined;\r\n for (const entry of clientIds) {\r\n if (entry.serviceBaseUrl === \"\") {\r\n defaultClientId = entry.clientId;\r\n } else {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\r\n }\r\n }\r\n\r\n // If we could not find a match with serviceBaseUrl, and a default clientId\r\n // was specified (i.e empty url), then use default clientId\r\n if (clientId === undefined && defaultClientId !== undefined) {\r\n clientId = defaultClientId;\r\n }\r\n return clientId;\r\n }\r\n\r\n public get expiration() {\r\n return this._expiration;\r\n }\r\n\r\n public get arcGisOnlineClientId() {\r\n return this._clientIds?.arcgisOnlineClientId;\r\n }\r\n\r\n public set arcGisOnlineClientId(clientId: string | undefined) {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = { arcgisOnlineClientId: clientId };\r\n }\r\n this._clientIds.arcgisOnlineClientId = clientId;\r\n }\r\n\r\n public get arcGisEnterpriseClientIds() {\r\n return this._clientIds?.enterpriseClientIds;\r\n }\r\n\r\n public setEnterpriseClientId(serviceBaseUrl: string, clientId: string) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);\r\n if (foundIdx !== -1) {\r\n this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;\r\n } else {\r\n this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });\r\n }\r\n } else {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = {};\r\n }\r\n this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];\r\n }\r\n }\r\n\r\n public removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n this._clientIds.enterpriseClientIds = this._clientIds?.enterpriseClientIds?.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);\r\n }\r\n\r\n }\r\n\r\n /// //////////\r\n /** @internal */\r\n private async getOAuthTokenForMapLayerUrl(mapLayerUrl: string): Promise<ArcGisOAuth2Token | undefined> {\r\n try {\r\n const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (oauthEndpoint !== undefined) {\r\n const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());\r\n return ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);\r\n }\r\n } catch { }\r\n return undefined;\r\n }\r\n\r\n // Derive the Oauth URL from a typical MapLayerURL\r\n // i.e. \t https://hostname/server/rest/services/NewYork/NewYork3857/MapServer\r\n // => https://hostname/portal/sharing/oauth2/authorize\r\n private _oauthAuthorizeEndPointsCache = new Map<string, any>();\r\n private _oauthTokenEndPointsCache = new Map<string, any>();\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private cacheEndpoint(url: string, endpoint: ArcGisOAuth2EndpointType, obj: ArcGisOAuth2Endpoint) {\r\n if (endpoint === ArcGisOAuth2EndpointType.Authorize) {\r\n this._oauthAuthorizeEndPointsCache.set(url, obj);\r\n } else {\r\n this._oauthTokenEndPointsCache.set(url, obj);\r\n }\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async createEndpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Validate the URL we just composed\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(url, this.constructLoginUrl(url, false), false);\r\n this.cacheEndpoint(url, endpoint, oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n\r\n /**\r\n * Returns whether the ArcGis host is valid\r\n * @internal\r\n */\r\n private isArcGisHostValid(url: URL): boolean {\r\n const allowedHosts = [\r\n \"arcgis.com\",\r\n ];\r\n\r\n return allowedHosts.some((host: string) => url.hostname.toLowerCase().endsWith(host));\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async getOAuth2Endpoint(url: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Return from cache if available\r\n const cachedEndpoint = (endpointType === ArcGisOAuth2EndpointType.Authorize ? this._oauthAuthorizeEndPointsCache.get(url) : this._oauthTokenEndPointsCache.get(url));\r\n if (cachedEndpoint !== undefined) {\r\n return cachedEndpoint;\r\n }\r\n\r\n const endpointStr = (endpointType === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n\r\n const urlObj = new URL(url);\r\n\r\n if (this.isArcGisHostValid(urlObj)) {\r\n // ArcGIS Online (fixed)\r\n // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/\r\n\r\n if (this.arcGisOnlineClientId === undefined) {\r\n return undefined;\r\n }\r\n\r\n const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;\r\n return new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, true), true);\r\n } else {\r\n\r\n // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'\r\n try {\r\n const restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n if (restUrlFromTokenService === undefined) {\r\n // We could not derive the token endpoint from 'tokenServicesUrl'.\r\n // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize\r\n const regExMatch = url.match(new RegExp(/([^&\\/]+)\\/rest\\/services\\/.*/, \"i\"));\r\n if (regExMatch !== null && regExMatch.length >= 2) {\r\n const subdirectory = regExMatch[1];\r\n const port = (urlObj.port !== \"80\" && urlObj.port !== \"443\") ? `:${urlObj.port}` : \"\";\r\n const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);\r\n\r\n // Check again the URL we just composed\r\n return await this.createEndpoint(newUrlObj.toString(), endpointType);\r\n }\r\n } else {\r\n const endpoint = await this.createEndpoint(`${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n } catch {\r\n\r\n }\r\n\r\n }\r\n return undefined; // we could not find any valid oauth2 endpoint\r\n }\r\n\r\n /**\r\n * Construct the complete Authorize url to starts the Oauth process\r\n * @internal\r\n */\r\n private constructLoginUrl(url: string, isArcgisOnline: boolean) {\r\n const urlObj = new URL(url);\r\n\r\n // Set the client id\r\n if (isArcgisOnline) {\r\n const clientId = this.arcGisOnlineClientId;\r\n assert(clientId !== undefined);\r\n if (clientId !== undefined) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n\r\n } else {\r\n const clientId = this.getMatchingEnterpriseClientId(url);\r\n assert(clientId !== undefined);\r\n if (undefined !== clientId) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n }\r\n\r\n urlObj.searchParams.set(\"response_type\", \"token\");\r\n if (this.expiration !== undefined) {\r\n urlObj.searchParams.set(\"expiration\", `${this.expiration}`);\r\n }\r\n\r\n if (this.redirectUri)\r\n urlObj.searchParams.set(\"redirect_uri\", this.redirectUri);\r\n\r\n return urlObj.toString();\r\n }\r\n\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ArcGisAccessClient.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisAccessClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, BeEvent } from \"@itwin/core-bentley\";\r\nimport { MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerTokenEndpoint } from \"@itwin/core-frontend\";\r\nimport { ArcGisOAuth2Token, ArcGisTokenClientType } from \"./ArcGisTokenGenerator\";\r\nimport { ArcGisOAuth2Endpoint, ArcGisOAuth2EndpointType } from \"./ArcGisOAuth2Endpoint\";\r\nimport { ArcGisTokenManager } from \"./ArcGisTokenManager\";\r\nimport { ArcGisUrl } from \"./ArcGisUrl\";\r\n\r\n/** @beta */\r\nexport interface ArcGisEnterpriseClientId {\r\n /* Oauth API endpoint base URL (i.e. https://hostname/portal/sharing/oauth2/authorize)\r\n used to identify uniquely each enterprise server. */\r\n serviceBaseUrl: string;\r\n\r\n /* Application's clientId for this enterprise server.*/\r\n clientId: string;\r\n}\r\n\r\n/** @beta */\r\nexport interface ArcGisOAuthClientIds {\r\n /* Application's OAuth clientId in ArcGIS online */\r\n arcgisOnlineClientId?: string;\r\n\r\n /* Application's OAuth clientId for each enterprise server used. */\r\n enterpriseClientIds?: ArcGisEnterpriseClientId[];\r\n}\r\n\r\n/** @beta\r\n * ArcGIS OAuth configurations parameters.\r\n * See https://developers.arcgis.com/documentation/mapping-apis-and-services/security/arcgis-identity/serverless-web-apps/\r\n * more details.\r\n*/\r\nexport interface ArcGisOAuthConfig {\r\n /* URL to which a user is sent once they complete sign in authorization.\r\n Must match a URI you define in the developer dashboard, otherwise, the authorization will be rejected.\r\n */\r\n redirectUri: string;\r\n\r\n /* Optional expiration after which the token will expire. Defined in minutes with a maximum of two weeks (20160 minutes)*/\r\n tokenExpiration?: number;\r\n\r\n /* Application client Ids */\r\n clientIds: ArcGisOAuthClientIds;\r\n}\r\n\r\ninterface EndPointsCacheEntry {\r\n authorizeEndpoint?: ArcGisOAuth2Endpoint;\r\n tokenEndpoint?: ArcGisOAuth2Endpoint;\r\n}\r\n\r\ntype MapLayerUrl = string;\r\n\r\n/** @beta */\r\nexport class ArcGisAccessClient implements MapLayerAccessClient {\r\n public readonly onOAuthProcessEnd = new BeEvent();\r\n private _redirectUri: string | undefined;\r\n private _expiration: number | undefined;\r\n private _clientIds: ArcGisOAuthClientIds | undefined;\r\n\r\n // Should be kept to 'false'. Debugging purposes only.\r\n private _forceLegacyToken = false;\r\n\r\n public constructor() {\r\n }\r\n\r\n public initialize(oAuthConfig?: ArcGisOAuthConfig): boolean {\r\n if (oAuthConfig) {\r\n this._redirectUri = oAuthConfig.redirectUri;\r\n this._expiration = oAuthConfig.tokenExpiration;\r\n this._clientIds = oAuthConfig.clientIds;\r\n\r\n this.initOauthCallbackFunction();\r\n }\r\n return true;\r\n }\r\n\r\n private initOauthCallbackFunction() {\r\n (window as any).arcGisOAuth2Callback = (redirectLocation?: Location) => {\r\n let eventSuccess = false;\r\n let stateData;\r\n\r\n if (redirectLocation && redirectLocation.hash.length > 0) {\r\n const locationHash = redirectLocation.hash;\r\n const hashParams = new URLSearchParams(locationHash.substring(1));\r\n const token = hashParams.get(\"access_token\") ?? undefined;\r\n const expiresInStr = hashParams.get(\"expires_in\") ?? undefined;\r\n const userName = hashParams.get(\"username\") ?? undefined;\r\n const ssl = hashParams.get(\"ssl\") === \"true\";\r\n const stateStr = hashParams.get(\"state\") ?? undefined;\r\n const persist = hashParams.get(\"persist\") === \"true\";\r\n if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {\r\n let endpointOrigin;\r\n try {\r\n const state = JSON.parse(stateStr);\r\n stateData = state?.customData;\r\n endpointOrigin = state?.endpointOrigin;\r\n\r\n } catch {\r\n }\r\n const expiresIn = Number(expiresInStr);\r\n const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)\r\n if (endpointOrigin !== undefined) {\r\n ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });\r\n eventSuccess = true;\r\n }\r\n\r\n }\r\n }\r\n this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);\r\n };\r\n }\r\n\r\n public unInitialize() {\r\n this._redirectUri = undefined;\r\n this._expiration = undefined;\r\n (window as any).arcGisOAuth2Callback = undefined;\r\n }\r\n\r\n public async getAccessToken(params: MapLayerAccessTokenParams): Promise<MapLayerAccessToken | undefined> {\r\n // First lookup Oauth2 tokens, otherwise check try \"legacy tokens\" if credentials were provided\r\n\r\n if (!this._forceLegacyToken) {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n }\r\n\r\n if (params.userName && params.password) {\r\n return ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /** @internal */\r\n public static async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean> {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n return data.status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\r\n }\r\n\r\n public async getTokenServiceEndPoint(mapLayerUrl: string): Promise<MapLayerTokenEndpoint | undefined> {\r\n if (!this._forceLegacyToken) {\r\n return this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public invalidateToken(token: MapLayerAccessToken): boolean {\r\n let found = ArcGisTokenManager.invalidateToken(token);\r\n if (!found) {\r\n found = ArcGisTokenManager.invalidateOAuth2Token(token);\r\n }\r\n return found;\r\n }\r\n\r\n public get redirectUri() {\r\n return this._redirectUri;\r\n }\r\n\r\n public getMatchingEnterpriseClientId(url: string) {\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n\r\n let clientId: string | undefined;\r\n let defaultClientId: string | undefined;\r\n for (const entry of clientIds) {\r\n if (entry.serviceBaseUrl === \"\") {\r\n defaultClientId = entry.clientId;\r\n } else {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\r\n }\r\n }\r\n\r\n // If we could not find a match with serviceBaseUrl, and a default clientId\r\n // was specified (i.e empty url), then use default clientId\r\n if (clientId === undefined && defaultClientId !== undefined) {\r\n clientId = defaultClientId;\r\n }\r\n return clientId;\r\n }\r\n\r\n public get expiration() {\r\n return this._expiration;\r\n }\r\n\r\n public get arcGisOnlineClientId() {\r\n return this._clientIds?.arcgisOnlineClientId;\r\n }\r\n\r\n public set arcGisOnlineClientId(clientId: string | undefined) {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = { arcgisOnlineClientId: clientId };\r\n }\r\n this._clientIds.arcgisOnlineClientId = clientId;\r\n }\r\n\r\n public get arcGisEnterpriseClientIds() {\r\n return this._clientIds?.enterpriseClientIds;\r\n }\r\n\r\n public setEnterpriseClientId(serviceBaseUrl: string, clientId: string) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);\r\n if (foundIdx !== -1) {\r\n this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;\r\n } else {\r\n this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });\r\n }\r\n } else {\r\n if (this._clientIds === undefined) {\r\n this._clientIds = {};\r\n }\r\n this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];\r\n }\r\n }\r\n\r\n public removeEnterpriseClientId(clientId: ArcGisEnterpriseClientId) {\r\n\r\n if (this._clientIds?.enterpriseClientIds) {\r\n this._clientIds.enterpriseClientIds = this._clientIds?.enterpriseClientIds?.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);\r\n }\r\n\r\n }\r\n\r\n /// //////////\r\n /** @internal */\r\n private async getOAuthTokenForMapLayerUrl(mapLayerUrl: string): Promise<ArcGisOAuth2Token | undefined> {\r\n try {\r\n const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);\r\n if (oauthEndpoint !== undefined) {\r\n const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());\r\n return ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);\r\n }\r\n } catch { }\r\n return undefined;\r\n }\r\n\r\n // Mapping between a map-layer URL and its corresponding Oauth endpoint\r\n // i.e. \t https://hostname/server/rest/services/NewYork/NewYork3857/MapServer\r\n // => https://hostname/portal/sharing/oauth2/authorize\r\n\r\n private _endPointsCache = new Map<MapLayerUrl, EndPointsCacheEntry>();\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private cacheEndpoint(url: MapLayerUrl, endpointType: ArcGisOAuth2EndpointType, endPoint: ArcGisOAuth2Endpoint) {\r\n const entry = endpointType === ArcGisOAuth2EndpointType.Authorize ? {authorizeEndpoint: endPoint} : {tokenEndpoint: endPoint};\r\n this._endPointsCache.set(url, entry);\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async createEndpoint(mapLayerUrl: MapLayerUrl, oauthEndpointUrl: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Validate the URL we just composed\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauthEndpointUrl, this.constructLoginUrl(oauthEndpointUrl, false), false);\r\n this.cacheEndpoint(mapLayerUrl, endpointType, oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n\r\n /**\r\n * Returns whether the ArcGis host is valid\r\n * @internal\r\n */\r\n private isArcGisHostValid(url: URL): boolean {\r\n const allowedHosts = [\r\n \"arcgis.com\",\r\n ];\r\n\r\n return allowedHosts.some((host: string) => url.hostname.toLowerCase().endsWith(host));\r\n }\r\n\r\n private async validateEndpointUrl(url: string) {\r\n let valid: boolean|undefined;\r\n try {\r\n valid = await ArcGisAccessClient.validateOAuth2Endpoint(url.toString());\r\n } catch {\r\n // If we reach here, this means we could not validate properly the endpoint;\r\n // we cannot conclude the endpoint is invalid though; it might happen endpoint doesn't support CORS requests,\r\n // but still valid for Oauth process.\r\n }\r\n return valid;\r\n }\r\n\r\n /**\r\n * Get OAuth2 endpoint that must be cause to get the Oauth2 token\r\n * @internal\r\n */\r\n private async getOAuth2Endpoint(mapLayerUrl: string, endpointType: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n // Return from cache if available\r\n const cachedEndpoint = this._endPointsCache.get(mapLayerUrl);\r\n if (cachedEndpoint !== undefined) {\r\n return (endpointType === ArcGisOAuth2EndpointType.Authorize ? cachedEndpoint.authorizeEndpoint : cachedEndpoint.authorizeEndpoint);\r\n }\r\n\r\n const endpointStr = (endpointType === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n\r\n const urlObj = new URL(mapLayerUrl);\r\n\r\n if (this.isArcGisHostValid(urlObj)) {\r\n // ArcGIS Online (fixed)\r\n // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/\r\n\r\n if (this.arcGisOnlineClientId === undefined) {\r\n return undefined;\r\n }\r\n\r\n const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;\r\n return new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, true), true);\r\n } else {\r\n\r\n // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'\r\n try {\r\n const restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n\r\n if (restUrlFromTokenService === undefined) {\r\n // We could not derive the token endpoint from 'tokenServicesUrl'.\r\n // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize\r\n const regExMatch = mapLayerUrl.match(new RegExp(/([^&\\/]+)\\/rest\\/services\\/.*/, \"i\"));\r\n if (regExMatch !== null && regExMatch.length >= 2) {\r\n const subdirectory = regExMatch[1];\r\n const port = (urlObj.port !== \"80\" && urlObj.port !== \"443\") ? `:${urlObj.port}` : \"\";\r\n const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);\r\n\r\n // Check again the URL we just composed\r\n const isValidUrl = await this.validateEndpointUrl(newUrlObj.toString());\r\n if (isValidUrl === undefined || isValidUrl ) {\r\n const endpoint = await this.createEndpoint(mapLayerUrl, newUrlObj.toString(), endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n }\r\n } else {\r\n const isValidUrl = await this.validateEndpointUrl(restUrlFromTokenService.toString());\r\n if (isValidUrl === undefined || isValidUrl ) {\r\n const endpoint = await this.createEndpoint(mapLayerUrl, `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`, endpointType);\r\n if (endpoint)\r\n return endpoint;\r\n }\r\n }\r\n } catch {\r\n }\r\n }\r\n\r\n // If we reach here, we were not successful creating an endpoint\r\n this._endPointsCache.set(mapLayerUrl, {}); // Cache an empty entry, and avoid making repeated failing requests.\r\n\r\n return undefined; // we could not find any valid oauth2 endpoint\r\n }\r\n\r\n /**\r\n * Construct the complete Authorize url to starts the Oauth process\r\n * @internal\r\n */\r\n private constructLoginUrl(url: string, isArcgisOnline: boolean) {\r\n const urlObj = new URL(url);\r\n\r\n // Set the client id\r\n if (isArcgisOnline) {\r\n const clientId = this.arcGisOnlineClientId;\r\n assert(clientId !== undefined);\r\n if (clientId !== undefined) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n\r\n } else {\r\n const clientId = this.getMatchingEnterpriseClientId(url);\r\n assert(clientId !== undefined);\r\n if (undefined !== clientId) {\r\n urlObj.searchParams.set(\"client_id\", clientId);\r\n }\r\n }\r\n\r\n urlObj.searchParams.set(\"response_type\", \"token\");\r\n if (this.expiration !== undefined) {\r\n urlObj.searchParams.set(\"expiration\", `${this.expiration}`);\r\n }\r\n\r\n if (this.redirectUri)\r\n urlObj.searchParams.set(\"redirect_uri\", this.redirectUri);\r\n\r\n return urlObj.toString();\r\n }\r\n\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/map-layers-auth",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0-dev.1",
|
|
4
4
|
"description": "Extension that adds a Map Layers Widget",
|
|
5
5
|
"main": "lib/cjs/map-layers-auth.js",
|
|
6
6
|
"module": "lib/esm/map-layers-auth.js",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"sinon-chai": "^3.2.0",
|
|
40
40
|
"source-map-support": "^0.5.6",
|
|
41
41
|
"typescript": "~5.0.2",
|
|
42
|
-
"@itwin/
|
|
43
|
-
"@itwin/
|
|
44
|
-
"@itwin/core-
|
|
45
|
-
"@itwin/core-
|
|
42
|
+
"@itwin/core-frontend": "4.4.0-dev.1",
|
|
43
|
+
"@itwin/build-tools": "4.4.0-dev.1",
|
|
44
|
+
"@itwin/core-bentley": "4.4.0-dev.1",
|
|
45
|
+
"@itwin/core-common": "4.4.0-dev.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@itwin/core-bentley": "4.
|
|
48
|
+
"@itwin/core-bentley": "4.4.0-dev.1"
|
|
49
49
|
},
|
|
50
50
|
"nyc": {
|
|
51
51
|
"extends": "./node_modules/@itwin/build-tools/.nycrc",
|