@itwin/map-layers-auth 3.5.0-dev.8 → 3.6.0-dev.3

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 CHANGED
@@ -1,6 +1,63 @@
1
1
  # Change Log - @itwin/map-layers-auth
2
2
 
3
- This log was last generated on Thu, 01 Sep 2022 14:37:22 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 30 Nov 2022 14:28:19 GMT and should not be manually modified.
4
+
5
+ ## 3.4.7
6
+ Wed, 30 Nov 2022 14:28:19 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 3.4.6
11
+ Tue, 22 Nov 2022 14:24:19 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 3.4.5
16
+ Thu, 17 Nov 2022 21:32:50 GMT
17
+
18
+ _Version update only_
19
+
20
+ ## 3.4.4
21
+ Thu, 10 Nov 2022 19:32:17 GMT
22
+
23
+ _Version update only_
24
+
25
+ ## 3.4.3
26
+ Fri, 28 Oct 2022 13:34:58 GMT
27
+
28
+ ### Updates
29
+
30
+ - ArcGIS access client now allow default client id. Also, oauth2 endpoint validation will be ignored if a CORS error occurs. Also fixed 'tilemap' requests not including oauth2 token.
31
+
32
+ ## 3.4.2
33
+ Mon, 24 Oct 2022 13:23:45 GMT
34
+
35
+ _Version update only_
36
+
37
+ ## 3.4.1
38
+ Mon, 17 Oct 2022 20:06:51 GMT
39
+
40
+ _Version update only_
41
+
42
+ ## 3.4.0
43
+ Thu, 13 Oct 2022 20:24:47 GMT
44
+
45
+ _Version update only_
46
+
47
+ ## 3.3.5
48
+ Tue, 27 Sep 2022 11:50:59 GMT
49
+
50
+ _Version update only_
51
+
52
+ ## 3.3.4
53
+ Thu, 08 Sep 2022 19:00:05 GMT
54
+
55
+ _Version update only_
56
+
57
+ ## 3.3.3
58
+ Tue, 06 Sep 2022 20:54:19 GMT
59
+
60
+ _Version update only_
4
61
 
5
62
  ## 3.3.2
6
63
  Thu, 01 Sep 2022 14:37:22 GMT
@@ -29,6 +29,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
29
29
  private _redirectUri;
30
30
  private _expiration;
31
31
  private _clientIds;
32
+ private _forceLegacyToken;
32
33
  constructor();
33
34
  initialize(oAuthConfig?: ArcGisOAuthConfig): boolean;
34
35
  private initOauthCallbackFunction;
@@ -48,6 +49,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
48
49
  private getOAuthTokenForMapLayerUrl;
49
50
  /**
50
51
  * Test if Oauth2 endpoint is accessible and has an associated appId
52
+ * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)
51
53
  * @internal
52
54
  */
53
55
  private validateOAuth2Endpoint;
