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