@esri/arcgis-rest-developer-credentials 1.1.0 → 2.1.0
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/dist/bundled/developer-credentials.esm.js +254 -182
- package/dist/bundled/developer-credentials.esm.js.map +1 -1
- package/dist/bundled/developer-credentials.esm.min.js +3 -3
- package/dist/bundled/developer-credentials.esm.min.js.map +1 -1
- package/dist/bundled/developer-credentials.umd.js +257 -182
- package/dist/bundled/developer-credentials.umd.js.map +1 -1
- package/dist/bundled/developer-credentials.umd.min.js +3 -3
- package/dist/bundled/developer-credentials.umd.min.js.map +1 -1
- package/dist/cjs/createApiKey.js +37 -12
- package/dist/cjs/createApiKey.js.map +1 -1
- package/dist/cjs/index.js +1 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/invalidateApiKey.js +46 -0
- package/dist/cjs/invalidateApiKey.js.map +1 -0
- package/dist/cjs/shared/enum/privileges.js +0 -27
- package/dist/cjs/shared/enum/privileges.js.map +1 -1
- package/dist/cjs/shared/generateApiKeyToken.js +27 -0
- package/dist/cjs/shared/generateApiKeyToken.js.map +1 -0
- package/dist/cjs/shared/helpers.js +94 -16
- package/dist/cjs/shared/helpers.js.map +1 -1
- package/dist/cjs/shared/registerApp.js +1 -5
- package/dist/cjs/shared/registerApp.js.map +1 -1
- package/dist/cjs/shared/types/apiKeyType.js.map +1 -1
- package/dist/cjs/shared/types/appType.js.map +1 -1
- package/dist/cjs/updateApiKey.js +45 -26
- package/dist/cjs/updateApiKey.js.map +1 -1
- package/dist/esm/createApiKey.d.ts +9 -3
- package/dist/esm/createApiKey.js +39 -14
- package/dist/esm/createApiKey.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/invalidateApiKey.d.ts +18 -0
- package/dist/esm/invalidateApiKey.js +42 -0
- package/dist/esm/invalidateApiKey.js.map +1 -0
- package/dist/esm/shared/enum/privileges.d.ts +2 -23
- package/dist/esm/shared/enum/privileges.js +1 -26
- package/dist/esm/shared/enum/privileges.js.map +1 -1
- package/dist/esm/shared/generateApiKeyToken.d.ts +11 -0
- package/dist/esm/shared/generateApiKeyToken.js +23 -0
- package/dist/esm/shared/generateApiKeyToken.js.map +1 -0
- package/dist/esm/shared/helpers.d.ts +42 -7
- package/dist/esm/shared/helpers.js +88 -14
- package/dist/esm/shared/helpers.js.map +1 -1
- package/dist/esm/shared/registerApp.d.ts +1 -1
- package/dist/esm/shared/registerApp.js +2 -6
- package/dist/esm/shared/registerApp.js.map +1 -1
- package/dist/esm/shared/types/apiKeyType.d.ts +54 -5
- package/dist/esm/shared/types/apiKeyType.js.map +1 -1
- package/dist/esm/shared/types/appType.d.ts +7 -3
- package/dist/esm/shared/types/appType.js.map +1 -1
- package/dist/esm/updateApiKey.d.ts +8 -2
- package/dist/esm/updateApiKey.js +47 -28
- package/dist/esm/updateApiKey.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/deleteApiKey.js +0 -43
- package/dist/cjs/deleteApiKey.js.map +0 -1
- package/dist/cjs/deleteOAuthApp.js +0 -43
- package/dist/cjs/deleteOAuthApp.js.map +0 -1
- package/dist/esm/deleteApiKey.d.ts +0 -27
- package/dist/esm/deleteApiKey.js +0 -39
- package/dist/esm/deleteApiKey.js.map +0 -1
- package/dist/esm/deleteOAuthApp.d.ts +0 -27
- package/dist/esm/deleteOAuthApp.js +0 -39
- package/dist/esm/deleteOAuthApp.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* @preserve
|
|
2
|
-
* @esri/arcgis-rest-developer-credentials -
|
|
2
|
+
* @esri/arcgis-rest-developer-credentials - v2.0.0 - Apache-2.0
|
|
3
3
|
* Copyright (c) 2017-2025 Esri, Inc.
|
|
4
|
-
*
|
|
4
|
+
* Wed Feb 26 2025 22:10:42 GMT+0000 (Coordinated Universal Time)
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@esri/arcgis-rest-portal'), require('@esri/arcgis-rest-request')) :
|
|
@@ -9,38 +9,62 @@
|
|
|
9
9
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.arcgisRest = global.arcgisRest || {}, global.arcgisRest, global.arcgisRest));
|
|
10
10
|
})(this, (function (exports, arcgisRestPortal, arcgisRestRequest) { 'use strict';
|
|
11
11
|
|
|
12
|
+
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
13
|
+
* Apache-2.0 */
|
|
12
14
|
/**
|
|
13
|
-
* Used to
|
|
15
|
+
* Used to retrieve registered app info. See the [REST Documentation](https://developers.arcgis.com/rest/users-groups-and-items/registered-app-info.htm) for more information.
|
|
16
|
+
*
|
|
17
|
+
* ```js
|
|
18
|
+
* import { getRegisteredAppInfo, IApp } from '@esri/arcgis-rest-developer-credentials';
|
|
19
|
+
* import { ArcGISIdentityManager } from "@esri/arcgis-rest-request";
|
|
20
|
+
*
|
|
21
|
+
* const authSession: ArcGISIdentityManager = await ArcGISIdentityManager.signIn({
|
|
22
|
+
* username: "xyz_usrName",
|
|
23
|
+
* password: "xyz_pw"
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* getRegisteredAppInfo({
|
|
27
|
+
* itemId: "xyz_itemId",
|
|
28
|
+
* authentication: authSession
|
|
29
|
+
* }).then((registeredApp: IApp) => {
|
|
30
|
+
* // => {client_id: "xyz_id", client_secret: "xyz_secret", ...}
|
|
31
|
+
* }).catch(e => {
|
|
32
|
+
* // => an exception object
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param requestOptions - Options for {@linkcode getRegisteredAppInfo | getRegisteredAppInfo()}, including an itemId of which app to retrieve and an {@linkcode ArcGISIdentityManager} authentication session.
|
|
37
|
+
* @returns A Promise that will resolve to an {@linkcode IApp} object representing successfully retrieved app.
|
|
14
38
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
async function getRegisteredAppInfo(requestOptions) {
|
|
40
|
+
const userName = await requestOptions.authentication.getUsername();
|
|
41
|
+
const url = arcgisRestPortal.getPortalUrl(requestOptions) +
|
|
42
|
+
`/content/users/${userName}/items/${requestOptions.itemId}/registeredAppInfo`;
|
|
43
|
+
requestOptions.httpMethod = "POST";
|
|
44
|
+
const registeredAppResponse = await arcgisRestRequest.request(url, Object.assign(Object.assign({}, requestOptions), { params: { f: "json" } }));
|
|
45
|
+
return registeredAppResponseToApp(registeredAppResponse);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function generateApiKeyToken(options) {
|
|
49
|
+
const portal = arcgisRestPortal.getPortalUrl(options);
|
|
50
|
+
const url = `${portal}/oauth2/token`;
|
|
51
|
+
const appInfo = await getRegisteredAppInfo({
|
|
52
|
+
itemId: options.itemId,
|
|
53
|
+
authentication: options.authentication
|
|
54
|
+
});
|
|
55
|
+
const params = {
|
|
56
|
+
client_id: appInfo.client_id,
|
|
57
|
+
client_secret: appInfo.client_secret,
|
|
58
|
+
apiToken: options.apiKey,
|
|
59
|
+
regenerateApiToken: true,
|
|
60
|
+
grant_type: "client_credentials"
|
|
61
|
+
};
|
|
62
|
+
// authentication is not being passed to the request because client_secret acts as the auth
|
|
63
|
+
return arcgisRestRequest.request(url, {
|
|
64
|
+
params
|
|
65
|
+
});
|
|
66
|
+
}
|
|
38
67
|
|
|
39
|
-
/**
|
|
40
|
-
* @internal
|
|
41
|
-
* Used to check privileges validity.
|
|
42
|
-
*/
|
|
43
|
-
const arePrivilegesValid = (privileges) => privileges.every((element) => Object.values(exports.Privileges).includes(element));
|
|
44
68
|
/**
|
|
45
69
|
* @internal
|
|
46
70
|
* Encode special params value (e.g. array type...) in advance in order to make {@linkcode encodeParam} works correctly. Usage is case by case.
|
|
@@ -62,7 +86,8 @@
|
|
|
62
86
|
"apnsProdCert",
|
|
63
87
|
"apnsSandboxCert",
|
|
64
88
|
"gcmApiKey",
|
|
65
|
-
"isBeta"
|
|
89
|
+
"isBeta",
|
|
90
|
+
"customAppLoginShowTriage"
|
|
66
91
|
];
|
|
67
92
|
const dateKeys = ["modified", "registered"];
|
|
68
93
|
return Object.keys(response)
|
|
@@ -82,13 +107,11 @@
|
|
|
82
107
|
* Used to convert {@linkcode IApp} to {@linkcode IApiKeyInfo} only if `appType` is "apikey".
|
|
83
108
|
*/
|
|
84
109
|
function appToApiKeyProperties(response) {
|
|
85
|
-
if (response.appType !== "apikey" || !("apiKey" in response)) {
|
|
86
|
-
throw new Error("Item is not an API key.");
|
|
87
|
-
}
|
|
88
|
-
delete response.client_id;
|
|
89
110
|
delete response.client_secret;
|
|
90
111
|
delete response.redirect_uris;
|
|
91
112
|
delete response.appType;
|
|
113
|
+
delete response.customAppLoginShowTriage;
|
|
114
|
+
delete response.apiKey;
|
|
92
115
|
return response;
|
|
93
116
|
}
|
|
94
117
|
/**
|
|
@@ -96,12 +119,14 @@
|
|
|
96
119
|
* Used to convert {@linkcode IApp} to {@linkcode IOAuthAppInfo}.
|
|
97
120
|
*/
|
|
98
121
|
function appToOAuthAppProperties(response) {
|
|
99
|
-
if (response.appType === "apikey") {
|
|
100
|
-
throw new Error("Item is not an OAuth 2.0 app.");
|
|
101
|
-
}
|
|
102
122
|
delete response.appType;
|
|
103
123
|
delete response.httpReferrers;
|
|
104
124
|
delete response.privileges;
|
|
125
|
+
delete response.apiKey;
|
|
126
|
+
delete response.customAppLoginShowTriage;
|
|
127
|
+
delete response.isPersonalAPIToken;
|
|
128
|
+
delete response.apiToken1Active;
|
|
129
|
+
delete response.apiToken2Active;
|
|
105
130
|
return response;
|
|
106
131
|
}
|
|
107
132
|
/**
|
|
@@ -134,6 +159,84 @@
|
|
|
134
159
|
return obj;
|
|
135
160
|
}, {});
|
|
136
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Used to determine if a generated key is in slot 1 or slot 2 key. The full API key should be passed. `undefined` will be returned if the proper slot could not be identified.
|
|
164
|
+
*/
|
|
165
|
+
function slotForKey(key) {
|
|
166
|
+
const slot = parseInt(key.substring(key.length - 10, key.length - 9));
|
|
167
|
+
if (slot === 1 || slot === 2) {
|
|
168
|
+
return slot;
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* @internal
|
|
174
|
+
* Used to determine which slot to invalidate a key in given a number or a full or patial key.
|
|
175
|
+
*/
|
|
176
|
+
function slotForInvalidationKey(param) {
|
|
177
|
+
if (param === 1 || param === 2) {
|
|
178
|
+
return param;
|
|
179
|
+
}
|
|
180
|
+
if (typeof param !== "string") {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
const fullKeySlot = slotForKey(param);
|
|
184
|
+
if (fullKeySlot) {
|
|
185
|
+
return fullKeySlot;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* @internal
|
|
190
|
+
* Used to generate tokens in slot 1 and/or 2 of an API key.
|
|
191
|
+
*/
|
|
192
|
+
function generateApiKeyTokens(itemId, slots, requestOptions) {
|
|
193
|
+
return Promise.all(slots.map((slot) => {
|
|
194
|
+
return generateApiKeyToken(Object.assign({ itemId, apiKey: slot }, requestOptions));
|
|
195
|
+
})).then((responses) => {
|
|
196
|
+
return responses
|
|
197
|
+
.map((responses) => responses.access_token)
|
|
198
|
+
.reduce((obj, token, index) => {
|
|
199
|
+
obj[`accessToken${slotForKey(token)}`] = token;
|
|
200
|
+
return obj;
|
|
201
|
+
}, {});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* @internal
|
|
206
|
+
* Convert boolean flags to an array of slots for {@linkcode generateApiKeyTokens}.
|
|
207
|
+
*/
|
|
208
|
+
function generateOptionsToSlots(generateToken1, generateToken2) {
|
|
209
|
+
const slots = [];
|
|
210
|
+
if (generateToken1) {
|
|
211
|
+
slots.push(1);
|
|
212
|
+
}
|
|
213
|
+
if (generateToken2) {
|
|
214
|
+
slots.push(2);
|
|
215
|
+
}
|
|
216
|
+
return slots;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* @internal
|
|
220
|
+
* Build params for updating expiration dates
|
|
221
|
+
*/
|
|
222
|
+
function buildExpirationDateParams(requestOptions, fillDefaults) {
|
|
223
|
+
const updateparams = {};
|
|
224
|
+
if (requestOptions.apiToken1ExpirationDate) {
|
|
225
|
+
updateparams.apiToken1ExpirationDate =
|
|
226
|
+
requestOptions.apiToken1ExpirationDate;
|
|
227
|
+
}
|
|
228
|
+
if (requestOptions.apiToken2ExpirationDate) {
|
|
229
|
+
updateparams.apiToken2ExpirationDate =
|
|
230
|
+
requestOptions.apiToken2ExpirationDate;
|
|
231
|
+
}
|
|
232
|
+
if (fillDefaults && !updateparams.apiToken1ExpirationDate) {
|
|
233
|
+
updateparams.apiToken1ExpirationDate = -1;
|
|
234
|
+
}
|
|
235
|
+
if (fillDefaults && !updateparams.apiToken2ExpirationDate) {
|
|
236
|
+
updateparams.apiToken2ExpirationDate = -1;
|
|
237
|
+
}
|
|
238
|
+
return updateparams;
|
|
239
|
+
}
|
|
137
240
|
|
|
138
241
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
139
242
|
* Apache-2.0 */
|
|
@@ -161,7 +264,7 @@
|
|
|
161
264
|
* appType: "multiple",
|
|
162
265
|
* redirect_uris: ["http://localhost:3000/"],
|
|
163
266
|
* httpReferrers: ["http://localhost:3000/"],
|
|
164
|
-
* privileges: [
|
|
267
|
+
* privileges: ["premium:user:geocode:temporary", Privileges.FeatureReport],
|
|
165
268
|
* authentication: authSession
|
|
166
269
|
* }).then((registeredApp: IApp) => {
|
|
167
270
|
* // => {client_id: "xyz_id", client_secret: "xyz_secret", ...}
|
|
@@ -174,10 +277,6 @@
|
|
|
174
277
|
* @returns A Promise that will resolve to an {@linkcode IApp} object representing the newly registered app.
|
|
175
278
|
*/
|
|
176
279
|
async function registerApp(requestOptions) {
|
|
177
|
-
// privileges validation
|
|
178
|
-
if (!arePrivilegesValid(requestOptions.privileges)) {
|
|
179
|
-
throw new Error("The `privileges` option contains invalid privileges.");
|
|
180
|
-
}
|
|
181
280
|
// build params
|
|
182
281
|
const options = arcgisRestRequest.appendCustomParams(requestOptions, [
|
|
183
282
|
"itemId",
|
|
@@ -209,14 +308,20 @@
|
|
|
209
308
|
* password: "xyz_pw"
|
|
210
309
|
* });
|
|
211
310
|
*
|
|
311
|
+
* const threeDaysFromToday = new Date();
|
|
312
|
+
* threeDaysFromToday.setDate(threeDaysFromToday.getDate() + 3);
|
|
313
|
+
* threeDaysFromToday.setHours(23, 59, 59, 999);
|
|
314
|
+
*
|
|
212
315
|
* createApiKey({
|
|
213
316
|
* title: "xyz_title",
|
|
214
317
|
* description: "xyz_desc",
|
|
215
318
|
* tags: ["xyz_tag1", "xyz_tag2"],
|
|
216
|
-
* privileges: [
|
|
217
|
-
* authentication: authSession
|
|
319
|
+
* privileges: ["premium:user:networkanalysis:routing"],
|
|
320
|
+
* authentication: authSession,
|
|
321
|
+
* generateToken1: true, // optional,generate a new token
|
|
322
|
+
* apiToken1ExpirationDate: threeDaysFromToday // optional, update expiration date
|
|
218
323
|
* }).then((registeredAPIKey: IApiKeyResponse) => {
|
|
219
|
-
* // => {
|
|
324
|
+
* // => {accessToken1: "xyz_key", item: {tags: ["xyz_tag1", "xyz_tag2"], ...}, ...}
|
|
220
325
|
* }).catch(e => {
|
|
221
326
|
* // => an exception object
|
|
222
327
|
* });
|
|
@@ -226,9 +331,6 @@
|
|
|
226
331
|
* @returns A Promise that will resolve to an {@linkcode IApiKeyResponse} object representing the newly registered API key.
|
|
227
332
|
*/
|
|
228
333
|
async function createApiKey(requestOptions) {
|
|
229
|
-
if (!arePrivilegesValid(requestOptions.privileges)) {
|
|
230
|
-
throw new Error("The `privileges` option contains invalid privileges.");
|
|
231
|
-
}
|
|
232
334
|
requestOptions.httpMethod = "POST";
|
|
233
335
|
// filter param buckets:
|
|
234
336
|
const baseRequestOptions = extractBaseRequestOptions(requestOptions); // snapshot of basic IRequestOptions before customized params being built into it
|
|
@@ -248,52 +350,37 @@
|
|
|
248
350
|
"typeKeywords",
|
|
249
351
|
"url"
|
|
250
352
|
];
|
|
251
|
-
|
|
252
|
-
|
|
353
|
+
/**
|
|
354
|
+
* step 1: create item
|
|
355
|
+
*/
|
|
356
|
+
const createItemOption = Object.assign(Object.assign({ item: Object.assign(Object.assign({}, filterKeys(requestOptions, itemAddProperties)), { type: "Application" }) }, baseRequestOptions), { authentication: requestOptions.authentication, params: {
|
|
253
357
|
f: "json"
|
|
254
358
|
} });
|
|
255
359
|
const createItemResponse = await arcgisRestPortal.createItem(createItemOption);
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
360
|
+
/**
|
|
361
|
+
* getRegisteredAppInfoRoute
|
|
362
|
+
*/
|
|
363
|
+
const registerAppOptions = Object.assign(Object.assign({ itemId: createItemResponse.id, appType: "multiple", redirect_uris: ["urn:ietf:wg:oauth:2.0:oob"], httpReferrers: requestOptions.httpReferrers || [], privileges: requestOptions.privileges }, baseRequestOptions), { authentication: requestOptions.authentication });
|
|
364
|
+
const registeredAppResponse = await registerApp(registerAppOptions);
|
|
365
|
+
/**
|
|
366
|
+
* step 3: update item with desired expiration dates
|
|
367
|
+
* you cannot set the expiration date propierties until you
|
|
368
|
+
* regiester the app so this has to be a seperate step
|
|
369
|
+
*/
|
|
370
|
+
await arcgisRestPortal.updateItem(Object.assign(Object.assign({}, baseRequestOptions), { item: Object.assign({ id: createItemResponse.id }, buildExpirationDateParams(requestOptions, true)), authentication: requestOptions.authentication }));
|
|
371
|
+
/*
|
|
372
|
+
* step 4: get item info
|
|
373
|
+
*/
|
|
259
374
|
const itemInfo = await arcgisRestPortal.getItem(registeredAppResponse.itemId, Object.assign(Object.assign({}, baseRequestOptions), { authentication: requestOptions.authentication, params: { f: "json" } }));
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
* import { getRegisteredAppInfo, IApp } from '@esri/arcgis-rest-developer-credentials';
|
|
270
|
-
* import { ArcGISIdentityManager } from "@esri/arcgis-rest-request";
|
|
271
|
-
*
|
|
272
|
-
* const authSession: ArcGISIdentityManager = await ArcGISIdentityManager.signIn({
|
|
273
|
-
* username: "xyz_usrName",
|
|
274
|
-
* password: "xyz_pw"
|
|
275
|
-
* });
|
|
276
|
-
*
|
|
277
|
-
* getRegisteredAppInfo({
|
|
278
|
-
* itemId: "xyz_itemId",
|
|
279
|
-
* authentication: authSession
|
|
280
|
-
* }).then((registeredApp: IApp) => {
|
|
281
|
-
* // => {client_id: "xyz_id", client_secret: "xyz_secret", ...}
|
|
282
|
-
* }).catch(e => {
|
|
283
|
-
* // => an exception object
|
|
284
|
-
* });
|
|
285
|
-
* ```
|
|
286
|
-
*
|
|
287
|
-
* @param requestOptions - Options for {@linkcode getRegisteredAppInfo | getRegisteredAppInfo()}, including an itemId of which app to retrieve and an {@linkcode ArcGISIdentityManager} authentication session.
|
|
288
|
-
* @returns A Promise that will resolve to an {@linkcode IApp} object representing successfully retrieved app.
|
|
289
|
-
*/
|
|
290
|
-
async function getRegisteredAppInfo(requestOptions) {
|
|
291
|
-
const userName = await requestOptions.authentication.getUsername();
|
|
292
|
-
const url = arcgisRestPortal.getPortalUrl(requestOptions) +
|
|
293
|
-
`/content/users/${userName}/items/${requestOptions.itemId}/registeredAppInfo`;
|
|
294
|
-
requestOptions.httpMethod = "POST";
|
|
295
|
-
const registeredAppResponse = await arcgisRestRequest.request(url, Object.assign(Object.assign({}, requestOptions), { params: { f: "json" } }));
|
|
296
|
-
return registeredAppResponseToApp(registeredAppResponse);
|
|
375
|
+
/**
|
|
376
|
+
* step 5: generate tokens if requested
|
|
377
|
+
*/
|
|
378
|
+
const generatedTokens = await generateApiKeyTokens(itemInfo.id, generateOptionsToSlots(requestOptions.generateToken1, requestOptions.generateToken2), Object.assign(Object.assign({}, baseRequestOptions), { authentication: requestOptions.authentication }));
|
|
379
|
+
/**
|
|
380
|
+
* step 6: get registered app info to get updated active key status
|
|
381
|
+
*/
|
|
382
|
+
const updatedRegisteredAppResponse = await getRegisteredAppInfo(Object.assign(Object.assign({}, baseRequestOptions), { itemId: itemInfo.id, authentication: requestOptions.authentication }));
|
|
383
|
+
return Object.assign(Object.assign(Object.assign({}, generatedTokens), appToApiKeyProperties(updatedRegisteredAppResponse)), { item: itemInfo });
|
|
297
384
|
}
|
|
298
385
|
|
|
299
386
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
@@ -314,13 +401,19 @@
|
|
|
314
401
|
* password: "xyz_pw"
|
|
315
402
|
* });
|
|
316
403
|
*
|
|
404
|
+
* const threeDaysFromToday = new Date();
|
|
405
|
+
* threeDaysFromToday.setDate(threeDaysFromToday.getDate() + 3);
|
|
406
|
+
* threeDaysFromToday.setHours(23, 59, 59, 999);
|
|
407
|
+
*
|
|
317
408
|
* updateApiKey({
|
|
318
409
|
* itemId: "xyz_itemId",
|
|
319
|
-
* privileges: [
|
|
410
|
+
* privileges: ["premium:user:geocode:temporary"],
|
|
320
411
|
* httpReferrers: [], // httpReferrers will be set to be empty
|
|
321
412
|
* authentication: authSession
|
|
413
|
+
* generateToken1: true, // optional,generate a new token
|
|
414
|
+
* apiToken1ExpirationDate: threeDaysFromToday // optional, update expiration date
|
|
322
415
|
* }).then((updatedAPIKey: IApiKeyResponse) => {
|
|
323
|
-
* // => {
|
|
416
|
+
* // => {accessToken1: "xyz_key", item: {tags: ["xyz_tag1", "xyz_tag2"], ...}, ...}
|
|
324
417
|
* }).catch(e => {
|
|
325
418
|
* // => an exception object
|
|
326
419
|
* });
|
|
@@ -330,33 +423,46 @@
|
|
|
330
423
|
* @returns A Promise that will resolve to an {@linkcode IApiKeyResponse} object representing updated API key.
|
|
331
424
|
*/
|
|
332
425
|
async function updateApiKey(requestOptions) {
|
|
333
|
-
// privileges validation
|
|
334
|
-
if (requestOptions.privileges &&
|
|
335
|
-
!arePrivilegesValid(requestOptions.privileges)) {
|
|
336
|
-
throw new Error("The `privileges` option contains invalid privileges.");
|
|
337
|
-
}
|
|
338
426
|
requestOptions.httpMethod = "POST";
|
|
339
|
-
// get app
|
|
340
427
|
const baseRequestOptions = extractBaseRequestOptions(requestOptions); // get base requestOptions snapshot
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (
|
|
345
|
-
|
|
428
|
+
/**
|
|
429
|
+
* step 1: update expiration dates if provided. Build the object up to avoid overwriting any existing properties.
|
|
430
|
+
*/
|
|
431
|
+
if (requestOptions.apiToken1ExpirationDate ||
|
|
432
|
+
requestOptions.apiToken2ExpirationDate) {
|
|
433
|
+
const updateParams = buildExpirationDateParams(requestOptions);
|
|
434
|
+
await arcgisRestPortal.updateItem(Object.assign(Object.assign({}, baseRequestOptions), { item: Object.assign({ id: requestOptions.itemId }, updateParams), authentication: requestOptions.authentication }));
|
|
346
435
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
436
|
+
/**
|
|
437
|
+
* step 2: update privileges and httpReferrers if provided. Build the object up to avoid overwriting any existing properties.
|
|
438
|
+
*/
|
|
439
|
+
if (requestOptions.privileges || requestOptions.httpReferrers) {
|
|
440
|
+
const getAppOption = Object.assign(Object.assign({}, baseRequestOptions), { authentication: requestOptions.authentication, itemId: requestOptions.itemId });
|
|
441
|
+
const appResponse = await getRegisteredAppInfo(getAppOption);
|
|
442
|
+
const clientId = appResponse.client_id;
|
|
443
|
+
const options = arcgisRestRequest.appendCustomParams(Object.assign(Object.assign({}, appResponse), requestOptions), // object with the custom params to look in
|
|
444
|
+
["privileges", "httpReferrers"] // keys you want copied to the params object
|
|
445
|
+
);
|
|
446
|
+
options.params.f = "json";
|
|
447
|
+
// encode special params value (e.g. array type...) in advance in order to make encodeQueryString() works correctly
|
|
448
|
+
stringifyArrays(options);
|
|
449
|
+
const url = arcgisRestPortal.getPortalUrl(options) + `/oauth2/apps/${clientId}/update`;
|
|
450
|
+
// Raw response from `/oauth2/apps/${clientId}/update`, apiKey not included because key is same.
|
|
451
|
+
await arcgisRestRequest.request(url, Object.assign(Object.assign({}, options), { authentication: requestOptions.authentication }));
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* step 3: get the updated item info to return to the user.
|
|
455
|
+
*/
|
|
456
|
+
const updatedItemInfo = await arcgisRestPortal.getItem(requestOptions.itemId, Object.assign(Object.assign({}, baseRequestOptions), { authentication: requestOptions.authentication, params: { f: "json" } }));
|
|
457
|
+
/**
|
|
458
|
+
* step 4: generate tokens if requested
|
|
459
|
+
*/
|
|
460
|
+
const generatedTokens = await generateApiKeyTokens(requestOptions.itemId, generateOptionsToSlots(requestOptions.generateToken1, requestOptions.generateToken2), Object.assign(Object.assign({}, baseRequestOptions), { authentication: requestOptions.authentication }));
|
|
461
|
+
/**
|
|
462
|
+
* step 5: get updated registered app info
|
|
463
|
+
*/
|
|
464
|
+
const updatedRegisteredAppResponse = await getRegisteredAppInfo(Object.assign(Object.assign({}, baseRequestOptions), { itemId: requestOptions.itemId, authentication: requestOptions.authentication }));
|
|
465
|
+
return Object.assign(Object.assign(Object.assign({}, generatedTokens), appToApiKeyProperties(updatedRegisteredAppResponse)), { item: updatedItemInfo });
|
|
360
466
|
}
|
|
361
467
|
|
|
362
468
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
@@ -395,37 +501,39 @@
|
|
|
395
501
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
396
502
|
* Apache-2.0 */
|
|
397
503
|
/**
|
|
398
|
-
* Used to
|
|
504
|
+
* Used to invalidate an API key.
|
|
399
505
|
*
|
|
400
506
|
* ```js
|
|
401
|
-
* import {
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
* })
|
|
408
|
-
*
|
|
409
|
-
* deleteApiKey({
|
|
410
|
-
* itemId: "xyz_itemId",
|
|
411
|
-
* authentication: authSession
|
|
412
|
-
* }).then((deletedApiKey: IDeleteApiKeyResponse) => {
|
|
413
|
-
* // => {itemId: "xyz_itemId", success: true}
|
|
507
|
+
* import { invalidateApiKey } from "@esri/arcgis-rest-developer-credentials";
|
|
508
|
+
*
|
|
509
|
+
* invalidateApiKey({
|
|
510
|
+
* itemId: ITEM_ID,
|
|
511
|
+
* authentication,
|
|
512
|
+
* apiKey: 1, // invalidate the key in slot 1
|
|
513
|
+
* }).then((response) => {
|
|
514
|
+
* // => {success: true}
|
|
414
515
|
* }).catch(e => {
|
|
415
516
|
* // => an exception object
|
|
416
517
|
* });
|
|
417
|
-
* ```
|
|
418
|
-
*
|
|
419
|
-
* @param requestOptions - Options for {@linkcode deleteApiKey | deleteApiKey()}, including `itemId` of which API key to be deleted and an {@linkcode ArcGISIdentityManager} authentication session.
|
|
420
|
-
* @returns A Promise that will resolve to an {@linkcode IDeleteApiKeyResponse} object representing deletion status.
|
|
421
518
|
*/
|
|
422
|
-
async function
|
|
423
|
-
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
519
|
+
async function invalidateApiKey(requestOptions) {
|
|
520
|
+
const portal = arcgisRestPortal.getPortalUrl(requestOptions);
|
|
521
|
+
const url = `${portal}/oauth2/revokeToken`;
|
|
522
|
+
const appInfo = await getRegisteredAppInfo({
|
|
523
|
+
itemId: requestOptions.itemId,
|
|
524
|
+
authentication: requestOptions.authentication
|
|
525
|
+
});
|
|
526
|
+
const params = {
|
|
527
|
+
client_id: appInfo.client_id,
|
|
528
|
+
client_secret: appInfo.client_secret,
|
|
529
|
+
apiToken: slotForInvalidationKey(requestOptions.apiKey),
|
|
530
|
+
regenerateApiToken: true,
|
|
531
|
+
grant_type: "client_credentials"
|
|
532
|
+
};
|
|
533
|
+
// authentication is not being passed to the request because client_secret acts as the auth
|
|
534
|
+
return arcgisRestRequest.request(url, {
|
|
535
|
+
params
|
|
536
|
+
});
|
|
429
537
|
}
|
|
430
538
|
|
|
431
539
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
@@ -461,42 +569,6 @@
|
|
|
461
569
|
return Object.assign(Object.assign({}, appToOAuthAppProperties(appResponse)), { item: itemInfo });
|
|
462
570
|
}
|
|
463
571
|
|
|
464
|
-
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
465
|
-
* Apache-2.0 */
|
|
466
|
-
/**
|
|
467
|
-
* Used to delete the OAuth2.0 app with given `itemId`.
|
|
468
|
-
*
|
|
469
|
-
* ```js
|
|
470
|
-
* import { deleteOAuthApp, IDeleteOAuthAppResponse } from '@esri/arcgis-rest-developer-credentials';
|
|
471
|
-
* import { ArcGISIdentityManager } from "@esri/arcgis-rest-request";
|
|
472
|
-
*
|
|
473
|
-
* const authSession: ArcGISIdentityManager = await ArcGISIdentityManager.signIn({
|
|
474
|
-
* username: "xyz_usrName",
|
|
475
|
-
* password: "xyz_pw"
|
|
476
|
-
* });
|
|
477
|
-
*
|
|
478
|
-
* deleteOAuthApp({
|
|
479
|
-
* itemId: "xyz_itemId",
|
|
480
|
-
* authentication: authSession
|
|
481
|
-
* }).then((deletedOAuthApp: IDeleteOAuthAppResponse) => {
|
|
482
|
-
* // => {itemId: "xyz_itemId", success: true}
|
|
483
|
-
* }).catch(e => {
|
|
484
|
-
* // => an exception object
|
|
485
|
-
* });
|
|
486
|
-
* ```
|
|
487
|
-
*
|
|
488
|
-
* @param requestOptions - Options for {@linkcode deleteOAuthApp | deleteOAuthApp()}, including `itemId` of which OAuth app to be deleted and an {@linkcode ArcGISIdentityManager} authentication session.
|
|
489
|
-
* @returns A Promise that will resolve to an {@linkcode IDeleteOAuthAppResponse} object representing deletion status.
|
|
490
|
-
*/
|
|
491
|
-
async function deleteOAuthApp(requestOptions) {
|
|
492
|
-
requestOptions.httpMethod = "POST";
|
|
493
|
-
const baseRequestOptions = extractBaseRequestOptions(requestOptions);
|
|
494
|
-
// validate provided itemId associates with OAuth app
|
|
495
|
-
await getOAuthApp(Object.assign(Object.assign({}, baseRequestOptions), { itemId: requestOptions.itemId, authentication: requestOptions.authentication }));
|
|
496
|
-
const removeItemResponse = await arcgisRestPortal.removeItem(Object.assign(Object.assign({}, baseRequestOptions), { id: requestOptions.itemId, authentication: requestOptions.authentication, params: { f: "json" } }));
|
|
497
|
-
return removeItemResponse;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
572
|
/* Copyright (c) 2023 Environmental Systems Research Institute, Inc.
|
|
501
573
|
* Apache-2.0 */
|
|
502
574
|
/**
|
|
@@ -655,18 +727,21 @@
|
|
|
655
727
|
|
|
656
728
|
exports.appToApiKeyProperties = appToApiKeyProperties;
|
|
657
729
|
exports.appToOAuthAppProperties = appToOAuthAppProperties;
|
|
658
|
-
exports.
|
|
730
|
+
exports.buildExpirationDateParams = buildExpirationDateParams;
|
|
659
731
|
exports.createApiKey = createApiKey;
|
|
660
732
|
exports.createOAuthApp = createOAuthApp;
|
|
661
|
-
exports.deleteApiKey = deleteApiKey;
|
|
662
|
-
exports.deleteOAuthApp = deleteOAuthApp;
|
|
663
733
|
exports.extractBaseRequestOptions = extractBaseRequestOptions;
|
|
664
734
|
exports.filterKeys = filterKeys;
|
|
735
|
+
exports.generateApiKeyTokens = generateApiKeyTokens;
|
|
736
|
+
exports.generateOptionsToSlots = generateOptionsToSlots;
|
|
665
737
|
exports.getApiKey = getApiKey;
|
|
666
738
|
exports.getOAuthApp = getOAuthApp;
|
|
667
739
|
exports.getRegisteredAppInfo = getRegisteredAppInfo;
|
|
740
|
+
exports.invalidateApiKey = invalidateApiKey;
|
|
668
741
|
exports.registerApp = registerApp;
|
|
669
742
|
exports.registeredAppResponseToApp = registeredAppResponseToApp;
|
|
743
|
+
exports.slotForInvalidationKey = slotForInvalidationKey;
|
|
744
|
+
exports.slotForKey = slotForKey;
|
|
670
745
|
exports.stringifyArrays = stringifyArrays;
|
|
671
746
|
exports.unregisterApp = unregisterApp;
|
|
672
747
|
exports.updateApiKey = updateApiKey;
|