@@ -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;AAED,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;;IAK9C,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;IAgB3F,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAa9F,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO;IAQ3D,IAAW,WAAW,uBAErB;IAEM,6BAA6B,CAAC,GAAG,EAAE,MAAM;IAchD,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;IAWzC;;;MAGE;YACY,sBAAsB;IAoBpC,OAAO,CAAC,6BAA6B,CAA0B;IAC/D,OAAO,CAAC,yBAAyB,CAA0B;IAE3D;;;KAGC;YACa,iBAAiB;IAwE/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
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;AAED,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;IAmB3F,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAc9F,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;IAWzC;;;;MAIE;YACY,sBAAsB;IAsBpC,OAAO,CAAC,6BAA6B,CAA0B;IAC/D,OAAO,CAAC,yBAAyB,CAA0B;IAE3D;;;KAGC;YACa,iBAAiB;IAyE/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
@@ -17,6 +17,8 @@ const ArcGisUrl_1 = require("./ArcGisUrl");
17
17
  class ArcGisAccessClient {
18
18
  constructor() {
19
19
  this.onOAuthProcessEnd = new core_bentley_1.BeEvent();
20
+ // Should be kept to 'false'. Debugging purposes only.
21
+ this._forceLegacyToken = false;
20
22
  // Derive the Oauth URL from a typical MapLayerURL
21
23
  // i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
22
24
  // => https://hostname/portal/sharing/oauth2/authorize
@@ -74,9 +76,11 @@ class ArcGisAccessClient {
74
76
  async getAccessToken(params) {
75
77
  // First lookup Oauth2 tokens, otherwise check try "legacy tokens" if credentials were provided
76
78
  try {
77
- const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
78
- if (oauth2Token)
79
- return oauth2Token;
79
+ if (!this._forceLegacyToken) {
80
+ const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
81
+ if (oauth2Token)
82
+ return oauth2Token;
83
+ }
80
84
  if (params.userName && params.password) {
81
85
  return await ArcGisTokenManager_1.ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenGenerator_1.ArcGisTokenClientType.referer });
82
86
  }
@@ -87,12 +91,14 @@ class ArcGisAccessClient {
87
91
  }
88
92
  async getTokenServiceEndPoint(mapLayerUrl) {
89
93
  let tokenEndpoint;
90
- try {
91
- tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
92
- if (tokenEndpoint) {
94
+ if (!this._forceLegacyToken) {
95
+ try {
96
+ tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
97
+ if (tokenEndpoint) {
98
+ }
93
99
  }
100
+ catch { }
94
101
  }
95
- catch { }
96
102
  return tokenEndpoint;
97
103
  }
98
104
  invalidateToken(token) {
@@ -106,16 +112,27 @@ class ArcGisAccessClient {
106
112
  return this._redirectUri;
107
113
  }
108
114
  getMatchingEnterpriseClientId(url) {
109
- let clientId;
110
115
  const clientIds = this.arcGisEnterpriseClientIds;
111
116
  if (!clientIds) {
112
117
  return undefined;
113
118
  }
119
+ let clientId;
120
+ let defaultClientId;
114
121
  for (const entry of clientIds) {
115
- if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
116
- clientId = entry.clientId;
122
+ if (entry.serviceBaseUrl === "") {
123
+ defaultClientId = entry.clientId;
124
+ }
125
+ else {
126
+ if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
127
+ clientId = entry.clientId;
128
+ }
117
129
  }
118
130
  }
131
+ // If we could not find a match with serviceBaseUrl, and a default clientId
132
+ // was specified (i.e empty url), then use default clientId
133
+ if (clientId === undefined && defaultClientId !== undefined) {
134
+ clientId = defaultClientId;
135
+ }
119
136
  return clientId;
120
137
  }
121
138
  get expiration() {
@@ -174,6 +191,7 @@ class ArcGisAccessClient {
174
191
  }
175
192
  /**
176
193
  * Test if Oauth2 endpoint is accessible and has an associated appId
194
+ * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)
177
195
  * @internal
178
196
  */
179
197
  async validateOAuth2Endpoint(endpointUrl) {
@@ -187,7 +205,9 @@ class ArcGisAccessClient {
187
205
  status = data.status;
188
206
  }
189
207
  catch (error) {
190
- status = error.status;
208
+ // fetch() throws when there is a CORS error, so in that case
209
+ // we cannot confirm if the oauth2 endpoint is valid or not, we return undefined
210
+ return undefined;
191
211
  }
192
212
  return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
193
213
  }
@@ -231,7 +251,9 @@ class ArcGisAccessClient {
231
251
  // Validate the URL we just composed
232
252
  try {
233
253
  const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;
234
- if (await this.validateOAuth2Endpoint(oauth2Url)) {
254
+ const valid = await this.validateOAuth2Endpoint(oauth2Url);
255
+ // We assume undefined means CORS error, that shouldn't prevent popup from displaying the login page.
256
+ if (valid === undefined || valid) {
235
257
  const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);
236
258
  cacheResult(oauthEndpoint);
237
259
  return oauthEndpoint;
@@ -239,8 +261,7 @@ class ArcGisAccessClient {
239
261
  }
240
262
  catch { }
241
263
  }
242
- // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'
243
- // lets use another approach.
264
+ // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl', lets try something else.
244
265
  // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
245
266
  const regExMatch = url.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
246
267
  if (regExMatch !== null && regExMatch.length >= 2) {
@@ -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 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 try {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n\r\n if (params.userName && params.password) {\r\n return await ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n } catch {\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\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 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 let clientId: string | undefined;\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n for (const entry of clientIds) {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\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 /**\r\n * Test if Oauth2 endpoint is accessible and has an associated appId\r\n * @internal\r\n */\r\n private async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean> {\r\n\r\n // Check if we got a matching appId for that endpoint, otherwise its not worth going further\r\n if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {\r\n return false;\r\n }\r\n\r\n let status: number | undefined;\r\n try {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n status = data.status;\r\n } catch (error: any) {\r\n status = error.status;\r\n }\r\n return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\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 async getOAuth2Endpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n\r\n // Return from cache if available\r\n const cachedEndpoint = (endpoint === 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 cacheResult = (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 const endpointStr = (endpoint === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n const urlObj = new URL(url);\r\n if (urlObj.hostname.toLowerCase().endsWith(\"arcgis.com\")) {\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(url, 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 let restUrlFromTokenService: URL | undefined;\r\n try {\r\n restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n } catch { }\r\n\r\n if (restUrlFromTokenService !== undefined) {\r\n // Validate the URL we just composed\r\n try {\r\n const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;\r\n if (await this.validateOAuth2Endpoint(oauth2Url)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\r\n }\r\n\r\n // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'\r\n // lets use another approach.\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 try {\r\n const newUrl = newUrlObj.toString();\r\n if (await this.validateOAuth2Endpoint(newUrl)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\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\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 try {\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 await ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n } catch {\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 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 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 /**\r\n * Test if Oauth2 endpoint is accessible and has an associated appId\r\n * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)\r\n * @internal\r\n */\r\n private async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean | undefined> {\r\n\r\n // Check if we got a matching appId for that endpoint, otherwise its not worth going further\r\n if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {\r\n return false;\r\n }\r\n\r\n let status: number | undefined;\r\n try {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n status = data.status;\r\n } catch (error: any) {\r\n // fetch() throws when there is a CORS error, so in that case\r\n // we cannot confirm if the oauth2 endpoint is valid or not, we return undefined\r\n return undefined;\r\n }\r\n return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\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 async getOAuth2Endpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n\r\n // Return from cache if available\r\n const cachedEndpoint = (endpoint === 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 cacheResult = (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 const endpointStr = (endpoint === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n const urlObj = new URL(url);\r\n if (urlObj.hostname.toLowerCase().endsWith(\"arcgis.com\")) {\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(url, 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 let restUrlFromTokenService: URL | undefined;\r\n try {\r\n restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n } catch { }\r\n\r\n if (restUrlFromTokenService !== undefined) {\r\n // Validate the URL we just composed\r\n try {\r\n const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;\r\n const valid = await this.validateOAuth2Endpoint(oauth2Url);\r\n // We assume undefined means CORS error, that shouldn't prevent popup from displaying the login page.\r\n if (valid === undefined || valid) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\r\n }\r\n\r\n // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl', lets try something else.\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 try {\r\n const newUrl = newUrlObj.toString();\r\n if (await this.validateOAuth2Endpoint(newUrl)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\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"]}
@@ -16,7 +16,7 @@ class ArcGisTokenGenerator {
16
16
  const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);
17
17
  if (restApiIdx === -1)
18
18
  return undefined;
19
- const infoUrl = lowerUrl.substr(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;
19
+ const infoUrl = arcGisRestServiceUrl.substring(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;
20
20
  let tokenServicesUrl;
21
21
  try {
22
22
  const response = await fetch(infoUrl, { method: "GET" });
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGisTokenGenerator.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisTokenGenerator.ts"],"names":[],"mappings":";;;AAmCA,4GAA4G;AAC5G,gBAAgB;AAChB,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,6DAAE,CAAA;IACF,uEAAO,CAAA;IACP,2EAAS,CAAA;AACX,CAAC,EAJW,qBAAqB,GAArB,6BAAqB,KAArB,6BAAqB,QAIhC;AA8BD,gBAAgB;AAChB,MAAa,oBAAoB;IAOxB,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,oBAA4B;QACnE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,UAAU,KAAK,CAAC,CAAC;YACnB,OAAO,SAAS,CAAC;QACnB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,GAAG,oBAAoB,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,oBAAoB,CAAC,eAAe,CAAC;QAEhI,IAAI,gBAAoC,CAAC;QACzC,IAAI;YACF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,gBAAgB,GAAG,oBAAoB,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;SAC3E;QAAC,OAAO,MAAM,EAAE;SAChB;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAEM,MAAM,CAAC,2BAA2B,CAAC,IAAS;;QACjD,OAAO,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,oBAAoB,EAAC,CAAC,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,OAAe;QAC7C,MAAM,MAAM,GAAG,oBAAoB,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,MAAM,KAAK,SAAS;YACtB,OAAO,MAAM,CAAC;QAEhB,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjF,IAAI,eAAe,KAAK,SAAS;YAC/B,oBAAoB,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAE3E,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,6FAA6F;IACtF,KAAK,CAAC,QAAQ,CAAC,oBAA4B,EAAE,QAAgB,EAAE,QAAgB,EAAE,OAAmC;QACzH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;QAC5E,IAAI,CAAC,eAAe;YAClB,OAAO,SAAS,CAAC;QAEnB,IAAI,KAAgB,CAAC;QACrB,IAAI;YACF,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACrD,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAErD,+BAA+B;YAC/B,IAAI,aAAa,GAAG,EAAE,CAAC;YACvB,IAAI,OAAO,CAAC,UAAU,EAAE;gBACtB,aAAa,GAAG,eAAe,OAAO,CAAC,UAAU,EAAE,CAAC;aACrD;YAED,2BAA2B;YAC3B,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI,OAAO,CAAC,MAAM,KAAK,qBAAqB,CAAC,OAAO,EAAE;gBACpD,IAAI,UAAU,GAAG,EAAE,CAAC;gBACpB,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;oBACjC,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAK,gCAAgC;iBACvF;qBAAM;oBACL,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;iBAClD;gBAED,SAAS,GAAG,2BAA2B,UAAU,EAAE,CAAC;aACrD;iBAAM,IAAI,OAAO,CAAC,MAAM,KAAK,qBAAqB,CAAC,EAAE,EAAE;gBACtD,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS;oBAC1B,OAAO,KAAK,CAAC;gBACf,SAAS,GAAG,iBAAiB,OAAO,CAAC,EAAE,EAAE,CAAC;aAC3C;iBAAM,IAAI,OAAO,CAAC,MAAM,KAAK,qBAAqB,CAAC,SAAS,EAAE;gBAC7D,SAAS,GAAG,uBAAuB,CAAC;aACrC;YAED,MAAM,kBAAkB,GAAgB;gBACtC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,YAAY,eAAe,aAAa,eAAe,GAAG,SAAS,GAAG,aAAa,UAAU;gBACnG,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;aACjE,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;YAElE,0EAA0E;YAC1E,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;SAE/B;QAAC,OAAO,MAAM,EAAE;SAChB;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gIAAgI;IAChI,2HAA2H;IACpH,MAAM,CAAC,UAAU,CAAC,GAAW;QAClC,OAAO,oBAAoB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtE,CAAC;IAED,2EAA2E;IAC3E,qDAAqD;IAC9C,MAAM,CAAC,aAAa,CAAC,GAAW;QACrC,OAAO,kBAAkB,CAAC,GAAG,CAAC;aAC3B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;;AA3GH,oDA4GC;AA3GyB,gCAAW,GAAG,QAAQ,CAAC;AACvB,oCAAe,GAAG,cAAc,CAAC;AAEzD,wEAAwE;AACzD,0CAAqB,GAAG,IAAI,GAAG,EAAkB,CAAC","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\nimport { MapLayerAccessToken } from \"@itwin/core-frontend\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/** @internal */\r\nexport interface ArcGisOAuth2Token extends MapLayerAccessToken {\r\n\r\n // The expiration time of the token in milliseconds (UNIX time)\r\n expiresAt: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n\r\n // Username associated with this token\r\n userName: string;\r\n\r\n // A Binary value that, if true, implies that the user had checked \"Keep me signed in\"\r\n persist?: boolean;\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisToken extends MapLayerAccessToken {\r\n // The expiration time of the token in milliseconds since January 1, 1970 (UTC).\r\n expires: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n}\r\n\r\n// client application's base URL, a user-specified IP address, or the IP address that is making the request.\r\n/** @internal */\r\nexport enum ArcGisTokenClientType {\r\n ip,\r\n referer,\r\n requestIp,\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisGenerateTokenOptions {\r\n\r\n // The client type that will be granted access to the token.\r\n // Users will be able to specify whether the token will be generated for a client application's base URL,\r\n // a user-specified IP address, or the IP address that is making the request.\r\n client: ArcGisTokenClientType;\r\n\r\n // The IP address that will be using the created token for access.\r\n // On the Generate Token page, the IP address is specified in the IP Address field. This is required when client has been set as ip.\r\n // Example ip=11.11.111.111\r\n ip?: string;\r\n\r\n // The base URL of the client application that will use the token.\r\n // On the Generate Token page, the referrer URL is specified in the Webapp URL field.\r\n // Defaults to location.origin if undefined and client = referer.\r\n // This is required when client has been set as referer.\r\n // Example : referer=https://myserver/mywebapp\r\n referer?: string;\r\n\r\n // The token expiration time in minutes. The default is 60 minutes (one hour).\r\n // The maximum expiration period is 15 days. The maximum value of the expiration time is controlled by the server.\r\n // Requests for tokens larger than this time will be rejected.\r\n // Applications are responsible for renewing expired tokens;\r\n // expired tokens will be rejected by the server on subsequent requests that use the token.\r\n expiration?: number; // in minutes, defaults to 60 minutes\r\n}\r\n\r\n/** @internal */\r\nexport class ArcGisTokenGenerator {\r\n private static readonly restApiPath = \"/rest/\";\r\n private static readonly restApiInfoPath = \"info?f=pjson\";\r\n\r\n // Cache info url to avoid fetching/parsing twice for the same base url.\r\n private static _tokenServiceUrlCache = new Map<string, string>();\r\n\r\n public static async fetchTokenServiceUrl(arcGisRestServiceUrl: string): Promise<string | undefined> {\r\n const lowerUrl = arcGisRestServiceUrl.toLowerCase();\r\n const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);\r\n if (restApiIdx === -1)\r\n return undefined;\r\n const infoUrl = lowerUrl.substr(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;\r\n\r\n let tokenServicesUrl: string | undefined;\r\n try {\r\n const response = await fetch(infoUrl, { method: \"GET\" });\r\n const json = await response.json();\r\n tokenServicesUrl = ArcGisTokenGenerator.getTokenServiceFromInfoJson(json);\r\n } catch (_error) {\r\n }\r\n return tokenServicesUrl;\r\n }\r\n\r\n public static getTokenServiceFromInfoJson(json: any): string | undefined {\r\n return json.authInfo?.isTokenBasedSecurity ? json?.authInfo?.tokenServicesUrl : undefined;\r\n }\r\n\r\n public async getTokenServiceUrl(baseUrl: string): Promise<string | undefined> {\r\n const cached = ArcGisTokenGenerator._tokenServiceUrlCache.get(baseUrl);\r\n if (cached !== undefined)\r\n return cached;\r\n\r\n const tokenServiceUrl = await ArcGisTokenGenerator.fetchTokenServiceUrl(baseUrl);\r\n if (tokenServiceUrl !== undefined)\r\n ArcGisTokenGenerator._tokenServiceUrlCache.set(baseUrl, tokenServiceUrl);\r\n\r\n return tokenServiceUrl;\r\n }\r\n\r\n // base url: ArcGis REST service base URL (format must be \"https://<host>/<instance>/rest/\")\r\n public async generate(arcGisRestServiceUrl: string, userName: string, password: string, options: ArcGisGenerateTokenOptions): Promise<any> {\r\n const tokenServiceUrl = await this.getTokenServiceUrl(arcGisRestServiceUrl);\r\n if (!tokenServiceUrl)\r\n return undefined;\r\n\r\n let token: undefined;\r\n try {\r\n const encodedUsername = encodeURIComponent(userName);\r\n const encodedPassword = encodeURIComponent(password);\r\n\r\n // Compose the expiration param\r\n let expirationStr = \"\";\r\n if (options.expiration) {\r\n expirationStr = `&expiration=${options.expiration}`;\r\n }\r\n\r\n // Compose the client param\r\n let clientStr = \"\";\r\n if (options.client === ArcGisTokenClientType.referer) {\r\n let refererStr = \"\";\r\n if (options.referer === undefined) {\r\n refererStr = encodeURIComponent(location.origin); // default to application origin\r\n } else {\r\n refererStr = encodeURIComponent(options.referer);\r\n }\r\n\r\n clientStr = `&client=referer&referer=${refererStr}`;\r\n } else if (options.client === ArcGisTokenClientType.ip) {\r\n if (options.ip === undefined)\r\n return token;\r\n clientStr = `&client=ip&ip=${options.ip}`;\r\n } else if (options.client === ArcGisTokenClientType.requestIp) {\r\n clientStr = `&client=requestip&ip=`;\r\n }\r\n\r\n const httpRequestOptions: RequestInit = {\r\n method: \"POST\",\r\n body: `username=${encodedUsername}&password=${encodedPassword}${clientStr}${expirationStr}&f=pjson`,\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\r\n };\r\n\r\n const response = await fetch(tokenServiceUrl, httpRequestOptions);\r\n\r\n // Check a token was really generated (an error could be part of the body)\r\n token = await response.json();\r\n\r\n } catch (_error) {\r\n }\r\n return token;\r\n }\r\n\r\n // Encode following 'application/x-www-form-urlencoded' standard (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.3)\r\n // Also mentioned here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\r\n public static formEncode(str: string): string {\r\n return ArcGisTokenGenerator.rfc1738Encode(str).replace(/%20/g, \"+\");\r\n }\r\n\r\n // Encode following RFC1738 standard (https://www.ietf.org/rfc/rfc1738.txt)\r\n // Code from https://locutus.io/php/url/rawurlencode/\r\n public static rfc1738Encode(str: string): string {\r\n return encodeURIComponent(str)\r\n .replace(/!/g, \"%21\")\r\n .replace(/'/g, \"%27\")\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\*/g, \"%2A\");\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ArcGisTokenGenerator.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisTokenGenerator.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\nimport { MapLayerAccessToken } from \"@itwin/core-frontend\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/** @internal */\r\nexport interface ArcGisOAuth2Token extends MapLayerAccessToken {\r\n\r\n // The expiration time of the token in milliseconds (UNIX time)\r\n expiresAt: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n\r\n // Username associated with this token\r\n userName: string;\r\n\r\n // A Binary value that, if true, implies that the user had checked \"Keep me signed in\"\r\n persist?: boolean;\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisToken extends MapLayerAccessToken {\r\n // The expiration time of the token in milliseconds since January 1, 1970 (UTC).\r\n expires: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n}\r\n\r\n// client application's base URL, a user-specified IP address, or the IP address that is making the request.\r\n/** @internal */\r\nexport enum ArcGisTokenClientType {\r\n ip,\r\n referer,\r\n requestIp,\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisGenerateTokenOptions {\r\n\r\n // The client type that will be granted access to the token.\r\n // Users will be able to specify whether the token will be generated for a client application's base URL,\r\n // a user-specified IP address, or the IP address that is making the request.\r\n client: ArcGisTokenClientType;\r\n\r\n // The IP address that will be using the created token for access.\r\n // On the Generate Token page, the IP address is specified in the IP Address field. This is required when client has been set as ip.\r\n // Example ip=11.11.111.111\r\n ip?: string;\r\n\r\n // The base URL of the client application that will use the token.\r\n // On the Generate Token page, the referrer URL is specified in the Webapp URL field.\r\n // Defaults to location.origin if undefined and client = referer.\r\n // This is required when client has been set as referer.\r\n // Example : referer=https://myserver/mywebapp\r\n referer?: string;\r\n\r\n // The token expiration time in minutes. The default is 60 minutes (one hour).\r\n // The maximum expiration period is 15 days. The maximum value of the expiration time is controlled by the server.\r\n // Requests for tokens larger than this time will be rejected.\r\n // Applications are responsible for renewing expired tokens;\r\n // expired tokens will be rejected by the server on subsequent requests that use the token.\r\n expiration?: number; // in minutes, defaults to 60 minutes\r\n}\r\n\r\n/** @internal */\r\nexport class ArcGisTokenGenerator {\r\n private static readonly restApiPath = \"/rest/\";\r\n private static readonly restApiInfoPath = \"info?f=pjson\";\r\n\r\n // Cache info url to avoid fetching/parsing twice for the same base url.\r\n private static _tokenServiceUrlCache = new Map<string, string>();\r\n\r\n public static async fetchTokenServiceUrl(arcGisRestServiceUrl: string): Promise<string | undefined> {\r\n const lowerUrl = arcGisRestServiceUrl.toLowerCase();\r\n const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);\r\n if (restApiIdx === -1)\r\n return undefined;\r\n const infoUrl = arcGisRestServiceUrl.substring(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;\r\n\r\n let tokenServicesUrl: string | undefined;\r\n try {\r\n const response = await fetch(infoUrl, { method: \"GET\" });\r\n const json = await response.json();\r\n tokenServicesUrl = ArcGisTokenGenerator.getTokenServiceFromInfoJson(json);\r\n } catch (_error) {\r\n }\r\n return tokenServicesUrl;\r\n }\r\n\r\n public static getTokenServiceFromInfoJson(json: any): string | undefined {\r\n return json.authInfo?.isTokenBasedSecurity ? json?.authInfo?.tokenServicesUrl : undefined;\r\n }\r\n\r\n public async getTokenServiceUrl(baseUrl: string): Promise<string | undefined> {\r\n const cached = ArcGisTokenGenerator._tokenServiceUrlCache.get(baseUrl);\r\n if (cached !== undefined)\r\n return cached;\r\n\r\n const tokenServiceUrl = await ArcGisTokenGenerator.fetchTokenServiceUrl(baseUrl);\r\n if (tokenServiceUrl !== undefined)\r\n ArcGisTokenGenerator._tokenServiceUrlCache.set(baseUrl, tokenServiceUrl);\r\n\r\n return tokenServiceUrl;\r\n }\r\n\r\n // base url: ArcGis REST service base URL (format must be \"https://<host>/<instance>/rest/\")\r\n public async generate(arcGisRestServiceUrl: string, userName: string, password: string, options: ArcGisGenerateTokenOptions): Promise<any> {\r\n const tokenServiceUrl = await this.getTokenServiceUrl(arcGisRestServiceUrl);\r\n if (!tokenServiceUrl)\r\n return undefined;\r\n\r\n let token: undefined;\r\n try {\r\n const encodedUsername = encodeURIComponent(userName);\r\n const encodedPassword = encodeURIComponent(password);\r\n\r\n // Compose the expiration param\r\n let expirationStr = \"\";\r\n if (options.expiration) {\r\n expirationStr = `&expiration=${options.expiration}`;\r\n }\r\n\r\n // Compose the client param\r\n let clientStr = \"\";\r\n if (options.client === ArcGisTokenClientType.referer) {\r\n let refererStr = \"\";\r\n if (options.referer === undefined) {\r\n refererStr = encodeURIComponent(location.origin); // default to application origin\r\n } else {\r\n refererStr = encodeURIComponent(options.referer);\r\n }\r\n\r\n clientStr = `&client=referer&referer=${refererStr}`;\r\n } else if (options.client === ArcGisTokenClientType.ip) {\r\n if (options.ip === undefined)\r\n return token;\r\n clientStr = `&client=ip&ip=${options.ip}`;\r\n } else if (options.client === ArcGisTokenClientType.requestIp) {\r\n clientStr = `&client=requestip&ip=`;\r\n }\r\n\r\n const httpRequestOptions: RequestInit = {\r\n method: \"POST\",\r\n body: `username=${encodedUsername}&password=${encodedPassword}${clientStr}${expirationStr}&f=pjson`,\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\r\n };\r\n\r\n const response = await fetch(tokenServiceUrl, httpRequestOptions);\r\n\r\n // Check a token was really generated (an error could be part of the body)\r\n token = await response.json();\r\n\r\n } catch (_error) {\r\n }\r\n return token;\r\n }\r\n\r\n // Encode following 'application/x-www-form-urlencoded' standard (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.3)\r\n // Also mentioned here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\r\n public static formEncode(str: string): string {\r\n return ArcGisTokenGenerator.rfc1738Encode(str).replace(/%20/g, \"+\");\r\n }\r\n\r\n // Encode following RFC1738 standard (https://www.ietf.org/rfc/rfc1738.txt)\r\n // Code from https://locutus.io/php/url/rawurlencode/\r\n public static rfc1738Encode(str: string): string {\r\n return encodeURIComponent(str)\r\n .replace(/!/g, \"%21\")\r\n .replace(/'/g, \"%27\")\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\*/g, \"%2A\");\r\n }\r\n}\r\n"]}
@@ -29,6 +29,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
29
29
  private _redirectUri;
30
30
  private _expiration;
31
31
  private _clientIds;
32
+ private _forceLegacyToken;
32
33
  constructor();
33
34
  initialize(oAuthConfig?: ArcGisOAuthConfig): boolean;
34
35
  private initOauthCallbackFunction;
@@ -48,6 +49,7 @@ export declare class ArcGisAccessClient implements MapLayerAccessClient {
48
49
  private getOAuthTokenForMapLayerUrl;
49
50
  /**
50
51
  * Test if Oauth2 endpoint is accessible and has an associated appId
52
+ * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)
51
53
  * @internal
52
54
  */
53
55
  private validateOAuth2Endpoint;
@@ -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;AAED,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;;IAK9C,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;IAgB3F,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAa9F,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO;IAQ3D,IAAW,WAAW,uBAErB;IAEM,6BAA6B,CAAC,GAAG,EAAE,MAAM;IAchD,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;IAWzC;;;MAGE;YACY,sBAAsB;IAoBpC,OAAO,CAAC,6BAA6B,CAA0B;IAC/D,OAAO,CAAC,yBAAyB,CAA0B;IAE3D;;;KAGC;YACa,iBAAiB;IAwE/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
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;AAED,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;IAmB3F,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAc9F,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;IAWzC;;;;MAIE;YACY,sBAAsB;IAsBpC,OAAO,CAAC,6BAA6B,CAA0B;IAC/D,OAAO,CAAC,yBAAyB,CAA0B;IAE3D;;;KAGC;YACa,iBAAiB;IAyE/B;;;KAGC;IACD,OAAO,CAAC,iBAAiB;CA8B1B"}
@@ -14,6 +14,8 @@ import { ArcGisUrl } from "./ArcGisUrl";
14
14
  export class ArcGisAccessClient {
15
15
  constructor() {
16
16
  this.onOAuthProcessEnd = new BeEvent();
17
+ // Should be kept to 'false'. Debugging purposes only.
18
+ this._forceLegacyToken = false;
17
19
  // Derive the Oauth URL from a typical MapLayerURL
18
20
  // i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
19
21
  // => https://hostname/portal/sharing/oauth2/authorize
@@ -71,9 +73,11 @@ export class ArcGisAccessClient {
71
73
  async getAccessToken(params) {
72
74
  // First lookup Oauth2 tokens, otherwise check try "legacy tokens" if credentials were provided
73
75
  try {
74
- const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
75
- if (oauth2Token)
76
- return oauth2Token;
76
+ if (!this._forceLegacyToken) {
77
+ const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
78
+ if (oauth2Token)
79
+ return oauth2Token;
80
+ }
77
81
  if (params.userName && params.password) {
78
82
  return await ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });
79
83
  }
@@ -84,12 +88,14 @@ export class ArcGisAccessClient {
84
88
  }
85
89
  async getTokenServiceEndPoint(mapLayerUrl) {
86
90
  let tokenEndpoint;
87
- try {
88
- tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);
89
- if (tokenEndpoint) {
91
+ if (!this._forceLegacyToken) {
92
+ try {
93
+ tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2EndpointType.Authorize);
94
+ if (tokenEndpoint) {
95
+ }
90
96
  }
97
+ catch { }
91
98
  }
92
- catch { }
93
99
  return tokenEndpoint;
94
100
  }
95
101
  invalidateToken(token) {
@@ -103,16 +109,27 @@ export class ArcGisAccessClient {
103
109
  return this._redirectUri;
104
110
  }
105
111
  getMatchingEnterpriseClientId(url) {
106
- let clientId;
107
112
  const clientIds = this.arcGisEnterpriseClientIds;
108
113
  if (!clientIds) {
109
114
  return undefined;
110
115
  }
116
+ let clientId;
117
+ let defaultClientId;
111
118
  for (const entry of clientIds) {
112
- if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
113
- clientId = entry.clientId;
119
+ if (entry.serviceBaseUrl === "") {
120
+ defaultClientId = entry.clientId;
121
+ }
122
+ else {
123
+ if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
124
+ clientId = entry.clientId;
125
+ }
114
126
  }
115
127
  }
128
+ // If we could not find a match with serviceBaseUrl, and a default clientId
129
+ // was specified (i.e empty url), then use default clientId
130
+ if (clientId === undefined && defaultClientId !== undefined) {
131
+ clientId = defaultClientId;
132
+ }
116
133
  return clientId;
117
134
  }
118
135
  get expiration() {
@@ -171,6 +188,7 @@ export class ArcGisAccessClient {
171
188
  }
172
189
  /**
173
190
  * Test if Oauth2 endpoint is accessible and has an associated appId
191
+ * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)
174
192
  * @internal
175
193
  */
176
194
  async validateOAuth2Endpoint(endpointUrl) {
@@ -184,7 +202,9 @@ export class ArcGisAccessClient {
184
202
  status = data.status;
185
203
  }
186
204
  catch (error) {
187
- status = error.status;
205
+ // fetch() throws when there is a CORS error, so in that case
206
+ // we cannot confirm if the oauth2 endpoint is valid or not, we return undefined
207
+ return undefined;
188
208
  }
189
209
  return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
190
210
  }
@@ -228,7 +248,9 @@ export class ArcGisAccessClient {
228
248
  // Validate the URL we just composed
229
249
  try {
230
250
  const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;
231
- if (await this.validateOAuth2Endpoint(oauth2Url)) {
251
+ const valid = await this.validateOAuth2Endpoint(oauth2Url);
252
+ // We assume undefined means CORS error, that shouldn't prevent popup from displaying the login page.
253
+ if (valid === undefined || valid) {
232
254
  const oauthEndpoint = new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);
233
255
  cacheResult(oauthEndpoint);
234
256
  return oauthEndpoint;
@@ -236,8 +258,7 @@ export class ArcGisAccessClient {
236
258
  }
237
259
  catch { }
238
260
  }
239
- // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'
240
- // lets use another approach.
261
+ // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl', lets try something else.
241
262
  // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
242
263
  const regExMatch = url.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
243
264
  if (regExMatch !== null && regExMatch.length >= 2) {
@@ -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 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 try {\r\n const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());\r\n if (oauth2Token)\r\n return oauth2Token;\r\n\r\n if (params.userName && params.password) {\r\n return await ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n } catch {\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\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 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 let clientId: string | undefined;\r\n const clientIds = this.arcGisEnterpriseClientIds;\r\n if (!clientIds) {\r\n return undefined;\r\n }\r\n for (const entry of clientIds) {\r\n if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {\r\n clientId = entry.clientId;\r\n }\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 /**\r\n * Test if Oauth2 endpoint is accessible and has an associated appId\r\n * @internal\r\n */\r\n private async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean> {\r\n\r\n // Check if we got a matching appId for that endpoint, otherwise its not worth going further\r\n if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {\r\n return false;\r\n }\r\n\r\n let status: number | undefined;\r\n try {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n status = data.status;\r\n } catch (error: any) {\r\n status = error.status;\r\n }\r\n return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\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 async getOAuth2Endpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n\r\n // Return from cache if available\r\n const cachedEndpoint = (endpoint === 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 cacheResult = (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 const endpointStr = (endpoint === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n const urlObj = new URL(url);\r\n if (urlObj.hostname.toLowerCase().endsWith(\"arcgis.com\")) {\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(url, 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 let restUrlFromTokenService: URL | undefined;\r\n try {\r\n restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n } catch { }\r\n\r\n if (restUrlFromTokenService !== undefined) {\r\n // Validate the URL we just composed\r\n try {\r\n const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;\r\n if (await this.validateOAuth2Endpoint(oauth2Url)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\r\n }\r\n\r\n // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'\r\n // lets use another approach.\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 try {\r\n const newUrl = newUrlObj.toString();\r\n if (await this.validateOAuth2Endpoint(newUrl)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\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\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 try {\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 await ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenClientType.referer });\r\n }\r\n } catch {\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 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 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 /**\r\n * Test if Oauth2 endpoint is accessible and has an associated appId\r\n * @return true/false if validation succeeded, undefined if validation could not be performed (i.e CORS/network error)\r\n * @internal\r\n */\r\n private async validateOAuth2Endpoint(endpointUrl: string): Promise<boolean | undefined> {\r\n\r\n // Check if we got a matching appId for that endpoint, otherwise its not worth going further\r\n if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {\r\n return false;\r\n }\r\n\r\n let status: number | undefined;\r\n try {\r\n const data = await fetch(endpointUrl, { method: \"GET\" });\r\n status = data.status;\r\n } catch (error: any) {\r\n // fetch() throws when there is a CORS error, so in that case\r\n // we cannot confirm if the oauth2 endpoint is valid or not, we return undefined\r\n return undefined;\r\n }\r\n return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters\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 async getOAuth2Endpoint(url: string, endpoint: ArcGisOAuth2EndpointType): Promise<ArcGisOAuth2Endpoint | undefined> {\r\n\r\n // Return from cache if available\r\n const cachedEndpoint = (endpoint === 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 cacheResult = (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 const endpointStr = (endpoint === ArcGisOAuth2EndpointType.Authorize ? \"authorize\" : \"token\");\r\n const urlObj = new URL(url);\r\n if (urlObj.hostname.toLowerCase().endsWith(\"arcgis.com\")) {\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(url, 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 let restUrlFromTokenService: URL | undefined;\r\n try {\r\n restUrlFromTokenService = await ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);\r\n } catch { }\r\n\r\n if (restUrlFromTokenService !== undefined) {\r\n // Validate the URL we just composed\r\n try {\r\n const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;\r\n const valid = await this.validateOAuth2Endpoint(oauth2Url);\r\n // We assume undefined means CORS error, that shouldn't prevent popup from displaying the login page.\r\n if (valid === undefined || valid) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\r\n }\r\n\r\n // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl', lets try something else.\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 try {\r\n const newUrl = newUrlObj.toString();\r\n if (await this.validateOAuth2Endpoint(newUrl)) {\r\n const oauthEndpoint = new ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);\r\n cacheResult(oauthEndpoint);\r\n return oauthEndpoint;\r\n }\r\n } catch { }\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"]}
@@ -13,7 +13,7 @@ export class ArcGisTokenGenerator {
13
13
  const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);
14
14
  if (restApiIdx === -1)
15
15
  return undefined;
16
- const infoUrl = lowerUrl.substr(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;
16
+ const infoUrl = arcGisRestServiceUrl.substring(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;
17
17
  let tokenServicesUrl;
18
18
  try {
19
19
  const response = await fetch(infoUrl, { method: "GET" });
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGisTokenGenerator.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisTokenGenerator.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\nimport { MapLayerAccessToken } from \"@itwin/core-frontend\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/** @internal */\r\nexport interface ArcGisOAuth2Token extends MapLayerAccessToken {\r\n\r\n // The expiration time of the token in milliseconds (UNIX time)\r\n expiresAt: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n\r\n // Username associated with this token\r\n userName: string;\r\n\r\n // A Binary value that, if true, implies that the user had checked \"Keep me signed in\"\r\n persist?: boolean;\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisToken extends MapLayerAccessToken {\r\n // The expiration time of the token in milliseconds since January 1, 1970 (UTC).\r\n expires: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n}\r\n\r\n// client application's base URL, a user-specified IP address, or the IP address that is making the request.\r\n/** @internal */\r\nexport enum ArcGisTokenClientType {\r\n ip,\r\n referer,\r\n requestIp,\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisGenerateTokenOptions {\r\n\r\n // The client type that will be granted access to the token.\r\n // Users will be able to specify whether the token will be generated for a client application's base URL,\r\n // a user-specified IP address, or the IP address that is making the request.\r\n client: ArcGisTokenClientType;\r\n\r\n // The IP address that will be using the created token for access.\r\n // On the Generate Token page, the IP address is specified in the IP Address field. This is required when client has been set as ip.\r\n // Example ip=11.11.111.111\r\n ip?: string;\r\n\r\n // The base URL of the client application that will use the token.\r\n // On the Generate Token page, the referrer URL is specified in the Webapp URL field.\r\n // Defaults to location.origin if undefined and client = referer.\r\n // This is required when client has been set as referer.\r\n // Example : referer=https://myserver/mywebapp\r\n referer?: string;\r\n\r\n // The token expiration time in minutes. The default is 60 minutes (one hour).\r\n // The maximum expiration period is 15 days. The maximum value of the expiration time is controlled by the server.\r\n // Requests for tokens larger than this time will be rejected.\r\n // Applications are responsible for renewing expired tokens;\r\n // expired tokens will be rejected by the server on subsequent requests that use the token.\r\n expiration?: number; // in minutes, defaults to 60 minutes\r\n}\r\n\r\n/** @internal */\r\nexport class ArcGisTokenGenerator {\r\n private static readonly restApiPath = \"/rest/\";\r\n private static readonly restApiInfoPath = \"info?f=pjson\";\r\n\r\n // Cache info url to avoid fetching/parsing twice for the same base url.\r\n private static _tokenServiceUrlCache = new Map<string, string>();\r\n\r\n public static async fetchTokenServiceUrl(arcGisRestServiceUrl: string): Promise<string | undefined> {\r\n const lowerUrl = arcGisRestServiceUrl.toLowerCase();\r\n const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);\r\n if (restApiIdx === -1)\r\n return undefined;\r\n const infoUrl = lowerUrl.substr(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;\r\n\r\n let tokenServicesUrl: string | undefined;\r\n try {\r\n const response = await fetch(infoUrl, { method: \"GET\" });\r\n const json = await response.json();\r\n tokenServicesUrl = ArcGisTokenGenerator.getTokenServiceFromInfoJson(json);\r\n } catch (_error) {\r\n }\r\n return tokenServicesUrl;\r\n }\r\n\r\n public static getTokenServiceFromInfoJson(json: any): string | undefined {\r\n return json.authInfo?.isTokenBasedSecurity ? json?.authInfo?.tokenServicesUrl : undefined;\r\n }\r\n\r\n public async getTokenServiceUrl(baseUrl: string): Promise<string | undefined> {\r\n const cached = ArcGisTokenGenerator._tokenServiceUrlCache.get(baseUrl);\r\n if (cached !== undefined)\r\n return cached;\r\n\r\n const tokenServiceUrl = await ArcGisTokenGenerator.fetchTokenServiceUrl(baseUrl);\r\n if (tokenServiceUrl !== undefined)\r\n ArcGisTokenGenerator._tokenServiceUrlCache.set(baseUrl, tokenServiceUrl);\r\n\r\n return tokenServiceUrl;\r\n }\r\n\r\n // base url: ArcGis REST service base URL (format must be \"https://<host>/<instance>/rest/\")\r\n public async generate(arcGisRestServiceUrl: string, userName: string, password: string, options: ArcGisGenerateTokenOptions): Promise<any> {\r\n const tokenServiceUrl = await this.getTokenServiceUrl(arcGisRestServiceUrl);\r\n if (!tokenServiceUrl)\r\n return undefined;\r\n\r\n let token: undefined;\r\n try {\r\n const encodedUsername = encodeURIComponent(userName);\r\n const encodedPassword = encodeURIComponent(password);\r\n\r\n // Compose the expiration param\r\n let expirationStr = \"\";\r\n if (options.expiration) {\r\n expirationStr = `&expiration=${options.expiration}`;\r\n }\r\n\r\n // Compose the client param\r\n let clientStr = \"\";\r\n if (options.client === ArcGisTokenClientType.referer) {\r\n let refererStr = \"\";\r\n if (options.referer === undefined) {\r\n refererStr = encodeURIComponent(location.origin); // default to application origin\r\n } else {\r\n refererStr = encodeURIComponent(options.referer);\r\n }\r\n\r\n clientStr = `&client=referer&referer=${refererStr}`;\r\n } else if (options.client === ArcGisTokenClientType.ip) {\r\n if (options.ip === undefined)\r\n return token;\r\n clientStr = `&client=ip&ip=${options.ip}`;\r\n } else if (options.client === ArcGisTokenClientType.requestIp) {\r\n clientStr = `&client=requestip&ip=`;\r\n }\r\n\r\n const httpRequestOptions: RequestInit = {\r\n method: \"POST\",\r\n body: `username=${encodedUsername}&password=${encodedPassword}${clientStr}${expirationStr}&f=pjson`,\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\r\n };\r\n\r\n const response = await fetch(tokenServiceUrl, httpRequestOptions);\r\n\r\n // Check a token was really generated (an error could be part of the body)\r\n token = await response.json();\r\n\r\n } catch (_error) {\r\n }\r\n return token;\r\n }\r\n\r\n // Encode following 'application/x-www-form-urlencoded' standard (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.3)\r\n // Also mentioned here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\r\n public static formEncode(str: string): string {\r\n return ArcGisTokenGenerator.rfc1738Encode(str).replace(/%20/g, \"+\");\r\n }\r\n\r\n // Encode following RFC1738 standard (https://www.ietf.org/rfc/rfc1738.txt)\r\n // Code from https://locutus.io/php/url/rawurlencode/\r\n public static rfc1738Encode(str: string): string {\r\n return encodeURIComponent(str)\r\n .replace(/!/g, \"%21\")\r\n .replace(/'/g, \"%27\")\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\*/g, \"%2A\");\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ArcGisTokenGenerator.js","sourceRoot":"","sources":["../../../src/ArcGis/ArcGisTokenGenerator.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\nimport { MapLayerAccessToken } from \"@itwin/core-frontend\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/** @internal */\r\nexport interface ArcGisOAuth2Token extends MapLayerAccessToken {\r\n\r\n // The expiration time of the token in milliseconds (UNIX time)\r\n expiresAt: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n\r\n // Username associated with this token\r\n userName: string;\r\n\r\n // A Binary value that, if true, implies that the user had checked \"Keep me signed in\"\r\n persist?: boolean;\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisToken extends MapLayerAccessToken {\r\n // The expiration time of the token in milliseconds since January 1, 1970 (UTC).\r\n expires: number;\r\n\r\n // This property will show as true if the token must always pass over ssl.\r\n ssl: boolean;\r\n}\r\n\r\n// client application's base URL, a user-specified IP address, or the IP address that is making the request.\r\n/** @internal */\r\nexport enum ArcGisTokenClientType {\r\n ip,\r\n referer,\r\n requestIp,\r\n}\r\n\r\n/** @internal */\r\nexport interface ArcGisGenerateTokenOptions {\r\n\r\n // The client type that will be granted access to the token.\r\n // Users will be able to specify whether the token will be generated for a client application's base URL,\r\n // a user-specified IP address, or the IP address that is making the request.\r\n client: ArcGisTokenClientType;\r\n\r\n // The IP address that will be using the created token for access.\r\n // On the Generate Token page, the IP address is specified in the IP Address field. This is required when client has been set as ip.\r\n // Example ip=11.11.111.111\r\n ip?: string;\r\n\r\n // The base URL of the client application that will use the token.\r\n // On the Generate Token page, the referrer URL is specified in the Webapp URL field.\r\n // Defaults to location.origin if undefined and client = referer.\r\n // This is required when client has been set as referer.\r\n // Example : referer=https://myserver/mywebapp\r\n referer?: string;\r\n\r\n // The token expiration time in minutes. The default is 60 minutes (one hour).\r\n // The maximum expiration period is 15 days. The maximum value of the expiration time is controlled by the server.\r\n // Requests for tokens larger than this time will be rejected.\r\n // Applications are responsible for renewing expired tokens;\r\n // expired tokens will be rejected by the server on subsequent requests that use the token.\r\n expiration?: number; // in minutes, defaults to 60 minutes\r\n}\r\n\r\n/** @internal */\r\nexport class ArcGisTokenGenerator {\r\n private static readonly restApiPath = \"/rest/\";\r\n private static readonly restApiInfoPath = \"info?f=pjson\";\r\n\r\n // Cache info url to avoid fetching/parsing twice for the same base url.\r\n private static _tokenServiceUrlCache = new Map<string, string>();\r\n\r\n public static async fetchTokenServiceUrl(arcGisRestServiceUrl: string): Promise<string | undefined> {\r\n const lowerUrl = arcGisRestServiceUrl.toLowerCase();\r\n const restApiIdx = lowerUrl.indexOf(ArcGisTokenGenerator.restApiPath);\r\n if (restApiIdx === -1)\r\n return undefined;\r\n const infoUrl = arcGisRestServiceUrl.substring(0, restApiIdx + ArcGisTokenGenerator.restApiPath.length) + ArcGisTokenGenerator.restApiInfoPath;\r\n\r\n let tokenServicesUrl: string | undefined;\r\n try {\r\n const response = await fetch(infoUrl, { method: \"GET\" });\r\n const json = await response.json();\r\n tokenServicesUrl = ArcGisTokenGenerator.getTokenServiceFromInfoJson(json);\r\n } catch (_error) {\r\n }\r\n return tokenServicesUrl;\r\n }\r\n\r\n public static getTokenServiceFromInfoJson(json: any): string | undefined {\r\n return json.authInfo?.isTokenBasedSecurity ? json?.authInfo?.tokenServicesUrl : undefined;\r\n }\r\n\r\n public async getTokenServiceUrl(baseUrl: string): Promise<string | undefined> {\r\n const cached = ArcGisTokenGenerator._tokenServiceUrlCache.get(baseUrl);\r\n if (cached !== undefined)\r\n return cached;\r\n\r\n const tokenServiceUrl = await ArcGisTokenGenerator.fetchTokenServiceUrl(baseUrl);\r\n if (tokenServiceUrl !== undefined)\r\n ArcGisTokenGenerator._tokenServiceUrlCache.set(baseUrl, tokenServiceUrl);\r\n\r\n return tokenServiceUrl;\r\n }\r\n\r\n // base url: ArcGis REST service base URL (format must be \"https://<host>/<instance>/rest/\")\r\n public async generate(arcGisRestServiceUrl: string, userName: string, password: string, options: ArcGisGenerateTokenOptions): Promise<any> {\r\n const tokenServiceUrl = await this.getTokenServiceUrl(arcGisRestServiceUrl);\r\n if (!tokenServiceUrl)\r\n return undefined;\r\n\r\n let token: undefined;\r\n try {\r\n const encodedUsername = encodeURIComponent(userName);\r\n const encodedPassword = encodeURIComponent(password);\r\n\r\n // Compose the expiration param\r\n let expirationStr = \"\";\r\n if (options.expiration) {\r\n expirationStr = `&expiration=${options.expiration}`;\r\n }\r\n\r\n // Compose the client param\r\n let clientStr = \"\";\r\n if (options.client === ArcGisTokenClientType.referer) {\r\n let refererStr = \"\";\r\n if (options.referer === undefined) {\r\n refererStr = encodeURIComponent(location.origin); // default to application origin\r\n } else {\r\n refererStr = encodeURIComponent(options.referer);\r\n }\r\n\r\n clientStr = `&client=referer&referer=${refererStr}`;\r\n } else if (options.client === ArcGisTokenClientType.ip) {\r\n if (options.ip === undefined)\r\n return token;\r\n clientStr = `&client=ip&ip=${options.ip}`;\r\n } else if (options.client === ArcGisTokenClientType.requestIp) {\r\n clientStr = `&client=requestip&ip=`;\r\n }\r\n\r\n const httpRequestOptions: RequestInit = {\r\n method: \"POST\",\r\n body: `username=${encodedUsername}&password=${encodedPassword}${clientStr}${expirationStr}&f=pjson`,\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\r\n };\r\n\r\n const response = await fetch(tokenServiceUrl, httpRequestOptions);\r\n\r\n // Check a token was really generated (an error could be part of the body)\r\n token = await response.json();\r\n\r\n } catch (_error) {\r\n }\r\n return token;\r\n }\r\n\r\n // Encode following 'application/x-www-form-urlencoded' standard (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.3)\r\n // Also mentioned here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\r\n public static formEncode(str: string): string {\r\n return ArcGisTokenGenerator.rfc1738Encode(str).replace(/%20/g, \"+\");\r\n }\r\n\r\n // Encode following RFC1738 standard (https://www.ietf.org/rfc/rfc1738.txt)\r\n // Code from https://locutus.io/php/url/rawurlencode/\r\n public static rfc1738Encode(str: string): string {\r\n return encodeURIComponent(str)\r\n .replace(/!/g, \"%21\")\r\n .replace(/'/g, \"%27\")\r\n .replace(/\\(/g, \"%28\")\r\n .replace(/\\)/g, \"%29\")\r\n .replace(/\\*/g, \"%2A\");\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": "3.5.0-dev.8",
3
+ "version": "3.6.0-dev.3",
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",
@@ -21,11 +21,11 @@
21
21
  "url": "http://www.bentley.com"
22
22
  },
23
23
  "devDependencies": {
24
- "@itwin/build-tools": "3.5.0-dev.8",
25
- "@itwin/core-bentley": "3.5.0-dev.8",
26
- "@itwin/core-common": "3.5.0-dev.8",
27
- "@itwin/core-frontend": "3.5.0-dev.8",
28
- "@itwin/eslint-plugin": "3.5.0-dev.8",
24
+ "@itwin/build-tools": "3.6.0-dev.3",
25
+ "@itwin/core-bentley": "3.6.0-dev.3",
26
+ "@itwin/core-common": "3.6.0-dev.3",
27
+ "@itwin/core-frontend": "3.6.0-dev.3",
28
+ "@itwin/eslint-plugin": "3.6.0-dev.3",
29
29
  "@types/chai": "4.3.1",
30
30
  "@types/mocha": "^8.2.2",
31
31
  "@types/sinon": "^9.0.0",
@@ -43,7 +43,7 @@
43
43
  "typescript": "~4.4.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "@itwin/core-bentley": "3.5.0-dev.8"
46
+ "@itwin/core-bentley": "3.6.0-dev.3"
47
47
  },
48
48
  "nyc": {
49
49
  "extends": "./node_modules/@itwin/build-tools/.nycrc",