autnam 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (490) hide show
  1. package/.env.example +2 -0
  2. package/.eslintrc.json +37 -0
  3. package/.github/workflows/deploy-docs.yml +27 -0
  4. package/.github/workflows/pre-release-tests.yml +49 -0
  5. package/.github/workflows/pull-request-tests.yml +49 -0
  6. package/.github/workflows/release.yml +75 -0
  7. package/.prettierignore +2 -0
  8. package/.prettierrc +19 -0
  9. package/.vscode/launch.json +25 -0
  10. package/.vscode/settings.json +5 -0
  11. package/codecov.yml +7 -0
  12. package/commitlint.config.cjs +41 -0
  13. package/demos/.eslintrc.js +13 -0
  14. package/demos/ago-node-cli/README.md +30 -0
  15. package/demos/ago-node-cli/ago.js +31 -0
  16. package/demos/ago-node-cli/index.js +11 -0
  17. package/demos/ago-node-cli/lib/item-export-command.js +48 -0
  18. package/demos/ago-node-cli/lib/item-search-command.js +32 -0
  19. package/demos/ago-node-cli/package.json +29 -0
  20. package/demos/attachments-browser/README.md +7 -0
  21. package/demos/attachments-browser/index.html +165 -0
  22. package/demos/attachments-browser/package.json +15 -0
  23. package/demos/attachments-node/README.md +4 -0
  24. package/demos/attachments-node/image.jpg +0 -0
  25. package/demos/attachments-node/index.js +89 -0
  26. package/demos/attachments-node/package.json +19 -0
  27. package/demos/batch-geocoder-node/NYC_Restaurant_Inspection_Results.csv +100 -0
  28. package/demos/batch-geocoder-node/README.md +13 -0
  29. package/demos/batch-geocoder-node/batch-geocode.js +112 -0
  30. package/demos/batch-geocoder-node/config-template.js +18 -0
  31. package/demos/batch-geocoder-node/package.json +34 -0
  32. package/demos/browser-es-modules/README.md +7 -0
  33. package/demos/browser-es-modules/index.html +38 -0
  34. package/demos/browser-es-modules/package.json +15 -0
  35. package/demos/deno/README.md +1 -0
  36. package/demos/deno/import_map.json +8 -0
  37. package/demos/deno/index.js +5 -0
  38. package/demos/express/README.md +16 -0
  39. package/demos/express/config.json.template +3 -0
  40. package/demos/express/package.json +15 -0
  41. package/demos/express/server.js +37 -0
  42. package/demos/feature-service-browser/README.md +8 -0
  43. package/demos/feature-service-browser/index.html +122 -0
  44. package/demos/feature-service-browser/package.json +15 -0
  45. package/demos/geocoder-browser/README.md +12 -0
  46. package/demos/geocoder-browser/authenticate.html +29 -0
  47. package/demos/geocoder-browser/config.js.template +1 -0
  48. package/demos/geocoder-browser/index.html +139 -0
  49. package/demos/geocoder-browser/package.json +15 -0
  50. package/demos/jsapi-integration/README.md +26 -0
  51. package/demos/jsapi-integration/authenticate.html +29 -0
  52. package/demos/jsapi-integration/config.js +6 -0
  53. package/demos/jsapi-integration/index.html +91 -0
  54. package/demos/jsapi-integration/package.json +15 -0
  55. package/demos/node-cli-item-management/README.md +11 -0
  56. package/demos/node-cli-item-management/index.js +229 -0
  57. package/demos/node-cli-item-management/package.json +24 -0
  58. package/demos/node-cli-item-management/screenshot.png +0 -0
  59. package/demos/node-common-js/README.md +4 -0
  60. package/demos/node-common-js/index.js +5 -0
  61. package/demos/node-common-js/package.json +15 -0
  62. package/demos/node-es-modules/README.md +4 -0
  63. package/demos/node-es-modules/index.js +5 -0
  64. package/demos/node-es-modules/package.json +16 -0
  65. package/demos/oauth2-browser/README.md +17 -0
  66. package/demos/oauth2-browser/authenticate.html +29 -0
  67. package/demos/oauth2-browser/config.js.template +6 -0
  68. package/demos/oauth2-browser/index.html +223 -0
  69. package/demos/oauth2-browser/logo.svg +4 -0
  70. package/demos/oauth2-browser/package.json +15 -0
  71. package/demos/oauth2-browser/style.css +36 -0
  72. package/demos/oauth2-browser-retry/README.md +32 -0
  73. package/demos/oauth2-browser-retry/authenticate.html +21 -0
  74. package/demos/oauth2-browser-retry/index.html +114 -0
  75. package/demos/oauth2-browser-retry/logo.svg +4 -0
  76. package/demos/oauth2-browser-retry/package.json +15 -0
  77. package/demos/parcel/README.md +8 -0
  78. package/demos/parcel/index.html +16 -0
  79. package/demos/parcel/index.js +8 -0
  80. package/demos/parcel/package.json +20 -0
  81. package/demos/snowpack/README.md +8 -0
  82. package/demos/snowpack/index.html +16 -0
  83. package/demos/snowpack/index.js +8 -0
  84. package/demos/snowpack/package.json +20 -0
  85. package/demos/snowpack/snowpack.config.js +3 -0
  86. package/demos/stream-response-to-file/README.md +7 -0
  87. package/demos/stream-response-to-file/index.js +36 -0
  88. package/demos/stream-response-to-file/output/.gitkeep +0 -0
  89. package/demos/stream-response-to-file/package.json +31 -0
  90. package/demos/tree-shaking-rollup/.babelrc +3 -0
  91. package/demos/tree-shaking-rollup/README.md +9 -0
  92. package/demos/tree-shaking-rollup/index.html +11 -0
  93. package/demos/tree-shaking-rollup/package.json +22 -0
  94. package/demos/tree-shaking-rollup/rollup.config.js +13 -0
  95. package/demos/tree-shaking-rollup/src/index.js +8 -0
  96. package/demos/tree-shaking-webpack/README.md +9 -0
  97. package/demos/tree-shaking-webpack/index.html +11 -0
  98. package/demos/tree-shaking-webpack/package.json +26 -0
  99. package/demos/tree-shaking-webpack/src/index.js +8 -0
  100. package/demos/tree-shaking-webpack/webpack.config.js +29 -0
  101. package/demos/vite/README.md +6 -0
  102. package/demos/vite/favicon.svg +15 -0
  103. package/demos/vite/index.html +13 -0
  104. package/demos/vite/main.js +8 -0
  105. package/demos/vite/package.json +18 -0
  106. package/demos/vue/.env.example +11 -0
  107. package/demos/vue/.eslintrc.js +17 -0
  108. package/demos/vue/.postcssrc.js +5 -0
  109. package/demos/vue/README.md +17 -0
  110. package/demos/vue/babel.config.js +3 -0
  111. package/demos/vue/package.json +35 -0
  112. package/demos/vue/public/favicon.ico +0 -0
  113. package/demos/vue/public/index.html +24 -0
  114. package/demos/vue/src/assets/logo.svg +29 -0
  115. package/demos/vue/src/components/App.vue +303 -0
  116. package/demos/vue/src/components/Authenticate.vue +65 -0
  117. package/demos/vue/src/components/Loader.vue +230 -0
  118. package/demos/vue/src/main.js +92 -0
  119. package/demos/webmap-checker-sapper/.env.example +5 -0
  120. package/demos/webmap-checker-sapper/README.md +124 -0
  121. package/demos/webmap-checker-sapper/appveyor.yml +18 -0
  122. package/demos/webmap-checker-sapper/cypress/fixtures/example.json +5 -0
  123. package/demos/webmap-checker-sapper/cypress/integration/spec.js +19 -0
  124. package/demos/webmap-checker-sapper/cypress/plugins/index.js +17 -0
  125. package/demos/webmap-checker-sapper/cypress/support/commands.js +25 -0
  126. package/demos/webmap-checker-sapper/cypress/support/index.js +20 -0
  127. package/demos/webmap-checker-sapper/cypress.json +4 -0
  128. package/demos/webmap-checker-sapper/package.json +47 -0
  129. package/demos/webmap-checker-sapper/rollup.config.js +87 -0
  130. package/demos/webmap-checker-sapper/src/client.js +20 -0
  131. package/demos/webmap-checker-sapper/src/components/LayerStatus.html +108 -0
  132. package/demos/webmap-checker-sapper/src/components/Nav.html +21 -0
  133. package/demos/webmap-checker-sapper/src/components/WebMap.html +62 -0
  134. package/demos/webmap-checker-sapper/src/routes/_error.html +41 -0
  135. package/demos/webmap-checker-sapper/src/routes/_layout.html +21 -0
  136. package/demos/webmap-checker-sapper/src/routes/auth/authorize.js +18 -0
  137. package/demos/webmap-checker-sapper/src/routes/auth/exchange-token.js +20 -0
  138. package/demos/webmap-checker-sapper/src/routes/auth/post-sign-in.js +24 -0
  139. package/demos/webmap-checker-sapper/src/routes/auth/sign-out.js +10 -0
  140. package/demos/webmap-checker-sapper/src/routes/index.html +20 -0
  141. package/demos/webmap-checker-sapper/src/routes/webmaps/[webmapId].html +83 -0
  142. package/demos/webmap-checker-sapper/src/routes/webmaps/index.html +59 -0
  143. package/demos/webmap-checker-sapper/src/server.js +102 -0
  144. package/demos/webmap-checker-sapper/src/service-worker.js +82 -0
  145. package/demos/webmap-checker-sapper/src/template.html +33 -0
  146. package/demos/webmap-checker-sapper/src/userInfoMiddleware.js +21 -0
  147. package/demos/webmap-checker-sapper/src/utils.js +33 -0
  148. package/demos/webmap-checker-sapper/static/favicon.png +0 -0
  149. package/demos/webmap-checker-sapper/static/global.css +36 -0
  150. package/demos/webmap-checker-sapper/static/manifest.json +20 -0
  151. package/demos/webmap-checker-sapper/static/svelte-logo-192.png +0 -0
  152. package/demos/webmap-checker-sapper/static/svelte-logo-512.png +0 -0
  153. package/docs/.eslintrc.js +12 -0
  154. package/docs/FAQ.md +48 -0
  155. package/docs/HISTORY.md +62 -0
  156. package/docs/acetate.config.js +262 -0
  157. package/docs/build-typedoc.js +434 -0
  158. package/docs/generate-srihashes.js +61 -0
  159. package/docs/package.json +3 -0
  160. package/docs/src/_layout.html +86 -0
  161. package/docs/src/api/_declaration.html +600 -0
  162. package/docs/src/api/_layout.html +204 -0
  163. package/docs/src/api/_package.html +38 -0
  164. package/docs/src/api/index.html +16 -0
  165. package/docs/src/guides/_layout.html +24 -0
  166. package/docs/src/guides/amd-requirejs-dojo.md +40 -0
  167. package/docs/src/guides/browser-authentication.md +39 -0
  168. package/docs/src/guides/bundlers.md +52 -0
  169. package/docs/src/guides/cli-authentication.md +9 -0
  170. package/docs/src/guides/client-server-authentication.md +9 -0
  171. package/docs/src/guides/embedded-apps.md +106 -0
  172. package/docs/src/guides/from-a-cdn.md +38 -0
  173. package/docs/src/guides/index.md +59 -0
  174. package/docs/src/guides/node.md +84 -0
  175. package/docs/src/guides/package-overview.md +111 -0
  176. package/docs/src/guides/server-authentication.md +9 -0
  177. package/docs/src/guides/whats-new-v2-0.md +305 -0
  178. package/docs/src/img/icons.png +0 -0
  179. package/docs/src/img/icons@2x.png +0 -0
  180. package/docs/src/img/oauth-browser.png +0 -0
  181. package/docs/src/index.html +12 -0
  182. package/docs/src/js/api-search.js +112 -0
  183. package/docs/src/js/nav-toggle.js +41 -0
  184. package/docs/src/sass/_highlight.scss +96 -0
  185. package/docs/src/sass/_icons.scss +157 -0
  186. package/docs/src/sass/style.scss +242 -0
  187. package/jasmine.json +7 -0
  188. package/jasmine.live.json +7 -0
  189. package/karma.conf.cjs +128 -0
  190. package/package.json +87 -0
  191. package/packages/arcgis-rest-auth/CHANGELOG.md +80 -0
  192. package/packages/arcgis-rest-auth/README.md +71 -0
  193. package/packages/arcgis-rest-auth/package.json +66 -0
  194. package/packages/arcgis-rest-auth/src/index.ts +34 -0
  195. package/packages/arcgis-rest-auth/tsconfig.json +6 -0
  196. package/packages/arcgis-rest-demographics/CHANGELOG.md +14 -0
  197. package/packages/arcgis-rest-demographics/README.md +74 -0
  198. package/packages/arcgis-rest-demographics/package.json +69 -0
  199. package/packages/arcgis-rest-demographics/src/getAvailableCountries.ts +113 -0
  200. package/packages/arcgis-rest-demographics/src/getAvailableDataCollections.ts +161 -0
  201. package/packages/arcgis-rest-demographics/src/getAvailableGeographyLevels.ts +86 -0
  202. package/packages/arcgis-rest-demographics/src/getGeography.ts +152 -0
  203. package/packages/arcgis-rest-demographics/src/helpers.ts +27 -0
  204. package/packages/arcgis-rest-demographics/src/index.ts +16 -0
  205. package/packages/arcgis-rest-demographics/src/queryDemographicData.ts +108 -0
  206. package/packages/arcgis-rest-demographics/test/getAvailableCountries.test.ts +89 -0
  207. package/packages/arcgis-rest-demographics/test/getAvailableDataCollections.test.ts +114 -0
  208. package/packages/arcgis-rest-demographics/test/getAvailableGeographyLevels.test.ts +69 -0
  209. package/packages/arcgis-rest-demographics/test/getGeography.test.ts +150 -0
  210. package/packages/arcgis-rest-demographics/test/mocks/responses.ts +4 -0
  211. package/packages/arcgis-rest-demographics/test/queryDemographicData.test.live.ts +50 -0
  212. package/packages/arcgis-rest-demographics/test/queryDemographicData.test.ts +127 -0
  213. package/packages/arcgis-rest-demographics/tsconfig.json +6 -0
  214. package/packages/arcgis-rest-feature-service/CHANGELOG.md +44 -0
  215. package/packages/arcgis-rest-feature-service/README.md +75 -0
  216. package/packages/arcgis-rest-feature-service/package.json +70 -0
  217. package/packages/arcgis-rest-feature-service/src/add.ts +55 -0
  218. package/packages/arcgis-rest-feature-service/src/addAttachment.ts +53 -0
  219. package/packages/arcgis-rest-feature-service/src/addToServiceDefinition.ts +74 -0
  220. package/packages/arcgis-rest-feature-service/src/applyEdits.ts +94 -0
  221. package/packages/arcgis-rest-feature-service/src/createFeatureService.ts +191 -0
  222. package/packages/arcgis-rest-feature-service/src/decodeValues.ts +126 -0
  223. package/packages/arcgis-rest-feature-service/src/delete.ts +62 -0
  224. package/packages/arcgis-rest-feature-service/src/deleteAttachments.ts +52 -0
  225. package/packages/arcgis-rest-feature-service/src/getAllLayersAndTables.ts +30 -0
  226. package/packages/arcgis-rest-feature-service/src/getAttachments.ts +55 -0
  227. package/packages/arcgis-rest-feature-service/src/getLayer.ts +23 -0
  228. package/packages/arcgis-rest-feature-service/src/getService.ts +25 -0
  229. package/packages/arcgis-rest-feature-service/src/getServiceAdminInfo.ts +33 -0
  230. package/packages/arcgis-rest-feature-service/src/getViewSources.ts +19 -0
  231. package/packages/arcgis-rest-feature-service/src/helpers.ts +768 -0
  232. package/packages/arcgis-rest-feature-service/src/index.ts +37 -0
  233. package/packages/arcgis-rest-feature-service/src/query.ts +200 -0
  234. package/packages/arcgis-rest-feature-service/src/queryRelated.ts +86 -0
  235. package/packages/arcgis-rest-feature-service/src/update.ts +65 -0
  236. package/packages/arcgis-rest-feature-service/src/updateAttachment.ts +59 -0
  237. package/packages/arcgis-rest-feature-service/src/updateServiceDefinition.ts +53 -0
  238. package/packages/arcgis-rest-feature-service/test/addToServiceDefinition.test.ts +350 -0
  239. package/packages/arcgis-rest-feature-service/test/attachments.test.ts +188 -0
  240. package/packages/arcgis-rest-feature-service/test/createFeatureService.test.ts +279 -0
  241. package/packages/arcgis-rest-feature-service/test/crud.test.ts +196 -0
  242. package/packages/arcgis-rest-feature-service/test/decodeValues.test.ts +66 -0
  243. package/packages/arcgis-rest-feature-service/test/getAllLayersAndTables.test.ts +27 -0
  244. package/packages/arcgis-rest-feature-service/test/getLayer.test.ts +30 -0
  245. package/packages/arcgis-rest-feature-service/test/getService.test.ts +30 -0
  246. package/packages/arcgis-rest-feature-service/test/getServiceAdminInfo.test.ts +41 -0
  247. package/packages/arcgis-rest-feature-service/test/getViewSources.test.ts +45 -0
  248. package/packages/arcgis-rest-feature-service/test/helpers.test.ts +27 -0
  249. package/packages/arcgis-rest-feature-service/test/mocks/allLayersAndTablesResponse.ts +950 -0
  250. package/packages/arcgis-rest-feature-service/test/mocks/cvdQueryResponse.ts +225 -0
  251. package/packages/arcgis-rest-feature-service/test/mocks/feature.ts +302 -0
  252. package/packages/arcgis-rest-feature-service/test/mocks/fields.ts +779 -0
  253. package/packages/arcgis-rest-feature-service/test/mocks/foo.txt +1 -0
  254. package/packages/arcgis-rest-feature-service/test/mocks/layerDefinition.ts +80 -0
  255. package/packages/arcgis-rest-feature-service/test/mocks/service.ts +476 -0
  256. package/packages/arcgis-rest-feature-service/test/query.test.ts +166 -0
  257. package/packages/arcgis-rest-feature-service/test/updateServiceDefinition.test.ts +103 -0
  258. package/packages/arcgis-rest-feature-service/tsconfig.json +9 -0
  259. package/packages/arcgis-rest-fetch/README.md +17 -0
  260. package/packages/arcgis-rest-fetch/browser-ponyfill.js +8 -0
  261. package/packages/arcgis-rest-fetch/browser-ponyfill.mjs +8 -0
  262. package/packages/arcgis-rest-fetch/index.types.d.ts +8 -0
  263. package/packages/arcgis-rest-fetch/node-ponyfill.js +10 -0
  264. package/packages/arcgis-rest-fetch/node-ponyfill.mjs +10 -0
  265. package/packages/arcgis-rest-fetch/package.json +21 -0
  266. package/packages/arcgis-rest-form-data/README.md +15 -0
  267. package/packages/arcgis-rest-form-data/browser-ponyfill.js +5 -0
  268. package/packages/arcgis-rest-form-data/browser-ponyfill.mjs +3 -0
  269. package/packages/arcgis-rest-form-data/index.types.d.ts +9 -0
  270. package/packages/arcgis-rest-form-data/node-ponyfill.js +7 -0
  271. package/packages/arcgis-rest-form-data/node-ponyfill.mjs +5 -0
  272. package/packages/arcgis-rest-form-data/package.json +21 -0
  273. package/packages/arcgis-rest-geocoding/CHANGELOG.md +26 -0
  274. package/packages/arcgis-rest-geocoding/README.md +85 -0
  275. package/packages/arcgis-rest-geocoding/package.json +69 -0
  276. package/packages/arcgis-rest-geocoding/src/bulk.ts +106 -0
  277. package/packages/arcgis-rest-geocoding/src/geocode.ts +169 -0
  278. package/packages/arcgis-rest-geocoding/src/helpers.ts +56 -0
  279. package/packages/arcgis-rest-geocoding/src/index.ts +17 -0
  280. package/packages/arcgis-rest-geocoding/src/reverse.ts +82 -0
  281. package/packages/arcgis-rest-geocoding/src/suggest.ts +45 -0
  282. package/packages/arcgis-rest-geocoding/test/bulk.test.ts +193 -0
  283. package/packages/arcgis-rest-geocoding/test/geocode.test.ts +254 -0
  284. package/packages/arcgis-rest-geocoding/test/helpers.test.ts +85 -0
  285. package/packages/arcgis-rest-geocoding/test/mocks/responses.ts +1031 -0
  286. package/packages/arcgis-rest-geocoding/test/reverse.test.ts +124 -0
  287. package/packages/arcgis-rest-geocoding/test/suggest.test.ts +53 -0
  288. package/packages/arcgis-rest-geocoding/tsconfig.json +6 -0
  289. package/packages/arcgis-rest-portal/CHANGELOG.md +73 -0
  290. package/packages/arcgis-rest-portal/README.md +72 -0
  291. package/packages/arcgis-rest-portal/package.json +68 -0
  292. package/packages/arcgis-rest-portal/src/groups/add-users.ts +140 -0
  293. package/packages/arcgis-rest-portal/src/groups/create.ts +42 -0
  294. package/packages/arcgis-rest-portal/src/groups/get.ts +187 -0
  295. package/packages/arcgis-rest-portal/src/groups/helpers.ts +14 -0
  296. package/packages/arcgis-rest-portal/src/groups/invite-users.ts +141 -0
  297. package/packages/arcgis-rest-portal/src/groups/join.ts +57 -0
  298. package/packages/arcgis-rest-portal/src/groups/notification.ts +77 -0
  299. package/packages/arcgis-rest-portal/src/groups/protect.ts +56 -0
  300. package/packages/arcgis-rest-portal/src/groups/remove-users.ts +84 -0
  301. package/packages/arcgis-rest-portal/src/groups/remove.ts +32 -0
  302. package/packages/arcgis-rest-portal/src/groups/search.ts +48 -0
  303. package/packages/arcgis-rest-portal/src/groups/update-user-membership.ts +63 -0
  304. package/packages/arcgis-rest-portal/src/groups/update.ts +39 -0
  305. package/packages/arcgis-rest-portal/src/helpers.ts +83 -0
  306. package/packages/arcgis-rest-portal/src/index.ts +68 -0
  307. package/packages/arcgis-rest-portal/src/items/add.ts +145 -0
  308. package/packages/arcgis-rest-portal/src/items/content.ts +70 -0
  309. package/packages/arcgis-rest-portal/src/items/create.ts +149 -0
  310. package/packages/arcgis-rest-portal/src/items/export.ts +92 -0
  311. package/packages/arcgis-rest-portal/src/items/get.ts +444 -0
  312. package/packages/arcgis-rest-portal/src/items/helpers.ts +272 -0
  313. package/packages/arcgis-rest-portal/src/items/protect.ts +41 -0
  314. package/packages/arcgis-rest-portal/src/items/reassign.ts +59 -0
  315. package/packages/arcgis-rest-portal/src/items/remove.ts +139 -0
  316. package/packages/arcgis-rest-portal/src/items/search.ts +25 -0
  317. package/packages/arcgis-rest-portal/src/items/update.ts +188 -0
  318. package/packages/arcgis-rest-portal/src/items/upload.ts +124 -0
  319. package/packages/arcgis-rest-portal/src/orgs/notification.ts +148 -0
  320. package/packages/arcgis-rest-portal/src/services/get-unique-service-name.ts +35 -0
  321. package/packages/arcgis-rest-portal/src/services/is-service-name-available.ts +29 -0
  322. package/packages/arcgis-rest-portal/src/sharing/access.ts +84 -0
  323. package/packages/arcgis-rest-portal/src/sharing/helpers.ts +80 -0
  324. package/packages/arcgis-rest-portal/src/sharing/is-item-shared-with-group.ts +42 -0
  325. package/packages/arcgis-rest-portal/src/sharing/share-item-with-group.ts +335 -0
  326. package/packages/arcgis-rest-portal/src/sharing/unshare-item-with-group.ts +114 -0
  327. package/packages/arcgis-rest-portal/src/users/get-user-tags.ts +52 -0
  328. package/packages/arcgis-rest-portal/src/users/get-user-url.ts +18 -0
  329. package/packages/arcgis-rest-portal/src/users/get-user.ts +60 -0
  330. package/packages/arcgis-rest-portal/src/users/invitation.ts +157 -0
  331. package/packages/arcgis-rest-portal/src/users/notification.ts +67 -0
  332. package/packages/arcgis-rest-portal/src/users/search-users.ts +35 -0
  333. package/packages/arcgis-rest-portal/src/users/update.ts +63 -0
  334. package/packages/arcgis-rest-portal/src/util/SearchQueryBuilder.ts +391 -0
  335. package/packages/arcgis-rest-portal/src/util/array.ts +16 -0
  336. package/packages/arcgis-rest-portal/src/util/generic-search.ts +111 -0
  337. package/packages/arcgis-rest-portal/src/util/get-portal-settings.ts +44 -0
  338. package/packages/arcgis-rest-portal/src/util/get-portal-url.ts +32 -0
  339. package/packages/arcgis-rest-portal/src/util/get-portal.ts +53 -0
  340. package/packages/arcgis-rest-portal/src/util/get-subscription-info.ts +43 -0
  341. package/packages/arcgis-rest-portal/src/util/scrub-control-chars.ts +13 -0
  342. package/packages/arcgis-rest-portal/src/util/search.ts +48 -0
  343. package/packages/arcgis-rest-portal/test/groups/add-users.test.ts +238 -0
  344. package/packages/arcgis-rest-portal/test/groups/crud.test.ts +183 -0
  345. package/packages/arcgis-rest-portal/test/groups/get.test.ts +174 -0
  346. package/packages/arcgis-rest-portal/test/groups/invite-users.test.ts +146 -0
  347. package/packages/arcgis-rest-portal/test/groups/join.test.ts +71 -0
  348. package/packages/arcgis-rest-portal/test/groups/notification.test.ts +111 -0
  349. package/packages/arcgis-rest-portal/test/groups/protect.test.ts +71 -0
  350. package/packages/arcgis-rest-portal/test/groups/remove-users.test.ts +140 -0
  351. package/packages/arcgis-rest-portal/test/groups/search.test.ts +151 -0
  352. package/packages/arcgis-rest-portal/test/groups/update-user-membership.test.ts +64 -0
  353. package/packages/arcgis-rest-portal/test/items/add.test.ts +320 -0
  354. package/packages/arcgis-rest-portal/test/items/content.test.ts +161 -0
  355. package/packages/arcgis-rest-portal/test/items/create.test.ts +404 -0
  356. package/packages/arcgis-rest-portal/test/items/export.test.ts +115 -0
  357. package/packages/arcgis-rest-portal/test/items/get.test.ts +606 -0
  358. package/packages/arcgis-rest-portal/test/items/helpers.test.ts +60 -0
  359. package/packages/arcgis-rest-portal/test/items/protect.test.ts +120 -0
  360. package/packages/arcgis-rest-portal/test/items/reassign.test.ts +130 -0
  361. package/packages/arcgis-rest-portal/test/items/remove.test.ts +259 -0
  362. package/packages/arcgis-rest-portal/test/items/search.test.ts +274 -0
  363. package/packages/arcgis-rest-portal/test/items/update.test.ts +549 -0
  364. package/packages/arcgis-rest-portal/test/items/upload.test.ts +286 -0
  365. package/packages/arcgis-rest-portal/test/mocks/groups/responses.ts +208 -0
  366. package/packages/arcgis-rest-portal/test/mocks/items/foo.zip +0 -0
  367. package/packages/arcgis-rest-portal/test/mocks/items/item.ts +526 -0
  368. package/packages/arcgis-rest-portal/test/mocks/items/resources.ts +38 -0
  369. package/packages/arcgis-rest-portal/test/mocks/items/search.ts +121 -0
  370. package/packages/arcgis-rest-portal/test/mocks/portal/response.ts +126 -0
  371. package/packages/arcgis-rest-portal/test/mocks/portal/settings-response.ts +56 -0
  372. package/packages/arcgis-rest-portal/test/mocks/sharing/sharing.ts +18 -0
  373. package/packages/arcgis-rest-portal/test/mocks/users/invitation.ts +70 -0
  374. package/packages/arcgis-rest-portal/test/mocks/users/notification.ts +34 -0
  375. package/packages/arcgis-rest-portal/test/mocks/users/user-search.ts +388 -0
  376. package/packages/arcgis-rest-portal/test/mocks/users/user-tags.ts +5 -0
  377. package/packages/arcgis-rest-portal/test/mocks/users/user.ts +174 -0
  378. package/packages/arcgis-rest-portal/test/orgs/notification.test.ts +142 -0
  379. package/packages/arcgis-rest-portal/test/services/get-unique-service-name.test.ts +64 -0
  380. package/packages/arcgis-rest-portal/test/services/is-service-name-available.test.ts +41 -0
  381. package/packages/arcgis-rest-portal/test/sharing/access.test.ts +162 -0
  382. package/packages/arcgis-rest-portal/test/sharing/helpers.test.ts +55 -0
  383. package/packages/arcgis-rest-portal/test/sharing/share-item-with-group.test.ts +1328 -0
  384. package/packages/arcgis-rest-portal/test/sharing/unshare-item-with-group.test.ts +288 -0
  385. package/packages/arcgis-rest-portal/test/users/get-user-tags.test.ts +71 -0
  386. package/packages/arcgis-rest-portal/test/users/get-user-url.test.ts +40 -0
  387. package/packages/arcgis-rest-portal/test/users/get-user.test.ts +90 -0
  388. package/packages/arcgis-rest-portal/test/users/invitation.test.ts +126 -0
  389. package/packages/arcgis-rest-portal/test/users/notification.test.ts +76 -0
  390. package/packages/arcgis-rest-portal/test/users/search.test.ts +41 -0
  391. package/packages/arcgis-rest-portal/test/users/update.test.ts +150 -0
  392. package/packages/arcgis-rest-portal/test/util/SearchQueryBuilder.test.ts +295 -0
  393. package/packages/arcgis-rest-portal/test/util/array.test.ts +33 -0
  394. package/packages/arcgis-rest-portal/test/util/get-portal-settings.test.ts +57 -0
  395. package/packages/arcgis-rest-portal/test/util/get-portal-url.test.ts +37 -0
  396. package/packages/arcgis-rest-portal/test/util/portal.test.ts +137 -0
  397. package/packages/arcgis-rest-portal/test/util/scrub-control-chars.test.ts +25 -0
  398. package/packages/arcgis-rest-portal/tsconfig.json +6 -0
  399. package/packages/arcgis-rest-request/README.md +72 -0
  400. package/packages/arcgis-rest-request/package.json +69 -0
  401. package/packages/arcgis-rest-request/post-message-auth-spec.md +70 -0
  402. package/packages/arcgis-rest-request/src/ApiKeyManager.ts +60 -0
  403. package/packages/arcgis-rest-request/src/ApplicationCredentialsManager.ts +141 -0
  404. package/packages/arcgis-rest-request/src/ArcGISIdentityManager.ts +1470 -0
  405. package/packages/arcgis-rest-request/src/app-tokens.ts +132 -0
  406. package/packages/arcgis-rest-request/src/authenticated-request-options.ts +23 -0
  407. package/packages/arcgis-rest-request/src/federation-utils.ts +88 -0
  408. package/packages/arcgis-rest-request/src/fetch-token.ts +48 -0
  409. package/packages/arcgis-rest-request/src/generate-token.ts +32 -0
  410. package/packages/arcgis-rest-request/src/index.ts +46 -0
  411. package/packages/arcgis-rest-request/src/request.ts +446 -0
  412. package/packages/arcgis-rest-request/src/revoke-token.ts +73 -0
  413. package/packages/arcgis-rest-request/src/types/feature.ts +42 -0
  414. package/packages/arcgis-rest-request/src/types/geometry.ts +239 -0
  415. package/packages/arcgis-rest-request/src/types/group.ts +72 -0
  416. package/packages/arcgis-rest-request/src/types/service.ts +87 -0
  417. package/packages/arcgis-rest-request/src/types/symbol.ts +21 -0
  418. package/packages/arcgis-rest-request/src/types/user.ts +49 -0
  419. package/packages/arcgis-rest-request/src/utils/ArcGISRequestError.ts +82 -0
  420. package/packages/arcgis-rest-request/src/utils/ErrorTypes.ts +29 -0
  421. package/packages/arcgis-rest-request/src/utils/GrantTypes.ts +5 -0
  422. package/packages/arcgis-rest-request/src/utils/HTTPMethods.ts +6 -0
  423. package/packages/arcgis-rest-request/src/utils/IAuthenticationManager.ts +22 -0
  424. package/packages/arcgis-rest-request/src/utils/IFetchTokenParams.ts +11 -0
  425. package/packages/arcgis-rest-request/src/utils/IGenerateTokenParams.ts +9 -0
  426. package/packages/arcgis-rest-request/src/utils/IParamBuilder.ts +3 -0
  427. package/packages/arcgis-rest-request/src/utils/IParams.ts +6 -0
  428. package/packages/arcgis-rest-request/src/utils/IParamsBuilder.ts +5 -0
  429. package/packages/arcgis-rest-request/src/utils/IRequestOptions.ts +59 -0
  430. package/packages/arcgis-rest-request/src/utils/ITokenRequestOptions.ts +9 -0
  431. package/packages/arcgis-rest-request/src/utils/ResponseFormats.ts +10 -0
  432. package/packages/arcgis-rest-request/src/utils/append-custom-params.ts +46 -0
  433. package/packages/arcgis-rest-request/src/utils/clean-url.ts +20 -0
  434. package/packages/arcgis-rest-request/src/utils/decode-query-string.ts +27 -0
  435. package/packages/arcgis-rest-request/src/utils/encode-form-data.ts +41 -0
  436. package/packages/arcgis-rest-request/src/utils/encode-query-string.ts +37 -0
  437. package/packages/arcgis-rest-request/src/utils/process-params.ts +109 -0
  438. package/packages/arcgis-rest-request/src/utils/retryAuthError.ts +10 -0
  439. package/packages/arcgis-rest-request/src/utils/warn.ts +11 -0
  440. package/packages/arcgis-rest-request/src/utils/with-options.ts +48 -0
  441. package/packages/arcgis-rest-request/src/validate-app-access.ts +69 -0
  442. package/packages/arcgis-rest-request/test/ApiKey.test.ts +53 -0
  443. package/packages/arcgis-rest-request/test/ApplicationSession.test.ts +148 -0
  444. package/packages/arcgis-rest-request/test/ArcGISIdentityManager.test.ts +2579 -0
  445. package/packages/arcgis-rest-request/test/app-tokens.test.ts +91 -0
  446. package/packages/arcgis-rest-request/test/federation-utils.test.ts +323 -0
  447. package/packages/arcgis-rest-request/test/fetchToken.test.ts +110 -0
  448. package/packages/arcgis-rest-request/test/generateToken.test.ts +40 -0
  449. package/packages/arcgis-rest-request/test/mocks/errors.ts +76 -0
  450. package/packages/arcgis-rest-request/test/mocks/geojson-feature-collection.ts +13 -0
  451. package/packages/arcgis-rest-request/test/mocks/param-builder.ts +7 -0
  452. package/packages/arcgis-rest-request/test/mocks/sharing-rest-info.ts +41 -0
  453. package/packages/arcgis-rest-request/test/mocks/webmap.ts +41 -0
  454. package/packages/arcgis-rest-request/test/request.test.ts +563 -0
  455. package/packages/arcgis-rest-request/test/revoke-token.test.ts +55 -0
  456. package/packages/arcgis-rest-request/test/utils/ArcGISAuthError.test.ts +196 -0
  457. package/packages/arcgis-rest-request/test/utils/ArcGISRequestError.test.ts +51 -0
  458. package/packages/arcgis-rest-request/test/utils/check-for-errors.test.ts +111 -0
  459. package/packages/arcgis-rest-request/test/utils/clean-url.test.ts +50 -0
  460. package/packages/arcgis-rest-request/test/utils/encode-form-data.test.ts +146 -0
  461. package/packages/arcgis-rest-request/test/utils/encode-query-string.test.ts +22 -0
  462. package/packages/arcgis-rest-request/test/utils/process-params.test.ts +205 -0
  463. package/packages/arcgis-rest-request/test/utils/with-options.test.ts +135 -0
  464. package/packages/arcgis-rest-request/test/validate-app-access.test.ts +44 -0
  465. package/packages/arcgis-rest-request/tsconfig.json +4 -0
  466. package/packages/arcgis-rest-routing/README.md +74 -0
  467. package/packages/arcgis-rest-routing/package.json +69 -0
  468. package/packages/arcgis-rest-routing/src/closestFacility.ts +223 -0
  469. package/packages/arcgis-rest-routing/src/helpers.ts +104 -0
  470. package/packages/arcgis-rest-routing/src/index.ts +20 -0
  471. package/packages/arcgis-rest-routing/src/originDestinationMatrix.ts +219 -0
  472. package/packages/arcgis-rest-routing/src/serviceArea.ts +169 -0
  473. package/packages/arcgis-rest-routing/src/solveRoute.ts +179 -0
  474. package/packages/arcgis-rest-routing/test/closestFacility.test.ts +686 -0
  475. package/packages/arcgis-rest-routing/test/mocks/inputs.ts +132 -0
  476. package/packages/arcgis-rest-routing/test/mocks/responses.ts +13316 -0
  477. package/packages/arcgis-rest-routing/test/originDestinationMatrix.test.ts +795 -0
  478. package/packages/arcgis-rest-routing/test/serviceArea.test.ts +601 -0
  479. package/packages/arcgis-rest-routing/test/solveRoute.test.ts +681 -0
  480. package/packages/arcgis-rest-routing/tsconfig.json +6 -0
  481. package/prettier-package-json.config.cjs +81 -0
  482. package/rollup.js +152 -0
  483. package/scripts/create-dist-package-jsons.js +17 -0
  484. package/scripts/deploy-doc-site.js +16 -0
  485. package/scripts/generate-sri-hashes.js +52 -0
  486. package/scripts/get-package-json.js +27 -0
  487. package/scripts/run-demo-server.js +21 -0
  488. package/scripts/test-helpers.ts +20 -0
  489. package/tsconfig.json +62 -0
  490. package/typedoc.json +14 -0
