@itwin/map-layers-auth 3.5.0-dev.4 → 3.5.0-dev.5

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.
Files changed (37) hide show
  1. package/lib/cjs/ArcGis/ArcGisAccessClient.d.ts +66 -66
  2. package/lib/cjs/ArcGis/ArcGisAccessClient.js +294 -294
  3. package/lib/cjs/ArcGis/ArcGisAccessClient.js.map +1 -1
  4. package/lib/cjs/ArcGis/ArcGisOAuth2Endpoint.d.ts +22 -22
  5. package/lib/cjs/ArcGis/ArcGisOAuth2Endpoint.js +46 -46
  6. package/lib/cjs/ArcGis/ArcGisOAuth2Endpoint.js.map +1 -1
  7. package/lib/cjs/ArcGis/ArcGisTokenGenerator.d.ts +41 -41
  8. package/lib/cjs/ArcGis/ArcGisTokenGenerator.js +110 -110
  9. package/lib/cjs/ArcGis/ArcGisTokenGenerator.js.map +1 -1
  10. package/lib/cjs/ArcGis/ArcGisTokenManager.d.ts +20 -20
  11. package/lib/cjs/ArcGis/ArcGisTokenManager.js +109 -109
  12. package/lib/cjs/ArcGis/ArcGisTokenManager.js.map +1 -1
  13. package/lib/cjs/ArcGis/ArcGisUrl.d.ts +6 -6
  14. package/lib/cjs/ArcGis/ArcGisUrl.js +49 -49
  15. package/lib/cjs/ArcGis/ArcGisUrl.js.map +1 -1
  16. package/lib/cjs/map-layers-auth.d.ts +5 -5
  17. package/lib/cjs/map-layers-auth.js +21 -21
  18. package/lib/cjs/map-layers-auth.js.map +1 -1
  19. package/lib/esm/ArcGis/ArcGisAccessClient.d.ts +66 -66
  20. package/lib/esm/ArcGis/ArcGisAccessClient.js +290 -290
  21. package/lib/esm/ArcGis/ArcGisAccessClient.js.map +1 -1
  22. package/lib/esm/ArcGis/ArcGisOAuth2Endpoint.d.ts +22 -22
  23. package/lib/esm/ArcGis/ArcGisOAuth2Endpoint.js +42 -42
  24. package/lib/esm/ArcGis/ArcGisOAuth2Endpoint.js.map +1 -1
  25. package/lib/esm/ArcGis/ArcGisTokenGenerator.d.ts +41 -41
  26. package/lib/esm/ArcGis/ArcGisTokenGenerator.js +106 -106
  27. package/lib/esm/ArcGis/ArcGisTokenGenerator.js.map +1 -1
  28. package/lib/esm/ArcGis/ArcGisTokenManager.d.ts +20 -20
  29. package/lib/esm/ArcGis/ArcGisTokenManager.js +105 -105
  30. package/lib/esm/ArcGis/ArcGisTokenManager.js.map +1 -1
  31. package/lib/esm/ArcGis/ArcGisUrl.d.ts +6 -6
  32. package/lib/esm/ArcGis/ArcGisUrl.js +45 -45
  33. package/lib/esm/ArcGis/ArcGisUrl.js.map +1 -1
  34. package/lib/esm/map-layers-auth.d.ts +5 -5
  35. package/lib/esm/map-layers-auth.js +9 -9
  36. package/lib/esm/map-layers-auth.js.map +1 -1
  37. package/package.json +7 -7