@@ -0,0 +1,1470 @@
1
+ /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
2
+ * Apache-2.0 */
3
+
4
+ import * as http from "http";
5
+ import { ArcGISAuthError, request } from "./request.js";
6
+ import { IRequestOptions } from "./utils/IRequestOptions.js";
7
+ import { IAuthenticationManager } from "./utils/IAuthenticationManager.js";
8
+ import { ITokenRequestOptions } from "./utils/ITokenRequestOptions.js";
9
+ import { decodeQueryString } from "./utils/decode-query-string.js";
10
+ import { encodeQueryString } from "./utils/encode-query-string.js";
11
+ import { IUser } from "./types/user.js";
12
+ import { generateToken } from "./generate-token.js";
13
+ import { fetchToken, IFetchTokenResponse } from "./fetch-token.js";
14
+ import { canUseOnlineToken, isFederated } from "./federation-utils.js";
15
+ import { IAppAccess, validateAppAccess } from "./validate-app-access.js";
16
+ import { cleanUrl } from "./utils/clean-url.js";
17
+ import { revokeToken } from "./revoke-token.js";
18
+
19
+ /**
20
+ * Options for {@linkcode ArcGISIdentityManager.fromToken}.
21
+ */
22
+ export interface IFromTokenOptions {
23
+ token: string;
24
+ tokenExpires?: Date;
25
+ portal?: string;
26
+ }
27
+
28
+ /**
29
+ * Options for {@linkcode ArcGISIdentityManager.signIn}.
30
+ */
31
+ export interface ISignInOptions {
32
+ username: string;
33
+ password: string;
34
+ portal?: string;
35
+ }
36
+
37
+ /**
38
+ * Internal utility for resolving a Promise from outside its constructor.
39
+ *
40
+ * See: http://lea.verou.me/2016/12/resolve-promises-externally-with-this-one-weird-trick/
41
+ */
42
+ interface IDeferred<T> {
43
+ promise: Promise<T>;
44
+ resolve: (v: T) => void;
45
+ reject: (v: any) => void;
46
+ }
47
+
48
+ export type AuthenticationProvider =
49
+ | "arcgis"
50
+ | "facebook"
51
+ | "google"
52
+ | "github"
53
+ | "apple";
54
+
55
+ /**
56
+ * Represents a [credential](https://developers.arcgis.com/javascript/latest/api-reference/esri-identity-Credential.html)
57
+ * object used to access a secure ArcGIS resource.
58
+ */
59
+ export interface ICredential {
60
+ expires: number;
61
+ server: string;
62
+ ssl: boolean;
63
+ token: string;
64
+ userId: string;
65
+ }
66
+
67
+ function defer<T>(): IDeferred<T> {
68
+ const deferred: any = {
69
+ promise: null,
70
+ resolve: null,
71
+ reject: null
72
+ };
73
+
74
+ deferred.promise = new Promise((resolve, reject) => {
75
+ deferred.resolve = resolve;
76
+ deferred.reject = reject;
77
+ });
78
+
79
+ return deferred as IDeferred<T>;
80
+ }
81
+
82
+ /**
83
+ * Options for static OAuth 2.0 helper methods on `ArcGISIdentityManager`.
84
+ */
85
+ export interface IOAuth2Options {
86
+ /**
87
+ * Client ID of your application. Can be obtained by registering an application
88
+ * on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
89
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
90
+ */
91
+ clientId: string;
92
+
93
+ /**
94
+ * A valid URL to redirect to after a user authorizes your application. Can be set on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
95
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
96
+ */
97
+ redirectUri: string;
98
+
99
+ /**
100
+ * The ArcGIS Online or ArcGIS Enterprise portal you want to use for authentication. Defaults to `https://www.arcgis.com/sharing/rest` for the ArcGIS Online portal.
101
+ */
102
+ portal?: string;
103
+
104
+ /**
105
+ * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page.
106
+ */
107
+
108
+ provider?: AuthenticationProvider;
109
+
110
+ /**
111
+ * The requested validity in minutes for a token. Defaults to 20160 (two weeks).
112
+ */
113
+ expiration?: number;
114
+
115
+ /**
116
+ * Duration (in minutes) that a token will be valid. Defaults to 20160 (two weeks).
117
+ *
118
+ * @deprecated use 'expiration' instead
119
+ */
120
+ duration?: number;
121
+
122
+ /**
123
+ * Determines whether to open the authorization window in a new tab/window or in the current window.
124
+ *
125
+ * @browserOnly
126
+ */
127
+ popup?: boolean;
128
+
129
+ /**
130
+ * The window features passed to [window.open()](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) when `popup` is true. Defaults to `height=400,width=600,menubar=no,location=yes,resizable=yes,scrollbars=yes,status=yes`
131
+ *
132
+ * @browserOnly
133
+ */
134
+ popupWindowFeatures?: string;
135
+
136
+ /**
137
+ * Duration (in minutes) that a refresh token will be valid.
138
+ *
139
+ * @nodeOnly
140
+ */
141
+ refreshTokenTTL?: number;
142
+
143
+ /**
144
+ * The locale assumed to render the login page.
145
+ *
146
+ * @browserOnly
147
+ */
148
+ locale?: string;
149
+
150
+ /**
151
+ * Applications can specify an opaque value for this parameter to correlate the authorization request sent with the received response. By default, clientId is used.
152
+ *
153
+ * @browserOnly
154
+ */
155
+ state?: string;
156
+
157
+ /**
158
+ * Sets the color theme of the oAuth 2.0 authorization screen. Will use the system preference or a light theme by default.
159
+ */
160
+ style?: "" | "light" | "dark";
161
+
162
+ [key: string]: any;
163
+ }
164
+
165
+ /**
166
+ * Options for the {@linkcode ArcGISIdentityManager} constructor.
167
+ */
168
+ export interface IArcGISIdentityManagerOptions {
169
+ /**
170
+ * Client ID of your application. Can be obtained by registering an application
171
+ * on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
172
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
173
+ */
174
+ clientId?: string;
175
+
176
+ /**
177
+ * A valid URL to redirect to after a user authorizes your application. Can be set on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
178
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
179
+ */
180
+ redirectUri?: string;
181
+
182
+ /**
183
+ * OAuth 2.0 refresh token from a previous user session.
184
+ */
185
+ refreshToken?: string;
186
+
187
+ /**
188
+ * Expiration date of the `refreshToken`
189
+ */
190
+ refreshTokenExpires?: Date;
191
+
192
+ /**
193
+ * The authenticated user's username. Guaranteed to be unique across ArcGIS Online or your instance of ArcGIS Enterprise.
194
+ */
195
+ username?: string;
196
+
197
+ /**
198
+ * Password for this user. Used in CLI apps where users cannot do OAuth 2.0.
199
+ */
200
+ password?: string;
201
+
202
+ /**
203
+ * OAuth 2.0 access token from a previous user session.
204
+ */
205
+ token?: string;
206
+
207
+ /**
208
+ * Expiration date for the `token`
209
+ */
210
+ tokenExpires?: Date;
211
+
212
+ /**
213
+ * The ArcGIS Online or ArcGIS Enterprise portal you want to use for authentication. Defaults to `https://www.arcgis.com/sharing/rest` for the ArcGIS Online portal.
214
+ */
215
+ portal?: string;
216
+
217
+ /**
218
+ * This value is set to true automatically if the ArcGIS Organization requires that requests be made over https.
219
+ */
220
+ ssl?: boolean;
221
+
222
+ /**
223
+ * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page.
224
+ */
225
+ provider?: AuthenticationProvider;
226
+
227
+ /**
228
+ * Duration of requested token validity in minutes. Used when requesting tokens with `username` and `password` or when validating the identity of unknown servers. Defaults to two weeks.
229
+ */
230
+ tokenDuration?: number;
231
+
232
+ /**
233
+ * Duration (in minutes) that a refresh token will be valid.
234
+ */
235
+ refreshTokenTTL?: number;
236
+
237
+ /**
238
+ * An unfederated ArcGIS Server instance known to recognize credentials supplied manually.
239
+ * ```js
240
+ * {
241
+ * server: "https://sampleserver6.arcgisonline.com/arcgis",
242
+ * token: "SOSlV3v..",
243
+ * tokenExpires: new Date(1545415669763)
244
+ * }
245
+ * ```
246
+ */
247
+ server?: string;
248
+ }
249
+
250
+ /**
251
+ * Used to authenticate both ArcGIS Online and ArcGIS Enterprise users. `ArcGISIdentityManager` includes helper methods for [OAuth 2.0](/arcgis-rest-js/guides/browser-authentication/) in both browser and server applications.
252
+ *
253
+ * **It is not recommended to construct `ArcGISIdentityManager` directly**. Instead there are several static methods used for specific workflows. The 2 primary workflows relate to oAuth 2.0:
254
+ *
255
+ * * {@linkcode ArcGISIdentityManager.beginOAuth2} + {@linkcode ArcGISIdentityManager.completeOAuth2} - for oAuth 2.0 in browser-only environment.
256
+ * * {@linkcode ArcGISIdentityManager.authorize} + {@linkcode ArcGISIdentityManager.exchangeAuthorizationCode} - for oAuth 2.0 for server-enabled application.
257
+ *
258
+ * Other more specialized helpers for less common workflows also exist:
259
+ *
260
+ * * {@linkcode ArcGISIdentityManager.enablePostMessageAuth} + {@linkcode ArcGISIdentityManager.fromParent} - For when your application needs to pass authentication details between different pages embedded in iframes.
261
+ * * {@linkcode ArcGISIdentityManager.fromToken} - When you have an existing token from another source and would like create an `ArcGISIdentityManager` instance.
262
+ * * {@linkcode ArcGISIdentityManager.fromCredential} - For creating an `ArcGISIdentityManager` instance from a `Credentials` object in the ArcGIS JS API `IdentityManager`
263
+ * * {@linkcode ArcGISIdentityManager.signIn} - Authenticate directly with a users username and password.
264
+ *
265
+ * Once a session has been created there are additional utilities:
266
+ *
267
+ * * {@linkcode ArcGISIdentityManager.serialize} can be used to create a JSON object representing an instance of `ArcGISIdentityManager`
268
+ * * {@linkcode ArcGISIdentityManager.deserialize} will create a new `ArcGISIdentityManager` from a JSON object created with {@linkcode ArcGISIdentityManager.serialize}
269
+ * * {@linkcode ArcGISIdentityManager.destroy} or {@linkcode ArcGISIdentityManager.signOut} will invalidate any tokens in use by the `ArcGISIdentityManager`.
270
+ */
271
+ export class ArcGISIdentityManager implements IAuthenticationManager {
272
+ /**
273
+ * The current ArcGIS Online or ArcGIS Enterprise `token`.
274
+ */
275
+ get token() {
276
+ return this._token;
277
+ }
278
+
279
+ /**
280
+ * The expiration time of the current `token`.
281
+ */
282
+ get tokenExpires() {
283
+ return this._tokenExpires;
284
+ }
285
+
286
+ /**
287
+ * The current token to ArcGIS Online or ArcGIS Enterprise.
288
+ */
289
+ get refreshToken() {
290
+ return this._refreshToken;
291
+ }
292
+
293
+ /**
294
+ * The expiration time of the current `refreshToken`.
295
+ */
296
+ get refreshTokenExpires() {
297
+ return this._refreshTokenExpires;
298
+ }
299
+
300
+ /**
301
+ * The currently authenticated user.
302
+ */
303
+ get username() {
304
+ if (this._username) {
305
+ return this._username;
306
+ }
307
+
308
+ if (this._user && this._user.username) {
309
+ return this._user.username;
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Deprecated, use `federatedServers` instead.
315
+ *
316
+ * @deprecated
317
+ */
318
+ get trustedServers() {
319
+ console.log("DEPRECATED: use federatedServers instead");
320
+ return this.federatedServers;
321
+ }
322
+
323
+ /**
324
+ * Returns `true` if this session can be refreshed and `false` if it cannot.
325
+ */
326
+ get canRefresh() {
327
+ if (this.username && this.password) {
328
+ return true;
329
+ }
330
+
331
+ if (this.clientId && this.refreshToken) {
332
+ return true;
333
+ }
334
+
335
+ return false;
336
+ }
337
+
338
+ /**
339
+ * Begins a new browser-based OAuth 2.0 sign in. If `options.popup` is `true` the
340
+ * authentication window will open in a new tab/window. Otherwise, the user will be redirected to the authorization page in their current tab/window and the function will return `undefined`.
341
+ *
342
+ * @browserOnly
343
+ */
344
+ /* istanbul ignore next */
345
+ public static beginOAuth2(
346
+ options: IOAuth2Options,
347
+ win: any = window
348
+ ): Promise<ArcGISIdentityManager> | undefined {
349
+ if (options.duration) {
350
+ console.log(
351
+ "DEPRECATED: 'duration' is deprecated - use 'expiration' instead"
352
+ );
353
+ }
354
+
355
+ const {
356
+ portal,
357
+ provider,
358
+ clientId,
359
+ expiration,
360
+ redirectUri,
361
+ popup,
362
+ popupWindowFeatures,
363
+ state,
364
+ locale,
365
+ params,
366
+ style
367
+ }: IOAuth2Options = {
368
+ ...{
369
+ portal: "https://www.arcgis.com/sharing/rest",
370
+ provider: "arcgis",
371
+ expiration: 20160,
372
+ popup: true,
373
+ popupWindowFeatures:
374
+ "height=400,width=600,menubar=no,location=yes,resizable=yes,scrollbars=yes,status=yes",
375
+ state: options.clientId,
376
+ locale: "",
377
+ style: ""
378
+ },
379
+ ...options
380
+ };
381
+
382
+ let url: string;
383
+
384
+ if (provider === "arcgis") {
385
+ url = `${portal}/oauth2/authorize?client_id=${clientId}&response_type=token&expiration=${
386
+ options.duration || expiration
387
+ }&redirect_uri=${encodeURIComponent(
388
+ redirectUri
389
+ )}&state=${state}&locale=${locale}&style=${style}`;
390
+ } else {
391
+ url = `${portal}/oauth2/social/authorize?client_id=${clientId}&socialLoginProviderName=${provider}&autoAccountCreateForSocial=true&response_type=token&expiration=${
392
+ options.duration || expiration
393
+ }&redirect_uri=${encodeURIComponent(
394
+ redirectUri
395
+ )}&state=${state}&locale=${locale}&style=${style}`;
396
+ }
397
+
398
+ // append additional params
399
+ if (params) {
400
+ url = `${url}&${encodeQueryString(params)}`;
401
+ }
402
+
403
+ if (!popup) {
404
+ win.location.href = url;
405
+ return undefined;
406
+ }
407
+
408
+ const session = defer<ArcGISIdentityManager>();
409
+
410
+ win[`__ESRI_REST_AUTH_HANDLER_${clientId}`] = function (
411
+ errorString: any,
412
+ oauthInfoString: string
413
+ ) {
414
+ if (errorString) {
415
+ const error = JSON.parse(errorString);
416
+ session.reject(new ArcGISAuthError(error.errorMessage, error.error));
417
+ return;
418
+ }
419
+
420
+ if (oauthInfoString) {
421
+ const oauthInfo = JSON.parse(oauthInfoString);
422
+ session.resolve(
423
+ new ArcGISIdentityManager({
424
+ clientId,
425
+ portal,
426
+ ssl: oauthInfo.ssl,
427
+ token: oauthInfo.token,
428
+ tokenExpires: new Date(oauthInfo.expires),
429
+ username: oauthInfo.username
430
+ })
431
+ );
432
+ }
433
+ };
434
+
435
+ win.open(url, "oauth-window", popupWindowFeatures);
436
+
437
+ return session.promise;
438
+ }
439
+
440
+ /**
441
+ * Completes a browser-based OAuth 2.0 sign in. If `options.popup` is `true` the user
442
+ * will be returned to the previous window and the popup will close. Otherwise a new `ArcGISIdentityManager` will be returned. You must pass the same values for `options.popup` and `options.portal` as you used in `beginOAuth2()`.
443
+ *
444
+ * @browserOnly
445
+ */
446
+ /* istanbul ignore next */
447
+ public static completeOAuth2(options: IOAuth2Options, win: any = window) {
448
+ const { portal, clientId, popup }: IOAuth2Options = {
449
+ ...{ portal: "https://www.arcgis.com/sharing/rest", popup: true },
450
+ ...options
451
+ };
452
+
453
+ function completeSignIn(error: any, oauthInfo?: IFetchTokenResponse) {
454
+ try {
455
+ let handlerFn;
456
+ const handlerFnName = `__ESRI_REST_AUTH_HANDLER_${clientId}`;
457
+
458
+ if (popup) {
459
+ // Guard b/c IE does not support window.opener
460
+ if (win.opener) {
461
+ if (win.opener.parent && win.opener.parent[handlerFnName]) {
462
+ handlerFn = win.opener.parent[handlerFnName];
463
+ } else if (win.opener && win.opener[handlerFnName]) {
464
+ // support pop-out oauth from within an iframe
465
+ handlerFn = win.opener[handlerFnName];
466
+ }
467
+ } else {
468
+ // IE
469
+ if (win !== win.parent && win.parent && win.parent[handlerFnName]) {
470
+ handlerFn = win.parent[handlerFnName];
471
+ }
472
+ }
473
+ // if we have a handler fn, call it and close the window
474
+ if (handlerFn) {
475
+ handlerFn(
476
+ error ? JSON.stringify(error) : undefined,
477
+ JSON.stringify(oauthInfo)
478
+ );
479
+ win.close();
480
+ return undefined;
481
+ }
482
+ }
483
+ } catch (e) {
484
+ throw new ArcGISAuthError(
485
+ `Unable to complete authentication. It's possible you specified popup based oAuth2 but no handler from "beginOAuth2()" present. This generally happens because the "popup" option differs between "beginOAuth2()" and "completeOAuth2()".`
486
+ );
487
+ }
488
+
489
+ if (error) {
490
+ throw new ArcGISAuthError(error.errorMessage, error.error);
491
+ }
492
+
493
+ return new ArcGISIdentityManager({
494
+ clientId,
495
+ portal,
496
+ ssl: oauthInfo.ssl,
497
+ token: oauthInfo.token,
498
+ tokenExpires: oauthInfo.expires,
499
+ username: oauthInfo.username
500
+ });
501
+ }
502
+
503
+ const params = decodeQueryString(win.location.hash);
504
+
505
+ if (!params.access_token) {
506
+ let error;
507
+ let errorMessage = "Unknown error";
508
+
509
+ if (params.error) {
510
+ error = params.error;
511
+ errorMessage = params.error_description;
512
+ }
513
+
514
+ return completeSignIn({ error, errorMessage });
515
+ }
516
+
517
+ const token = params.access_token;
518
+ const expires = new Date(
519
+ Date.now() + parseInt(params.expires_in, 10) * 1000 - 60 * 1000
520
+ );
521
+ const username = params.username;
522
+ const ssl = params.ssl === "true";
523
+
524
+ return completeSignIn(undefined, {
525
+ token,
526
+ expires,
527
+ ssl,
528
+ username
529
+ });
530
+ }
531
+
532
+ /**
533
+ * Request session information from the parent application
534
+ *
535
+ * When an application is embedded into another application via an IFrame, the embedded app can
536
+ * use `window.postMessage` to request credentials from the host application. This function wraps
537
+ * that behavior.
538
+ *
539
+ * The ArcGIS API for Javascript has this built into the Identity Manager as of the 4.19 release.
540
+ *
541
+ * Note: The parent application will not respond if the embedded app's origin is not:
542
+ * - the same origin as the parent or *.arcgis.com (JSAPI)
543
+ * - in the list of valid child origins (REST-JS)
544
+ *
545
+ *
546
+ * @param parentOrigin origin of the parent frame. Passed into the embedded application as `parentOrigin` query param
547
+ * @browserOnly
548
+ */
549
+ public static fromParent(parentOrigin: string, win?: any): Promise<any> {
550
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
551
+ if (!win && window) {
552
+ win = window;
553
+ }
554
+ // Declare handler outside of promise scope so we can detach it
555
+ let handler: (event: any) => void;
556
+ // return a promise that will resolve when the handler receives
557
+ // session information from the correct origin
558
+ return new Promise((resolve, reject) => {
559
+ // create an event handler that just wraps the parentMessageHandler
560
+ handler = (event: any) => {
561
+ // ensure we only listen to events from the parent
562
+ if (event.source === win.parent && event.data) {
563
+ try {
564
+ return resolve(ArcGISIdentityManager.parentMessageHandler(event));
565
+ } catch (err) {
566
+ return reject(err);
567
+ }
568
+ }
569
+ };
570
+ // add listener
571
+ win.addEventListener("message", handler, false);
572
+ win.parent.postMessage(
573
+ { type: "arcgis:auth:requestCredential" },
574
+ parentOrigin
575
+ );
576
+ }).then((session) => {
577
+ win.removeEventListener("message", handler, false);
578
+ return session;
579
+ });
580
+ }
581
+
582
+ /**
583
+ * Begins a new server-based OAuth 2.0 sign in. This will redirect the user to
584
+ * the ArcGIS Online or ArcGIS Enterprise authorization page.
585
+ *
586
+ * @nodeOnly
587
+ */
588
+ public static authorize(
589
+ options: IOAuth2Options,
590
+ response: http.ServerResponse
591
+ ) {
592
+ if (options.duration) {
593
+ console.log(
594
+ "DEPRECATED: 'duration' is deprecated - use 'expiration' instead"
595
+ );
596
+ }
597
+ const { portal, clientId, expiration, redirectUri }: IOAuth2Options = {
598
+ ...{ portal: "https://arcgis.com/sharing/rest", expiration: 20160 },
599
+ ...options
600
+ };
601
+
602
+ response.writeHead(301, {
603
+ Location: `${portal}/oauth2/authorize?client_id=${clientId}&expiration=${
604
+ options.duration || expiration
605
+ }&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}`
606
+ });
607
+
608
+ response.end();
609
+ }
610
+
611
+ /**
612
+ * Completes the server-based OAuth 2.0 sign in process by exchanging the `authorizationCode`
613
+ * for a `access_token`.
614
+ *
615
+ * @nodeOnly
616
+ */
617
+ public static exchangeAuthorizationCode(
618
+ options: IOAuth2Options,
619
+ authorizationCode: string
620
+ ): Promise<ArcGISIdentityManager> {
621
+ const { portal, clientId, redirectUri, refreshTokenTTL }: IOAuth2Options = {
622
+ ...{
623
+ portal: "https://www.arcgis.com/sharing/rest",
624
+ refreshTokenTTL: 20160
625
+ },
626
+ ...options
627
+ };
628
+
629
+ return fetchToken(`${portal}/oauth2/token`, {
630
+ params: {
631
+ grant_type: "authorization_code",
632
+ client_id: clientId,
633
+ redirect_uri: redirectUri,
634
+ code: authorizationCode
635
+ }
636
+ }).then((response) => {
637
+ return new ArcGISIdentityManager({
638
+ clientId,
639
+ portal,
640
+ ssl: response.ssl,
641
+ redirectUri,
642
+ refreshToken: response.refreshToken,
643
+ refreshTokenTTL,
644
+ refreshTokenExpires: new Date(
645
+ Date.now() + (refreshTokenTTL - 1) * 60 * 1000
646
+ ),
647
+ token: response.token,
648
+ tokenExpires: response.expires,
649
+ username: response.username
650
+ });
651
+ });
652
+ }
653
+
654
+ public static deserialize(str: string) {
655
+ const options = JSON.parse(str);
656
+ return new ArcGISIdentityManager({
657
+ clientId: options.clientId,
658
+ refreshToken: options.refreshToken,
659
+ refreshTokenExpires: new Date(options.refreshTokenExpires),
660
+ username: options.username,
661
+ password: options.password,
662
+ token: options.token,
663
+ tokenExpires: new Date(options.tokenExpires),
664
+ portal: options.portal,
665
+ ssl: options.ssl,
666
+ tokenDuration: options.tokenDuration,
667
+ redirectUri: options.redirectUri,
668
+ refreshTokenTTL: options.refreshTokenTTL,
669
+ server: options.server
670
+ });
671
+ }
672
+
673
+ /**
674
+ * Translates authentication from the format used in the [ArcGIS API for JavaScript](https://developers.arcgis.com/javascript/).
675
+ *
676
+ * ```js
677
+ * ArcGISIdentityManager.fromCredential({
678
+ * userId: "jsmith",
679
+ * token: "secret"
680
+ * });
681
+ * ```
682
+ *
683
+ * @returns ArcGISIdentityManager
684
+ */
685
+ public static fromCredential(credential: ICredential) {
686
+ // At ArcGIS Online 9.1, credentials no longer include the ssl and expires properties
687
+ // Here, we provide default values for them to cover this condition
688
+ const ssl = typeof credential.ssl !== "undefined" ? credential.ssl : true;
689
+ const expires = credential.expires || Date.now() + 7200000; /* 2 hours */
690
+
691
+ return new ArcGISIdentityManager({
692
+ portal: credential.server.includes("sharing/rest")
693
+ ? credential.server
694
+ : credential.server + `/sharing/rest`,
695
+ ssl,
696
+ token: credential.token,
697
+ username: credential.userId,
698
+ tokenExpires: new Date(expires)
699
+ });
700
+ }
701
+
702
+ /**
703
+ * Handle the response from the parent
704
+ * @param event DOM Event
705
+ */
706
+ private static parentMessageHandler(event: any): ArcGISIdentityManager {
707
+ if (event.data.type === "arcgis:auth:credential") {
708
+ return ArcGISIdentityManager.fromCredential(event.data.credential);
709
+ }
710
+ if (event.data.type === "arcgis:auth:error") {
711
+ const err = new Error(event.data.error.message);
712
+ err.name = event.data.error.name;
713
+ throw err;
714
+ } else {
715
+ throw new Error("Unknown message type.");
716
+ }
717
+ }
718
+
719
+ /**
720
+ * Revokes all active tokens for a provided {@linkcode ArcGISIdentityManager}. The can be considered the equivalent to signing the user out of your application.
721
+ */
722
+ public static destroy(session: ArcGISIdentityManager) {
723
+ return revokeToken({
724
+ clientId: session.clientId,
725
+ portal: session.portal,
726
+ token: session.refreshToken || session.token
727
+ });
728
+ }
729
+
730
+ /**
731
+ * Create a {@linkcode ArcGISIdentityManager} from an existing token. Useful for when you have a users token from a different authentication system and want to get a {@linkcode ArcGISIdentityManager}.
732
+ */
733
+ public static fromToken(
734
+ options: IFromTokenOptions
735
+ ): Promise<ArcGISIdentityManager> {
736
+ const session = new ArcGISIdentityManager(options);
737
+
738
+ return session.getUser().then(() => {
739
+ return session;
740
+ });
741
+ }
742
+
743
+ /**
744
+ * Initialize a {@linkcode ArcGISIdentityManager} with a users `username` and `password`. **This method is intended ONLY for applications without a user interface such as CLI tools.**.
745
+ *
746
+ * If possible you should use {@linkcode ArcGISIdentityManager.beginOAuth2} to authenticate users in a browser or {@linkcode ArcGISIdentityManager.authorize} for authenticating users with a web server.
747
+ */
748
+ public static signIn(options: ISignInOptions) {
749
+ const session = new ArcGISIdentityManager(options);
750
+
751
+ return session.getUser().then(() => {
752
+ return session;
753
+ });
754
+ }
755
+
756
+ /**
757
+ * Client ID being used for authentication if provided in the `constructor`.
758
+ */
759
+ public readonly clientId: string;
760
+
761
+ /**
762
+ * The currently authenticated user's password if provided in the `constructor`.
763
+ */
764
+ public readonly password: string;
765
+
766
+ /**
767
+ * The current portal the user is authenticated with.
768
+ */
769
+ public readonly portal: string;
770
+
771
+ /**
772
+ * This value is set to true automatically if the ArcGIS Organization requires that requests be made over https.
773
+ */
774
+ public readonly ssl: boolean;
775
+
776
+ /**
777
+ * The authentication provider to use.
778
+ */
779
+ public readonly provider: AuthenticationProvider;
780
+
781
+ /**
782
+ * Determines how long new tokens requested are valid.
783
+ */
784
+ public readonly tokenDuration: number;
785
+
786
+ /**
787
+ * A valid redirect URI for this application if provided in the `constructor`.
788
+ */
789
+ public readonly redirectUri: string;
790
+
791
+ /**
792
+ * Duration of new OAuth 2.0 refresh token validity (in minutes).
793
+ */
794
+ public readonly refreshTokenTTL: number;
795
+
796
+ /**
797
+ * An unfederated ArcGIS Server instance known to recognize credentials supplied manually.
798
+ * ```js
799
+ * {
800
+ * server: "https://sampleserver6.arcgisonline.com/arcgis",
801
+ * token: "SOSlV3v..",
802
+ * tokenExpires: new Date(1545415669763)
803
+ * }
804
+ * ```
805
+ */
806
+ public readonly server: string;
807
+
808
+ /**
809
+ * Hydrated by a call to [getUser()](#getUser-summary).
810
+ */
811
+ private _user: IUser;
812
+
813
+ /**
814
+ * Hydrated by a call to [getPortal()](#getPortal-summary).
815
+ */
816
+ private _portalInfo: any;
817
+
818
+ private _token: string;
819
+ private _tokenExpires: Date;
820
+ private _refreshToken: string;
821
+ private _refreshTokenExpires: Date;
822
+ private _pendingUserRequest: Promise<IUser>;
823
+ private _pendingPortalRequest: Promise<any>;
824
+
825
+ /**
826
+ * Internal object to keep track of pending token requests. Used to prevent
827
+ * duplicate token requests.
828
+ */
829
+ private _pendingTokenRequests: {
830
+ [key: string]: Promise<string>;
831
+ };
832
+
833
+ private _username: string;
834
+
835
+ /**
836
+ * Internal list of tokens to 3rd party servers (federated servers) that have
837
+ * been created via `generateToken`. The object key is the root URL of the server.
838
+ */
839
+ private federatedServers: {
840
+ [key: string]: {
841
+ token: string;
842
+ expires: Date;
843
+ };
844
+ };
845
+
846
+ /**
847
+ * Internal list of 3rd party domains that should receive all cookies (credentials: "include").
848
+ * Used to for PKI and IWA workflows in high security environments.
849
+ */
850
+ private trustedDomains: string[];
851
+
852
+ private _hostHandler: any;
853
+
854
+ constructor(options: IArcGISIdentityManagerOptions) {
855
+ this.clientId = options.clientId;
856
+ this._refreshToken = options.refreshToken;
857
+ this._refreshTokenExpires = options.refreshTokenExpires;
858
+ this._username = options.username;
859
+ this.password = options.password;
860
+ this._token = options.token;
861
+ this._tokenExpires = options.tokenExpires;
862
+ this.portal = options.portal
863
+ ? cleanUrl(options.portal)
864
+ : "https://www.arcgis.com/sharing/rest";
865
+ this.ssl = options.ssl;
866
+ this.provider = options.provider || "arcgis";
867
+ this.tokenDuration = options.tokenDuration || 20160;
868
+ this.redirectUri = options.redirectUri;
869
+ this.refreshTokenTTL = options.refreshTokenTTL || 20160;
870
+ this.server = options.server;
871
+
872
+ this.federatedServers = {};
873
+ this.trustedDomains = [];
874
+
875
+ // if a non-federated server was passed explicitly, it should be trusted.
876
+ if (options.server) {
877
+ // if the url includes more than '/arcgis/', trim the rest
878
+ const root = this.getServerRootUrl(options.server);
879
+
880
+ this.federatedServers[root] = {
881
+ token: options.token,
882
+ expires: options.tokenExpires
883
+ };
884
+ }
885
+ this._pendingTokenRequests = {};
886
+ }
887
+
888
+ /**
889
+ * Returns authentication in a format useable in the [ArcGIS API for JavaScript](https://developers.arcgis.com/javascript/).
890
+ *
891
+ * ```js
892
+ * esriId.registerToken(session.toCredential());
893
+ * ```
894
+ *
895
+ * @returns ICredential
896
+ */
897
+ public toCredential(): ICredential {
898
+ return {
899
+ expires: this.tokenExpires.getTime(),
900
+ server: this.portal,
901
+ ssl: this.ssl,
902
+ token: this.token,
903
+ userId: this.username
904
+ };
905
+ }
906
+
907
+ /**
908
+ * Returns information about the currently logged in [user](https://developers.arcgis.com/rest/users-groups-and-items/user.htm). Subsequent calls will *not* result in additional web traffic.
909
+ *
910
+ * ```js
911
+ * session.getUser()
912
+ * .then(response => {
913
+ * console.log(response.role); // "org_admin"
914
+ * })
915
+ * ```
916
+ *
917
+ * @param requestOptions - Options for the request. NOTE: `rawResponse` is not supported by this operation.
918
+ * @returns A Promise that will resolve with the data from the response.
919
+ */
920
+ public getUser(requestOptions?: IRequestOptions): Promise<IUser> {
921
+ if (this._pendingUserRequest) {
922
+ return this._pendingUserRequest;
923
+ } else if (this._user) {
924
+ return Promise.resolve(this._user);
925
+ } else {
926
+ const url = `${this.portal}/community/self`;
927
+
928
+ const options = {
929
+ httpMethod: "GET",
930
+ authentication: this,
931
+ ...requestOptions,
932
+ rawResponse: false
933
+ } as IRequestOptions;
934
+
935
+ this._pendingUserRequest = request(url, options).then((response) => {
936
+ this._user = response;
937
+ this._pendingUserRequest = null;
938
+ return response;
939
+ });
940
+
941
+ return this._pendingUserRequest;
942
+ }
943
+ }
944
+
945
+ /**
946
+ * Returns information about the currently logged in user's [portal](https://developers.arcgis.com/rest/users-groups-and-items/portal-self.htm). Subsequent calls will *not* result in additional web traffic.
947
+ *
948
+ * ```js
949
+ * session.getPortal()
950
+ * .then(response => {
951
+ * console.log(portal.name); // "City of ..."
952
+ * })
953
+ * ```
954
+ *
955
+ * @param requestOptions - Options for the request. NOTE: `rawResponse` is not supported by this operation.
956
+ * @returns A Promise that will resolve with the data from the response.
957
+ */
958
+ public getPortal(requestOptions?: IRequestOptions): Promise<any> {
959
+ if (this._pendingPortalRequest) {
960
+ return this._pendingPortalRequest;
961
+ } else if (this._portalInfo) {
962
+ return Promise.resolve(this._portalInfo);
963
+ } else {
964
+ const url = `${this.portal}/portals/self`;
965
+
966
+ const options = {
967
+ httpMethod: "GET",
968
+ authentication: this,
969
+ ...requestOptions,
970
+ rawResponse: false
971
+ } as IRequestOptions;
972
+
973
+ this._pendingPortalRequest = request(url, options).then((response) => {
974
+ this._portalInfo = response;
975
+ this._pendingPortalRequest = null;
976
+ return response;
977
+ });
978
+
979
+ return this._pendingPortalRequest;
980
+ }
981
+ }
982
+
983
+ /**
984
+ * Returns the username for the currently logged in [user](https://developers.arcgis.com/rest/users-groups-and-items/user.htm). Subsequent calls will *not* result in additional web traffic. This is also used internally when a username is required for some requests but is not present in the options.
985
+ *
986
+ * * ```js
987
+ * session.getUsername()
988
+ * .then(response => {
989
+ * console.log(response); // "casey_jones"
990
+ * })
991
+ * ```
992
+ */
993
+ public getUsername() {
994
+ if (this.username) {
995
+ return Promise.resolve(this.username);
996
+ } else {
997
+ return this.getUser().then((user) => {
998
+ return user.username;
999
+ });
1000
+ }
1001
+ }
1002
+
1003
+ /**
1004
+ * Gets an appropriate token for the given URL. If `portal` is ArcGIS Online and
1005
+ * the request is to an ArcGIS Online domain `token` will be used. If the request
1006
+ * is to the current `portal` the current `token` will also be used. However if
1007
+ * the request is to an unknown server we will validate the server with a request
1008
+ * to our current `portal`.
1009
+ */
1010
+ public getToken(url: string, requestOptions?: ITokenRequestOptions) {
1011
+ if (canUseOnlineToken(this.portal, url)) {
1012
+ return this.getFreshToken(requestOptions);
1013
+ } else if (new RegExp(this.portal, "i").test(url)) {
1014
+ return this.getFreshToken(requestOptions);
1015
+ } else {
1016
+ return this.getTokenForServer(url, requestOptions);
1017
+ }
1018
+ }
1019
+
1020
+ /**
1021
+ * Get application access information for the current user
1022
+ * see `validateAppAccess` function for details
1023
+ *
1024
+ * @param clientId application client id
1025
+ */
1026
+ public validateAppAccess(clientId: string): Promise<IAppAccess> {
1027
+ return this.getToken(this.portal).then((token) => {
1028
+ return validateAppAccess(token, clientId);
1029
+ });
1030
+ }
1031
+
1032
+ public toJSON(): IArcGISIdentityManagerOptions {
1033
+ return {
1034
+ clientId: this.clientId,
1035
+ refreshToken: this.refreshToken,
1036
+ refreshTokenExpires: this.refreshTokenExpires,
1037
+ username: this.username,
1038
+ password: this.password,
1039
+ token: this.token,
1040
+ tokenExpires: this.tokenExpires,
1041
+ portal: this.portal,
1042
+ ssl: this.ssl,
1043
+ tokenDuration: this.tokenDuration,
1044
+ redirectUri: this.redirectUri,
1045
+ refreshTokenTTL: this.refreshTokenTTL,
1046
+ server: this.server
1047
+ };
1048
+ }
1049
+
1050
+ public serialize() {
1051
+ return JSON.stringify(this);
1052
+ }
1053
+ /**
1054
+ * For a "Host" app that embeds other platform apps via iframes, after authenticating the user
1055
+ * and creating a ArcGISIdentityManager, the app can then enable "post message" style authentication by calling
1056
+ * this method.
1057
+ *
1058
+ * Internally this adds an event listener on window for the `message` event
1059
+ *
1060
+ * @param validChildOrigins Array of origins that are allowed to request authentication from the host app
1061
+ */
1062
+ public enablePostMessageAuth(validChildOrigins: string[], win?: any): any {
1063
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
1064
+ if (!win && window) {
1065
+ win = window;
1066
+ }
1067
+ this._hostHandler = this.createPostMessageHandler(validChildOrigins);
1068
+ win.addEventListener("message", this._hostHandler, false);
1069
+ }
1070
+
1071
+ /**
1072
+ * For a "Host" app that has embedded other platform apps via iframes, when the host needs
1073
+ * to transition routes, it should call `ArcGISIdentityManager.disablePostMessageAuth()` to remove
1074
+ * the event listener and prevent memory leaks
1075
+ */
1076
+ public disablePostMessageAuth(win?: any) {
1077
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
1078
+ if (!win && window) {
1079
+ win = window;
1080
+ }
1081
+ win.removeEventListener("message", this._hostHandler, false);
1082
+ }
1083
+
1084
+ /**
1085
+ * Manually refreshes the current `token` and `tokenExpires`.
1086
+ */
1087
+ public refreshSession(
1088
+ requestOptions?: ITokenRequestOptions
1089
+ ): Promise<ArcGISIdentityManager> {
1090
+ // make sure subsequent calls to getUser() don't returned cached metadata
1091
+ this._user = null;
1092
+
1093
+ if (this.username && this.password) {
1094
+ return this.refreshWithUsernameAndPassword(requestOptions);
1095
+ }
1096
+
1097
+ if (this.clientId && this.refreshToken) {
1098
+ return this.refreshWithRefreshToken();
1099
+ }
1100
+
1101
+ return Promise.reject(new ArcGISAuthError("Unable to refresh token."));
1102
+ }
1103
+
1104
+ /**
1105
+ * Determines the root of the ArcGIS Server or Portal for a given URL.
1106
+ *
1107
+ * @param url the URl to determine the root url for.
1108
+ */
1109
+ public getServerRootUrl(url: string) {
1110
+ const [root] = cleanUrl(url).split(
1111
+ /\/rest(\/admin)?\/services(?:\/|#|\?|$)/
1112
+ );
1113
+ const [match, protocol, domainAndPath] = root.match(/(https?:\/\/)(.+)/);
1114
+ const [domain, ...path] = domainAndPath.split("/");
1115
+
1116
+ // only the domain is lowercased because in some cases an org id might be
1117
+ // in the path which cannot be lowercased.
1118
+ return `${protocol}${domain.toLowerCase()}/${path.join("/")}`;
1119
+ }
1120
+
1121
+ /**
1122
+ * Returns the proper [`credentials`] option for `fetch` for a given domain.
1123
+ * See [trusted server](https://enterprise.arcgis.com/en/portal/latest/administer/windows/configure-security.htm#ESRI_SECTION1_70CC159B3540440AB325BE5D89DBE94A).
1124
+ * Used internally by underlying request methods to add support for specific security considerations.
1125
+ *
1126
+ * @param url The url of the request
1127
+ * @returns "include" or "same-origin"
1128
+ */
1129
+ public getDomainCredentials(url: string): RequestCredentials {
1130
+ if (!this.trustedDomains || !this.trustedDomains.length) {
1131
+ return "same-origin";
1132
+ }
1133
+
1134
+ return this.trustedDomains.some((domainWithProtocol) => {
1135
+ return url.startsWith(domainWithProtocol);
1136
+ })
1137
+ ? "include"
1138
+ : "same-origin";
1139
+ }
1140
+
1141
+ /**
1142
+ * Convenience method for {@linkcode ArcGISIdentityManager.destroy} for this instance of `ArcGISIdentityManager`
1143
+ */
1144
+ public signOut() {
1145
+ return ArcGISIdentityManager.destroy(this);
1146
+ }
1147
+
1148
+ /**
1149
+ * Return a function that closes over the validOrigins array and
1150
+ * can be used as an event handler for the `message` event
1151
+ *
1152
+ * @param validOrigins Array of valid origins
1153
+ */
1154
+ private createPostMessageHandler(
1155
+ validOrigins: string[]
1156
+ ): (event: any) => void {
1157
+ // return a function that closes over the validOrigins and
1158
+ // has access to the credential
1159
+ return (event: any) => {
1160
+ // Verify that the origin is valid
1161
+ // Note: do not use regex's here. validOrigins is an array so we're checking that the event's origin
1162
+ // is in the array via exact match. More info about avoiding postMessage xss issues here
1163
+ // https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html#tipsbypasses-in-postmessage-vulnerabilities
1164
+ const isValidOrigin = validOrigins.indexOf(event.origin) > -1;
1165
+ // JSAPI handles this slightly differently - instead of checking a list, it will respond if
1166
+ // event.origin === window.location.origin || event.origin.endsWith('.arcgis.com')
1167
+ // For Hub, and to enable cross domain debugging with port's in urls, we are opting to
1168
+ // use a list of valid origins
1169
+
1170
+ // Ensure the message type is something we want to handle
1171
+ const isValidType = event.data.type === "arcgis:auth:requestCredential";
1172
+ // Ensure we don't pass an expired session forward
1173
+ const isTokenValid = this.tokenExpires.getTime() > Date.now();
1174
+
1175
+ if (isValidOrigin && isValidType) {
1176
+ let msg = {};
1177
+ if (isTokenValid) {
1178
+ const credential = this.toCredential();
1179
+ // the following line allows us to conform to our spec without changing other depended-on functionality
1180
+ // https://github.com/Esri/arcgis-rest-js/blob/master/packages/arcgis-rest-request/post-message-auth-spec.md#arcgisauthcredential
1181
+ credential.server = credential.server.replace("/sharing/rest", "");
1182
+ msg = {
1183
+ type: "arcgis:auth:credential",
1184
+ credential
1185
+ };
1186
+ } else {
1187
+ msg = {
1188
+ type: "arcgis:auth:error",
1189
+ error: {
1190
+ name: "tokenExpiredError",
1191
+ message:
1192
+ "Session token was expired, and not returned to the child application"
1193
+ }
1194
+ };
1195
+ }
1196
+
1197
+ event.source.postMessage(msg, event.origin);
1198
+ }
1199
+ };
1200
+ }
1201
+
1202
+ /**
1203
+ * Validates that a given URL is properly federated with our current `portal`.
1204
+ * Attempts to use the internal `federatedServers` cache first.
1205
+ */
1206
+ private getTokenForServer(
1207
+ url: string,
1208
+ requestOptions?: ITokenRequestOptions
1209
+ ) {
1210
+ // requests to /rest/services/ and /rest/admin/services/ are both valid
1211
+ // Federated servers may have inconsistent casing, so lowerCase it
1212
+ const root = this.getServerRootUrl(url);
1213
+ const existingToken = this.federatedServers[root];
1214
+
1215
+ if (
1216
+ existingToken &&
1217
+ existingToken.expires &&
1218
+ existingToken.expires.getTime() > Date.now()
1219
+ ) {
1220
+ return Promise.resolve(existingToken.token);
1221
+ }
1222
+
1223
+ if (this._pendingTokenRequests[root]) {
1224
+ return this._pendingTokenRequests[root];
1225
+ }
1226
+
1227
+ this._pendingTokenRequests[root] = this.fetchAuthorizedDomains().then(
1228
+ () => {
1229
+ return request(`${root}/rest/info`, {
1230
+ credentials: this.getDomainCredentials(url)
1231
+ })
1232
+ .then((response) => {
1233
+ if (response.owningSystemUrl) {
1234
+ /**
1235
+ * if this server is not owned by this portal
1236
+ * bail out with an error since we know we wont
1237
+ * be able to generate a token
1238
+ */
1239
+ if (!isFederated(response.owningSystemUrl, this.portal)) {
1240
+ throw new ArcGISAuthError(
1241
+ `${url} is not federated with ${this.portal}.`,
1242
+ "NOT_FEDERATED"
1243
+ );
1244
+ } else {
1245
+ /**
1246
+ * if the server is federated, use the relevant token endpoint.
1247
+ */
1248
+ return request(
1249
+ `${response.owningSystemUrl}/sharing/rest/info`,
1250
+ requestOptions
1251
+ );
1252
+ }
1253
+ } else if (
1254
+ response.authInfo &&
1255
+ this.federatedServers[root] !== undefined
1256
+ ) {
1257
+ /**
1258
+ * if its a stand-alone instance of ArcGIS Server that doesn't advertise
1259
+ * federation, but the root server url is recognized, use its built in token endpoint.
1260
+ */
1261
+ return Promise.resolve({
1262
+ authInfo: response.authInfo
1263
+ });
1264
+ } else {
1265
+ throw new ArcGISAuthError(
1266
+ `${url} is not federated with any portal and is not explicitly trusted.`,
1267
+ "NOT_FEDERATED"
1268
+ );
1269
+ }
1270
+ })
1271
+ .then((response: any) => {
1272
+ return response.authInfo.tokenServicesUrl;
1273
+ })
1274
+ .then((tokenServicesUrl: string) => {
1275
+ // an expired token cant be used to generate a new token
1276
+ if (this.token && this.tokenExpires.getTime() > Date.now()) {
1277
+ return generateToken(tokenServicesUrl, {
1278
+ params: {
1279
+ token: this.token,
1280
+ serverUrl: url,
1281
+ expiration: this.tokenDuration,
1282
+ client: "referer"
1283
+ }
1284
+ });
1285
+ // generate an entirely fresh token if necessary
1286
+ } else {
1287
+ return generateToken(tokenServicesUrl, {
1288
+ params: {
1289
+ username: this.username,
1290
+ password: this.password,
1291
+ expiration: this.tokenDuration,
1292
+ client: "referer"
1293
+ }
1294
+ }).then((response: any) => {
1295
+ this._token = response.token;
1296
+ this._tokenExpires = new Date(response.expires);
1297
+ return response;
1298
+ });
1299
+ }
1300
+ })
1301
+ .then((response) => {
1302
+ this.federatedServers[root] = {
1303
+ expires: new Date(response.expires),
1304
+ token: response.token
1305
+ };
1306
+ delete this._pendingTokenRequests[root];
1307
+ return response.token;
1308
+ });
1309
+ }
1310
+ );
1311
+
1312
+ return this._pendingTokenRequests[root];
1313
+ }
1314
+
1315
+ /**
1316
+ * Returns an unexpired token for the current `portal`.
1317
+ */
1318
+ private getFreshToken(requestOptions?: ITokenRequestOptions) {
1319
+ if (this.token && !this.tokenExpires) {
1320
+ return Promise.resolve(this.token);
1321
+ }
1322
+
1323
+ if (
1324
+ this.token &&
1325
+ this.tokenExpires &&
1326
+ this.tokenExpires.getTime() > Date.now()
1327
+ ) {
1328
+ return Promise.resolve(this.token);
1329
+ }
1330
+
1331
+ if (!this._pendingTokenRequests[this.portal]) {
1332
+ this._pendingTokenRequests[this.portal] = this.refreshSession(
1333
+ requestOptions
1334
+ ).then((session) => {
1335
+ this._pendingTokenRequests[this.portal] = null;
1336
+ return session.token;
1337
+ });
1338
+ }
1339
+
1340
+ return this._pendingTokenRequests[this.portal];
1341
+ }
1342
+
1343
+ /**
1344
+ * Refreshes the current `token` and `tokenExpires` with `username` and
1345
+ * `password`.
1346
+ */
1347
+ private refreshWithUsernameAndPassword(
1348
+ requestOptions?: ITokenRequestOptions
1349
+ ) {
1350
+ const options = {
1351
+ params: {
1352
+ username: this.username,
1353
+ password: this.password,
1354
+ expiration: this.tokenDuration
1355
+ },
1356
+ ...requestOptions
1357
+ };
1358
+ return generateToken(`${this.portal}/generateToken`, options).then(
1359
+ (response: any) => {
1360
+ this._token = response.token;
1361
+ this._tokenExpires = new Date(response.expires);
1362
+ return this;
1363
+ }
1364
+ );
1365
+ }
1366
+
1367
+ /**
1368
+ * Refreshes the current `token` and `tokenExpires` with `refreshToken`.
1369
+ */
1370
+ private refreshWithRefreshToken(requestOptions?: ITokenRequestOptions) {
1371
+ if (
1372
+ this.refreshToken &&
1373
+ this.refreshTokenExpires &&
1374
+ this.refreshTokenExpires.getTime() < Date.now()
1375
+ ) {
1376
+ return this.refreshRefreshToken(requestOptions);
1377
+ }
1378
+
1379
+ const options: ITokenRequestOptions = {
1380
+ params: {
1381
+ client_id: this.clientId,
1382
+ refresh_token: this.refreshToken,
1383
+ grant_type: "refresh_token"
1384
+ },
1385
+ ...requestOptions
1386
+ };
1387
+ return fetchToken(`${this.portal}/oauth2/token`, options).then(
1388
+ (response) => {
1389
+ this._token = response.token;
1390
+ this._tokenExpires = response.expires;
1391
+ return this;
1392
+ }
1393
+ );
1394
+ }
1395
+
1396
+ /**
1397
+ * Exchanges an unexpired `refreshToken` for a new one, also updates `token` and
1398
+ * `tokenExpires`.
1399
+ */
1400
+ private refreshRefreshToken(requestOptions?: ITokenRequestOptions) {
1401
+ const options: ITokenRequestOptions = {
1402
+ params: {
1403
+ client_id: this.clientId,
1404
+ refresh_token: this.refreshToken,
1405
+ redirect_uri: this.redirectUri,
1406
+ grant_type: "exchange_refresh_token"
1407
+ },
1408
+ ...requestOptions
1409
+ };
1410
+
1411
+ return fetchToken(`${this.portal}/oauth2/token`, options).then(
1412
+ (response) => {
1413
+ this._token = response.token;
1414
+ this._tokenExpires = response.expires;
1415
+ this._refreshToken = response.refreshToken;
1416
+ this._refreshTokenExpires = new Date(
1417
+ Date.now() + (this.refreshTokenTTL - 1) * 60 * 1000
1418
+ );
1419
+ return this;
1420
+ }
1421
+ );
1422
+ }
1423
+
1424
+ /**
1425
+ * ensures that the authorizedCrossOriginDomains are obtained from the portal and cached
1426
+ * so we can check them later.
1427
+ *
1428
+ * @returns this
1429
+ */
1430
+ private fetchAuthorizedDomains() {
1431
+ // if this token is for a specific server or we don't have a portal
1432
+ // don't get the portal info because we cant get the authorizedCrossOriginDomains
1433
+ if (this.server || !this.portal) {
1434
+ return Promise.resolve(this);
1435
+ }
1436
+
1437
+ return this.getPortal().then((portalInfo) => {
1438
+ /**
1439
+ * Specific domains can be configured as secure.esri.com or https://secure.esri.com this
1440
+ * normalizes to https://secure.esri.com so we can use startsWith later.
1441
+ */
1442
+ if (
1443
+ portalInfo.authorizedCrossOriginDomains &&
1444
+ portalInfo.authorizedCrossOriginDomains.length
1445
+ ) {
1446
+ this.trustedDomains = portalInfo.authorizedCrossOriginDomains
1447
+ .filter((d: string) => !d.startsWith("http://"))
1448
+ .map((d: string) => {
1449
+ if (d.startsWith("https://")) {
1450
+ return d;
1451
+ } else {
1452
+ return `https://${d}`;
1453
+ }
1454
+ });
1455
+ }
1456
+ return this;
1457
+ });
1458
+ }
1459
+ }
1460
+
1461
+ /**
1462
+ * @deprecated - Use {@linkcode ArcGISIdentityManager}.
1463
+ */ /* istanbul ignore next */
1464
+ export function UserSession(options: IArcGISIdentityManagerOptions) {
1465
+ console.log(
1466
+ "DEPRECATED:, 'UserSession' is deprecated. Use 'ArcGISIdentityManagerOptions' instead."
1467
+ );
1468
+
1469
+ return new ArcGISIdentityManager(options);
1470
+ }