@@ -1,295 +1,295 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- /** @packageDocumentation
7
- * @module Tiles
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ArcGisAccessClient = void 0;
11
- const core_bentley_1 = require("@itwin/core-bentley");
12
- const ArcGisTokenGenerator_1 = require("./ArcGisTokenGenerator");
13
- const ArcGisOAuth2Endpoint_1 = require("./ArcGisOAuth2Endpoint");
14
- const ArcGisTokenManager_1 = require("./ArcGisTokenManager");
15
- const ArcGisUrl_1 = require("./ArcGisUrl");
16
- /** @beta */
17
- class ArcGisAccessClient {
18
- constructor() {
19
- this.onOAuthProcessEnd = new core_bentley_1.BeEvent();
20
- // Derive the Oauth URL from a typical MapLayerURL
21
- // i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
22
- // => https://hostname/portal/sharing/oauth2/authorize
23
- this._oauthAuthorizeEndPointsCache = new Map();
24
- this._oauthTokenEndPointsCache = new Map();
25
- }
26
- initialize(oAuthConfig) {
27
- if (oAuthConfig) {
28
- this._redirectUri = oAuthConfig.redirectUri;
29
- this._expiration = oAuthConfig.tokenExpiration;
30
- this._clientIds = oAuthConfig.clientIds;
31
- this.initOauthCallbackFunction();
32
- }
33
- return true;
34
- }
35
- initOauthCallbackFunction() {
36
- window.arcGisOAuth2Callback = (redirectLocation) => {
37
- var _a, _b, _c, _d;
38
- let eventSuccess = false;
39
- let stateData;
40
- if (redirectLocation && redirectLocation.hash.length > 0) {
41
- const locationHash = redirectLocation.hash;
42
- const hashParams = new URLSearchParams(locationHash.substring(1));
43
- const token = (_a = hashParams.get("access_token")) !== null && _a !== void 0 ? _a : undefined;
44
- const expiresInStr = (_b = hashParams.get("expires_in")) !== null && _b !== void 0 ? _b : undefined;
45
- const userName = (_c = hashParams.get("username")) !== null && _c !== void 0 ? _c : undefined;
46
- const ssl = hashParams.get("ssl") === "true";
47
- const stateStr = (_d = hashParams.get("state")) !== null && _d !== void 0 ? _d : undefined;
48
- const persist = hashParams.get("persist") === "true";
49
- if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {
50
- let endpointOrigin;
51
- try {
52
- const state = JSON.parse(stateStr);
53
- stateData = state === null || state === void 0 ? void 0 : state.customData;
54
- endpointOrigin = state === null || state === void 0 ? void 0 : state.endpointOrigin;
55
- }
56
- catch {
57
- }
58
- const expiresIn = Number(expiresInStr);
59
- const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)
60
- if (endpointOrigin !== undefined) {
61
- ArcGisTokenManager_1.ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });
62
- eventSuccess = true;
63
- }
64
- }
65
- }
66
- this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);
67
- };
68
- }
69
- unInitialize() {
70
- this._redirectUri = undefined;
71
- this._expiration = undefined;
72
- window.arcGisOAuth2Callback = undefined;
73
- }
74
- async getAccessToken(params) {
75
- // First lookup Oauth2 tokens, otherwise check try "legacy tokens" if credentials were provided
76
- try {
77
- const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
78
- if (oauth2Token)
79
- return oauth2Token;
80
- if (params.userName && params.password) {
81
- return await ArcGisTokenManager_1.ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenGenerator_1.ArcGisTokenClientType.referer });
82
- }
83
- }
84
- catch {
85
- }
86
- return undefined;
87
- }
88
- async getTokenServiceEndPoint(mapLayerUrl) {
89
- let tokenEndpoint;
90
- try {
91
- tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
92
- if (tokenEndpoint) {
93
- }
94
- }
95
- catch { }
96
- return tokenEndpoint;
97
- }
98
- invalidateToken(token) {
99
- let found = ArcGisTokenManager_1.ArcGisTokenManager.invalidateToken(token);
100
- if (!found) {
101
- found = ArcGisTokenManager_1.ArcGisTokenManager.invalidateOAuth2Token(token);
102
- }
103
- return found;
104
- }
105
- get redirectUri() {
106
- return this._redirectUri;
107
- }
108
- getMatchingEnterpriseClientId(url) {
109
- let clientId;
110
- const clientIds = this.arcGisEnterpriseClientIds;
111
- if (!clientIds) {
112
- return undefined;
113
- }
114
- for (const entry of clientIds) {
115
- if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
116
- clientId = entry.clientId;
117
- }
118
- }
119
- return clientId;
120
- }
121
- get expiration() {
122
- return this._expiration;
123
- }
124
- get arcGisOnlineClientId() {
125
- var _a;
126
- return (_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.arcgisOnlineClientId;
127
- }
128
- set arcGisOnlineClientId(clientId) {
129
- if (this._clientIds === undefined) {
130
- this._clientIds = { arcgisOnlineClientId: clientId };
131
- }
132
- this._clientIds.arcgisOnlineClientId = clientId;
133
- }
134
- get arcGisEnterpriseClientIds() {
135
- var _a;
136
- return (_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds;
137
- }
138
- setEnterpriseClientId(serviceBaseUrl, clientId) {
139
- var _a;
140
- if ((_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds) {
141
- const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);
142
- if (foundIdx !== -1) {
143
- this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;
144
- }
145
- else {
146
- this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });
147
- }
148
- }
149
- else {
150
- if (this._clientIds === undefined) {
151
- this._clientIds = {};
152
- }
153
- this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];
154
- }
155
- }
156
- removeEnterpriseClientId(clientId) {
157
- var _a, _b, _c;
158
- if ((_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds) {
159
- this._clientIds.enterpriseClientIds = (_c = (_b = this._clientIds) === null || _b === void 0 ? void 0 : _b.enterpriseClientIds) === null || _c === void 0 ? void 0 : _c.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);
160
- }
161
- }
162
- /// //////////
163
- /** @internal */
164
- async getOAuthTokenForMapLayerUrl(mapLayerUrl) {
165
- try {
166
- const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
167
- if (oauthEndpoint !== undefined) {
168
- const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());
169
- return ArcGisTokenManager_1.ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);
170
- }
171
- }
172
- catch { }
173
- return undefined;
174
- }
175
- /**
176
- * Test if Oauth2 endpoint is accessible and has an associated appId
177
- * @internal
178
- */
179
- async validateOAuth2Endpoint(endpointUrl) {
180
- // Check if we got a matching appId for that endpoint, otherwise its not worth going further
181
- if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {
182
- return false;
183
- }
184
- let status;
185
- try {
186
- const data = await fetch(endpointUrl, { method: "GET" });
187
- status = data.status;
188
- }
189
- catch (error) {
190
- status = error.status;
191
- }
192
- return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
193
- }
194
- /**
195
- * Get OAuth2 endpoint that must be cause to get the Oauth2 token
196
- * @internal
197
- */
198
- async getOAuth2Endpoint(url, endpoint) {
199
- // Return from cache if available
200
- const cachedEndpoint = (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? this._oauthAuthorizeEndPointsCache.get(url) : this._oauthTokenEndPointsCache.get(url));
201
- if (cachedEndpoint !== undefined) {
202
- return cachedEndpoint;
203
- }
204
- const cacheResult = (obj) => {
205
- if (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize) {
206
- this._oauthAuthorizeEndPointsCache.set(url, obj);
207
- }
208
- else {
209
- this._oauthTokenEndPointsCache.set(url, obj);
210
- }
211
- };
212
- const endpointStr = (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? "authorize" : "token");
213
- const urlObj = new URL(url);
214
- if (urlObj.hostname.toLowerCase().endsWith("arcgis.com")) {
215
- // ArcGIS Online (fixed)
216
- // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/
217
- if (this.arcGisOnlineClientId === undefined) {
218
- return undefined;
219
- }
220
- const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;
221
- return new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(url, this.constructLoginUrl(oauth2Url, true), true);
222
- }
223
- else {
224
- // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'
225
- let restUrlFromTokenService;
226
- try {
227
- restUrlFromTokenService = await ArcGisUrl_1.ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);
228
- }
229
- catch { }
230
- if (restUrlFromTokenService !== undefined) {
231
- // Validate the URL we just composed
232
- try {
233
- const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;
234
- if (await this.validateOAuth2Endpoint(oauth2Url)) {
235
- const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);
236
- cacheResult(oauthEndpoint);
237
- return oauthEndpoint;
238
- }
239
- }
240
- catch { }
241
- }
242
- // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'
243
- // lets use another approach.
244
- // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
245
- const regExMatch = url.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
246
- if (regExMatch !== null && regExMatch.length >= 2) {
247
- const subdirectory = regExMatch[1];
248
- const port = (urlObj.port !== "80" && urlObj.port !== "443") ? `:${urlObj.port}` : "";
249
- const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);
250
- // Check again the URL we just composed
251
- try {
252
- const newUrl = newUrlObj.toString();
253
- if (await this.validateOAuth2Endpoint(newUrl)) {
254
- const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);
255
- cacheResult(oauthEndpoint);
256
- return oauthEndpoint;
257
- }
258
- }
259
- catch { }
260
- }
261
- }
262
- return undefined; // we could not find any valid oauth2 endpoint
263
- }
264
- /**
265
- * Construct the complete Authorize url to starts the Oauth process
266
- * @internal
267
- */
268
- constructLoginUrl(url, isArcgisOnline) {
269
- const urlObj = new URL(url);
270
- // Set the client id
271
- if (isArcgisOnline) {
272
- const clientId = this.arcGisOnlineClientId;
273
- (0, core_bentley_1.assert)(clientId !== undefined);
274
- if (clientId !== undefined) {
275
- urlObj.searchParams.set("client_id", clientId);
276
- }
277
- }
278
- else {
279
- const clientId = this.getMatchingEnterpriseClientId(url);
280
- (0, core_bentley_1.assert)(clientId !== undefined);
281
- if (undefined !== clientId) {
282
- urlObj.searchParams.set("client_id", clientId);
283
- }
284
- }
285
- urlObj.searchParams.set("response_type", "token");
286
- if (this.expiration !== undefined) {
287
- urlObj.searchParams.set("expiration", `${this.expiration}`);
288
- }
289
- if (this.redirectUri)
290
- urlObj.searchParams.set("redirect_uri", this.redirectUri);
291
- return urlObj.toString();
292
- }
293
- }
294
- exports.ArcGisAccessClient = ArcGisAccessClient;
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Tiles
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ArcGisAccessClient = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const ArcGisTokenGenerator_1 = require("./ArcGisTokenGenerator");
13
+ const ArcGisOAuth2Endpoint_1 = require("./ArcGisOAuth2Endpoint");
14
+ const ArcGisTokenManager_1 = require("./ArcGisTokenManager");
15
+ const ArcGisUrl_1 = require("./ArcGisUrl");
16
+ /** @beta */
17
+ class ArcGisAccessClient {
18
+ constructor() {
19
+ this.onOAuthProcessEnd = new core_bentley_1.BeEvent();
20
+ // Derive the Oauth URL from a typical MapLayerURL
21
+ // i.e. https://hostname/server/rest/services/NewYork/NewYork3857/MapServer
22
+ // => https://hostname/portal/sharing/oauth2/authorize
23
+ this._oauthAuthorizeEndPointsCache = new Map();
24
+ this._oauthTokenEndPointsCache = new Map();
25
+ }
26
+ initialize(oAuthConfig) {
27
+ if (oAuthConfig) {
28
+ this._redirectUri = oAuthConfig.redirectUri;
29
+ this._expiration = oAuthConfig.tokenExpiration;
30
+ this._clientIds = oAuthConfig.clientIds;
31
+ this.initOauthCallbackFunction();
32
+ }
33
+ return true;
34
+ }
35
+ initOauthCallbackFunction() {
36
+ window.arcGisOAuth2Callback = (redirectLocation) => {
37
+ var _a, _b, _c, _d;
38
+ let eventSuccess = false;
39
+ let stateData;
40
+ if (redirectLocation && redirectLocation.hash.length > 0) {
41
+ const locationHash = redirectLocation.hash;
42
+ const hashParams = new URLSearchParams(locationHash.substring(1));
43
+ const token = (_a = hashParams.get("access_token")) !== null && _a !== void 0 ? _a : undefined;
44
+ const expiresInStr = (_b = hashParams.get("expires_in")) !== null && _b !== void 0 ? _b : undefined;
45
+ const userName = (_c = hashParams.get("username")) !== null && _c !== void 0 ? _c : undefined;
46
+ const ssl = hashParams.get("ssl") === "true";
47
+ const stateStr = (_d = hashParams.get("state")) !== null && _d !== void 0 ? _d : undefined;
48
+ const persist = hashParams.get("persist") === "true";
49
+ if (token !== undefined && expiresInStr !== undefined && userName !== undefined && ssl !== undefined && stateStr !== undefined) {
50
+ let endpointOrigin;
51
+ try {
52
+ const state = JSON.parse(stateStr);
53
+ stateData = state === null || state === void 0 ? void 0 : state.customData;
54
+ endpointOrigin = state === null || state === void 0 ? void 0 : state.endpointOrigin;
55
+ }
56
+ catch {
57
+ }
58
+ const expiresIn = Number(expiresInStr);
59
+ const expiresAt = (expiresIn * 1000) + (+new Date()); // Converts the token expiration delay (seconds) into a timestamp (UNIX time)
60
+ if (endpointOrigin !== undefined) {
61
+ ArcGisTokenManager_1.ArcGisTokenManager.setOAuth2Token(endpointOrigin, { token, expiresAt, ssl, userName, persist });
62
+ eventSuccess = true;
63
+ }
64
+ }
65
+ }
66
+ this.onOAuthProcessEnd.raiseEvent(eventSuccess, stateData);
67
+ };
68
+ }
69
+ unInitialize() {
70
+ this._redirectUri = undefined;
71
+ this._expiration = undefined;
72
+ window.arcGisOAuth2Callback = undefined;
73
+ }
74
+ async getAccessToken(params) {
75
+ // First lookup Oauth2 tokens, otherwise check try "legacy tokens" if credentials were provided
76
+ try {
77
+ const oauth2Token = await this.getOAuthTokenForMapLayerUrl(params.mapLayerUrl.toString());
78
+ if (oauth2Token)
79
+ return oauth2Token;
80
+ if (params.userName && params.password) {
81
+ return await ArcGisTokenManager_1.ArcGisTokenManager.getToken(params.mapLayerUrl.toString(), params.userName, params.password, { client: ArcGisTokenGenerator_1.ArcGisTokenClientType.referer });
82
+ }
83
+ }
84
+ catch {
85
+ }
86
+ return undefined;
87
+ }
88
+ async getTokenServiceEndPoint(mapLayerUrl) {
89
+ let tokenEndpoint;
90
+ try {
91
+ tokenEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
92
+ if (tokenEndpoint) {
93
+ }
94
+ }
95
+ catch { }
96
+ return tokenEndpoint;
97
+ }
98
+ invalidateToken(token) {
99
+ let found = ArcGisTokenManager_1.ArcGisTokenManager.invalidateToken(token);
100
+ if (!found) {
101
+ found = ArcGisTokenManager_1.ArcGisTokenManager.invalidateOAuth2Token(token);
102
+ }
103
+ return found;
104
+ }
105
+ get redirectUri() {
106
+ return this._redirectUri;
107
+ }
108
+ getMatchingEnterpriseClientId(url) {
109
+ let clientId;
110
+ const clientIds = this.arcGisEnterpriseClientIds;
111
+ if (!clientIds) {
112
+ return undefined;
113
+ }
114
+ for (const entry of clientIds) {
115
+ if (url.toLowerCase().startsWith(entry.serviceBaseUrl)) {
116
+ clientId = entry.clientId;
117
+ }
118
+ }
119
+ return clientId;
120
+ }
121
+ get expiration() {
122
+ return this._expiration;
123
+ }
124
+ get arcGisOnlineClientId() {
125
+ var _a;
126
+ return (_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.arcgisOnlineClientId;
127
+ }
128
+ set arcGisOnlineClientId(clientId) {
129
+ if (this._clientIds === undefined) {
130
+ this._clientIds = { arcgisOnlineClientId: clientId };
131
+ }
132
+ this._clientIds.arcgisOnlineClientId = clientId;
133
+ }
134
+ get arcGisEnterpriseClientIds() {
135
+ var _a;
136
+ return (_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds;
137
+ }
138
+ setEnterpriseClientId(serviceBaseUrl, clientId) {
139
+ var _a;
140
+ if ((_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds) {
141
+ const foundIdx = this._clientIds.enterpriseClientIds.findIndex((entry) => entry.serviceBaseUrl === serviceBaseUrl);
142
+ if (foundIdx !== -1) {
143
+ this._clientIds.enterpriseClientIds[foundIdx].clientId = clientId;
144
+ }
145
+ else {
146
+ this._clientIds.enterpriseClientIds.push({ serviceBaseUrl, clientId });
147
+ }
148
+ }
149
+ else {
150
+ if (this._clientIds === undefined) {
151
+ this._clientIds = {};
152
+ }
153
+ this._clientIds.enterpriseClientIds = [{ serviceBaseUrl, clientId }];
154
+ }
155
+ }
156
+ removeEnterpriseClientId(clientId) {
157
+ var _a, _b, _c;
158
+ if ((_a = this._clientIds) === null || _a === void 0 ? void 0 : _a.enterpriseClientIds) {
159
+ this._clientIds.enterpriseClientIds = (_c = (_b = this._clientIds) === null || _b === void 0 ? void 0 : _b.enterpriseClientIds) === null || _c === void 0 ? void 0 : _c.filter((item) => item.serviceBaseUrl !== clientId.serviceBaseUrl);
160
+ }
161
+ }
162
+ /// //////////
163
+ /** @internal */
164
+ async getOAuthTokenForMapLayerUrl(mapLayerUrl) {
165
+ try {
166
+ const oauthEndpoint = await this.getOAuth2Endpoint(mapLayerUrl, ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize);
167
+ if (oauthEndpoint !== undefined) {
168
+ const oauthEndpointUrl = new URL(oauthEndpoint.getUrl());
169
+ return ArcGisTokenManager_1.ArcGisTokenManager.getOAuth2Token(oauthEndpointUrl.origin);
170
+ }
171
+ }
172
+ catch { }
173
+ return undefined;
174
+ }
175
+ /**
176
+ * Test if Oauth2 endpoint is accessible and has an associated appId
177
+ * @internal
178
+ */
179
+ async validateOAuth2Endpoint(endpointUrl) {
180
+ // Check if we got a matching appId for that endpoint, otherwise its not worth going further
181
+ if (undefined === this.getMatchingEnterpriseClientId(endpointUrl)) {
182
+ return false;
183
+ }
184
+ let status;
185
+ try {
186
+ const data = await fetch(endpointUrl, { method: "GET" });
187
+ status = data.status;
188
+ }
189
+ catch (error) {
190
+ status = error.status;
191
+ }
192
+ return status === 400; // Oauth2 API returns 400 (Bad Request) when there are missing parameters
193
+ }
194
+ /**
195
+ * Get OAuth2 endpoint that must be cause to get the Oauth2 token
196
+ * @internal
197
+ */
198
+ async getOAuth2Endpoint(url, endpoint) {
199
+ // Return from cache if available
200
+ const cachedEndpoint = (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? this._oauthAuthorizeEndPointsCache.get(url) : this._oauthTokenEndPointsCache.get(url));
201
+ if (cachedEndpoint !== undefined) {
202
+ return cachedEndpoint;
203
+ }
204
+ const cacheResult = (obj) => {
205
+ if (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize) {
206
+ this._oauthAuthorizeEndPointsCache.set(url, obj);
207
+ }
208
+ else {
209
+ this._oauthTokenEndPointsCache.set(url, obj);
210
+ }
211
+ };
212
+ const endpointStr = (endpoint === ArcGisOAuth2Endpoint_1.ArcGisOAuth2EndpointType.Authorize ? "authorize" : "token");
213
+ const urlObj = new URL(url);
214
+ if (urlObj.hostname.toLowerCase().endsWith("arcgis.com")) {
215
+ // ArcGIS Online (fixed)
216
+ // Doc: https://developers.arcgis.com/documentation/mapping-apis-and-services/security/oauth-2.0/
217
+ if (this.arcGisOnlineClientId === undefined) {
218
+ return undefined;
219
+ }
220
+ const oauth2Url = `https://www.arcgis.com/sharing/rest/oauth2/${endpointStr}`;
221
+ return new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(url, this.constructLoginUrl(oauth2Url, true), true);
222
+ }
223
+ else {
224
+ // First attempt: derive the Oauth2 token URL from the 'tokenServicesUrl', exposed by the 'info request'
225
+ let restUrlFromTokenService;
226
+ try {
227
+ restUrlFromTokenService = await ArcGisUrl_1.ArcGisUrl.getRestUrlFromGenerateTokenUrl(urlObj);
228
+ }
229
+ catch { }
230
+ if (restUrlFromTokenService !== undefined) {
231
+ // Validate the URL we just composed
232
+ try {
233
+ const oauth2Url = `${restUrlFromTokenService.toString()}oauth2/${endpointStr}`;
234
+ if (await this.validateOAuth2Endpoint(oauth2Url)) {
235
+ const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(oauth2Url, this.constructLoginUrl(oauth2Url, false), false);
236
+ cacheResult(oauthEndpoint);
237
+ return oauthEndpoint;
238
+ }
239
+ }
240
+ catch { }
241
+ }
242
+ // If reach this point, that means we could not derive the token endpoint from 'tokenServicesUrl'
243
+ // lets use another approach.
244
+ // ArcGIS Enterprise Format https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/authorize
245
+ const regExMatch = url.match(new RegExp(/([^&\/]+)\/rest\/services\/.*/, "i"));
246
+ if (regExMatch !== null && regExMatch.length >= 2) {
247
+ const subdirectory = regExMatch[1];
248
+ const port = (urlObj.port !== "80" && urlObj.port !== "443") ? `:${urlObj.port}` : "";
249
+ const newUrlObj = new URL(`${urlObj.protocol}//${urlObj.hostname}${port}/${subdirectory}/sharing/rest/oauth2/${endpointStr}`);
250
+ // Check again the URL we just composed
251
+ try {
252
+ const newUrl = newUrlObj.toString();
253
+ if (await this.validateOAuth2Endpoint(newUrl)) {
254
+ const oauthEndpoint = new ArcGisOAuth2Endpoint_1.ArcGisOAuth2Endpoint(newUrl, this.constructLoginUrl(newUrl, false), false);
255
+ cacheResult(oauthEndpoint);
256
+ return oauthEndpoint;
257
+ }
258
+ }
259
+ catch { }
260
+ }
261
+ }
262
+ return undefined; // we could not find any valid oauth2 endpoint
263
+ }
264
+ /**
265
+ * Construct the complete Authorize url to starts the Oauth process
266
+ * @internal
267
+ */
268
+ constructLoginUrl(url, isArcgisOnline) {
269
+ const urlObj = new URL(url);
270
+ // Set the client id
271
+ if (isArcgisOnline) {
272
+ const clientId = this.arcGisOnlineClientId;
273
+ (0, core_bentley_1.assert)(clientId !== undefined);
274
+ if (clientId !== undefined) {
275
+ urlObj.searchParams.set("client_id", clientId);
276
+ }
277
+ }
278
+ else {
279
+ const clientId = this.getMatchingEnterpriseClientId(url);
280
+ (0, core_bentley_1.assert)(clientId !== undefined);
281
+ if (undefined !== clientId) {
282
+ urlObj.searchParams.set("client_id", clientId);
283
+ }
284
+ }
285
+ urlObj.searchParams.set("response_type", "token");
286
+ if (this.expiration !== undefined) {
287
+ urlObj.searchParams.set("expiration", `${this.expiration}`);
288
+ }
289
+ if (this.redirectUri)
290
+ urlObj.searchParams.set("redirect_uri", this.redirectUri);
291
+ return urlObj.toString();
292
+ }
293
+ }
294
+ exports.ArcGisAccessClient = ArcGisAccessClient;
295
295
  //# sourceMappingURL=ArcGisAccessClient.js.map