impeditmaiores 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (421) hide show
  1. package/.prettierignore +2 -0
  2. package/.travis.yml +35 -0
  3. package/.vscode/launch.json +24 -0
  4. package/.vscode/settings.json +3 -0
  5. package/codecov.yml +7 -0
  6. package/demos/ago-node-cli/README.md +29 -0
  7. package/demos/ago-node-cli/ago.js +33 -0
  8. package/demos/ago-node-cli/index.js +11 -0
  9. package/demos/ago-node-cli/lib/item-export-command.js +48 -0
  10. package/demos/ago-node-cli/lib/item-search-command.js +35 -0
  11. package/demos/ago-node-cli/package-lock.json +152 -0
  12. package/demos/ago-node-cli/package.json +30 -0
  13. package/demos/attachments/README.md +5 -0
  14. package/demos/attachments/index.html +165 -0
  15. package/demos/attachments/package-lock.json +182 -0
  16. package/demos/attachments/package.json +18 -0
  17. package/demos/batch-geocoder-node/NYC_Restaurant_Inspection_Results.csv +100 -0
  18. package/demos/batch-geocoder-node/README.md +15 -0
  19. package/demos/batch-geocoder-node/batch-geocode.js +115 -0
  20. package/demos/batch-geocoder-node/config-template.js +18 -0
  21. package/demos/batch-geocoder-node/package-lock.json +81 -0
  22. package/demos/batch-geocoder-node/package.json +37 -0
  23. package/demos/express/README.md +15 -0
  24. package/demos/express/config.json.template +3 -0
  25. package/demos/express/package-lock.json +413 -0
  26. package/demos/express/package.json +18 -0
  27. package/demos/express/server.js +33 -0
  28. package/demos/feature-service-browser/README.md +6 -0
  29. package/demos/feature-service-browser/index.html +122 -0
  30. package/demos/feature-service-browser/package-lock.json +182 -0
  31. package/demos/feature-service-browser/package.json +18 -0
  32. package/demos/geocoder-browser/README.md +10 -0
  33. package/demos/geocoder-browser/config.js.template +1 -0
  34. package/demos/geocoder-browser/index.html +131 -0
  35. package/demos/geocoder-browser/package-lock.json +182 -0
  36. package/demos/geocoder-browser/package.json +19 -0
  37. package/demos/geocoder-browser/post-sign-in.html +25 -0
  38. package/demos/jsapi-integration/README.md +25 -0
  39. package/demos/jsapi-integration/config.js +6 -0
  40. package/demos/jsapi-integration/index.html +89 -0
  41. package/demos/jsapi-integration/package-lock.json +184 -0
  42. package/demos/jsapi-integration/package.json +19 -0
  43. package/demos/node-cli-item-management/README.md +10 -0
  44. package/demos/node-cli-item-management/index.js +238 -0
  45. package/demos/node-cli-item-management/package-lock.json +152 -0
  46. package/demos/node-cli-item-management/package.json +27 -0
  47. package/demos/node-cli-item-management/screenshot.png +0 -0
  48. package/demos/oauth2-browser/README.md +14 -0
  49. package/demos/oauth2-browser/authenticate.html +30 -0
  50. package/demos/oauth2-browser/config.js.template +6 -0
  51. package/demos/oauth2-browser/index.html +211 -0
  52. package/demos/oauth2-browser/logo.svg +4 -0
  53. package/demos/oauth2-browser/package-lock.json +224 -0
  54. package/demos/oauth2-browser/package.json +18 -0
  55. package/demos/oauth2-browser/style.css +36 -0
  56. package/demos/oauth2-browser-retry/README.md +25 -0
  57. package/demos/oauth2-browser-retry/authenticate.html +22 -0
  58. package/demos/oauth2-browser-retry/index.html +116 -0
  59. package/demos/oauth2-browser-retry/logo.svg +4 -0
  60. package/demos/stream-response-to-file/README.md +7 -0
  61. package/demos/stream-response-to-file/index.js +36 -0
  62. package/demos/stream-response-to-file/output/.gitkeep +0 -0
  63. package/demos/stream-response-to-file/package-lock.json +60 -0
  64. package/demos/stream-response-to-file/package.json +33 -0
  65. package/demos/tree-shaking-rollup/.babelrc +3 -0
  66. package/demos/tree-shaking-rollup/README.md +9 -0
  67. package/demos/tree-shaking-rollup/index.html +11 -0
  68. package/demos/tree-shaking-rollup/package-lock.json +2225 -0
  69. package/demos/tree-shaking-rollup/package.json +25 -0
  70. package/demos/tree-shaking-rollup/rollup.config.js +17 -0
  71. package/demos/tree-shaking-rollup/src/index.js +8 -0
  72. package/demos/tree-shaking-webpack/README.md +8 -0
  73. package/demos/tree-shaking-webpack/index.html +11 -0
  74. package/demos/tree-shaking-webpack/package-lock.json +4614 -0
  75. package/demos/tree-shaking-webpack/package.json +24 -0
  76. package/demos/tree-shaking-webpack/src/index.js +10 -0
  77. package/demos/tree-shaking-webpack/webpack.config.js +27 -0
  78. package/demos/vue/.env.example +11 -0
  79. package/demos/vue/.eslintrc.js +17 -0
  80. package/demos/vue/.postcssrc.js +5 -0
  81. package/demos/vue/README.md +17 -0
  82. package/demos/vue/babel.config.js +3 -0
  83. package/demos/vue/package-lock.json +11342 -0
  84. package/demos/vue/package.json +33 -0
  85. package/demos/vue/public/favicon.ico +0 -0
  86. package/demos/vue/public/index.html +24 -0
  87. package/demos/vue/src/assets/logo.svg +29 -0
  88. package/demos/vue/src/components/App.vue +305 -0
  89. package/demos/vue/src/components/Authenticate.vue +65 -0
  90. package/demos/vue/src/components/Loader.vue +230 -0
  91. package/demos/vue/src/main.js +92 -0
  92. package/demos/webmap-checker-sapper/.env.example +5 -0
  93. package/demos/webmap-checker-sapper/README.md +123 -0
  94. package/demos/webmap-checker-sapper/appveyor.yml +18 -0
  95. package/demos/webmap-checker-sapper/cypress/fixtures/example.json +5 -0
  96. package/demos/webmap-checker-sapper/cypress/integration/spec.js +19 -0
  97. package/demos/webmap-checker-sapper/cypress/plugins/index.js +17 -0
  98. package/demos/webmap-checker-sapper/cypress/support/commands.js +25 -0
  99. package/demos/webmap-checker-sapper/cypress/support/index.js +20 -0
  100. package/demos/webmap-checker-sapper/cypress.json +4 -0
  101. package/demos/webmap-checker-sapper/package-lock.json +3870 -0
  102. package/demos/webmap-checker-sapper/package.json +50 -0
  103. package/demos/webmap-checker-sapper/rollup.config.js +87 -0
  104. package/demos/webmap-checker-sapper/src/client.js +20 -0
  105. package/demos/webmap-checker-sapper/src/components/LayerStatus.html +108 -0
  106. package/demos/webmap-checker-sapper/src/components/Nav.html +21 -0
  107. package/demos/webmap-checker-sapper/src/components/WebMap.html +62 -0
  108. package/demos/webmap-checker-sapper/src/routes/_error.html +41 -0
  109. package/demos/webmap-checker-sapper/src/routes/_layout.html +21 -0
  110. package/demos/webmap-checker-sapper/src/routes/auth/authorize.js +18 -0
  111. package/demos/webmap-checker-sapper/src/routes/auth/exchange-token.js +20 -0
  112. package/demos/webmap-checker-sapper/src/routes/auth/post-sign-in.js +24 -0
  113. package/demos/webmap-checker-sapper/src/routes/auth/sign-out.js +10 -0
  114. package/demos/webmap-checker-sapper/src/routes/index.html +20 -0
  115. package/demos/webmap-checker-sapper/src/routes/webmaps/[webmapId].html +83 -0
  116. package/demos/webmap-checker-sapper/src/routes/webmaps/index.html +59 -0
  117. package/demos/webmap-checker-sapper/src/server.js +101 -0
  118. package/demos/webmap-checker-sapper/src/service-worker.js +82 -0
  119. package/demos/webmap-checker-sapper/src/template.html +33 -0
  120. package/demos/webmap-checker-sapper/src/userInfoMiddleware.js +21 -0
  121. package/demos/webmap-checker-sapper/src/utils.js +33 -0
  122. package/demos/webmap-checker-sapper/static/favicon.png +0 -0
  123. package/demos/webmap-checker-sapper/static/global.css +36 -0
  124. package/demos/webmap-checker-sapper/static/manifest.json +20 -0
  125. package/demos/webmap-checker-sapper/static/svelte-logo-192.png +0 -0
  126. package/demos/webmap-checker-sapper/static/svelte-logo-512.png +0 -0
  127. package/docs/FAQ.md +48 -0
  128. package/docs/HISTORY.md +62 -0
  129. package/docs/acetate.config.js +262 -0
  130. package/docs/build-typedoc.js +434 -0
  131. package/docs/generate-srihashes.js +53 -0
  132. package/docs/src/_layout.html +86 -0
  133. package/docs/src/api/_declaration.html +600 -0
  134. package/docs/src/api/_layout.html +204 -0
  135. package/docs/src/api/_package.html +38 -0
  136. package/docs/src/api/index.html +16 -0
  137. package/docs/src/guides/_layout.html +24 -0
  138. package/docs/src/guides/amd-requirejs-dojo.md +40 -0
  139. package/docs/src/guides/browser-authentication.md +41 -0
  140. package/docs/src/guides/bundlers.md +52 -0
  141. package/docs/src/guides/cli-authentication.md +9 -0
  142. package/docs/src/guides/client-server-authentication.md +9 -0
  143. package/docs/src/guides/embedded-apps.md +93 -0
  144. package/docs/src/guides/from-a-cdn.md +38 -0
  145. package/docs/src/guides/index.md +59 -0
  146. package/docs/src/guides/node.md +87 -0
  147. package/docs/src/guides/package-overview.md +111 -0
  148. package/docs/src/guides/server-authentication.md +9 -0
  149. package/docs/src/guides/whats-new-v2-0.md +305 -0
  150. package/docs/src/img/icons.png +0 -0
  151. package/docs/src/img/icons@2x.png +0 -0
  152. package/docs/src/index.html +12 -0
  153. package/docs/src/js/api-search.js +112 -0
  154. package/docs/src/js/nav-toggle.js +41 -0
  155. package/docs/src/sass/_highlight.scss +96 -0
  156. package/docs/src/sass/_icons.scss +157 -0
  157. package/docs/src/sass/style.scss +242 -0
  158. package/docs/src/srihashes.json +12 -0
  159. package/jasmine.json +7 -0
  160. package/karma.conf.js +106 -0
  161. package/lerna.json +8 -0
  162. package/notes/README.md +68 -0
  163. package/package.json +87 -0
  164. package/packages/arcgis-rest-auth/README.md +71 -0
  165. package/packages/arcgis-rest-auth/package-lock.json +11 -0
  166. package/packages/arcgis-rest-auth/package.json +69 -0
  167. package/packages/arcgis-rest-auth/src/ApplicationSession.ts +122 -0
  168. package/packages/arcgis-rest-auth/src/UserSession.ts +1206 -0
  169. package/packages/arcgis-rest-auth/src/app-tokens.ts +91 -0
  170. package/packages/arcgis-rest-auth/src/authenticated-request-options.ts +24 -0
  171. package/packages/arcgis-rest-auth/src/federation-utils.ts +85 -0
  172. package/packages/arcgis-rest-auth/src/fetch-token.ts +50 -0
  173. package/packages/arcgis-rest-auth/src/generate-token.ts +35 -0
  174. package/packages/arcgis-rest-auth/src/index.ts +9 -0
  175. package/packages/arcgis-rest-auth/src/validate-app-access.ts +68 -0
  176. package/packages/arcgis-rest-auth/test/ApplicationSession.test.ts +124 -0
  177. package/packages/arcgis-rest-auth/test/UserSession.test.ts +1807 -0
  178. package/packages/arcgis-rest-auth/test/app-tokens.test.ts +91 -0
  179. package/packages/arcgis-rest-auth/test/federation-utils.test.ts +323 -0
  180. package/packages/arcgis-rest-auth/test/fetchToken.test.ts +112 -0
  181. package/packages/arcgis-rest-auth/test/generateToken.test.ts +102 -0
  182. package/packages/arcgis-rest-auth/test/utils.ts +14 -0
  183. package/packages/arcgis-rest-auth/test/validate-app-access.test.ts +46 -0
  184. package/packages/arcgis-rest-auth/tsconfig.json +6 -0
  185. package/packages/arcgis-rest-feature-layer/README.md +77 -0
  186. package/packages/arcgis-rest-feature-layer/package-lock.json +11 -0
  187. package/packages/arcgis-rest-feature-layer/package.json +64 -0
  188. package/packages/arcgis-rest-feature-layer/src/add.ts +56 -0
  189. package/packages/arcgis-rest-feature-layer/src/addAttachment.ts +53 -0
  190. package/packages/arcgis-rest-feature-layer/src/applyEdits.ts +90 -0
  191. package/packages/arcgis-rest-feature-layer/src/decodeValues.ts +124 -0
  192. package/packages/arcgis-rest-feature-layer/src/delete.ts +61 -0
  193. package/packages/arcgis-rest-feature-layer/src/deleteAttachments.ts +52 -0
  194. package/packages/arcgis-rest-feature-layer/src/getAttachments.ts +55 -0
  195. package/packages/arcgis-rest-feature-layer/src/getLayer.ts +24 -0
  196. package/packages/arcgis-rest-feature-layer/src/getService.ts +26 -0
  197. package/packages/arcgis-rest-feature-layer/src/helpers.ts +79 -0
  198. package/packages/arcgis-rest-feature-layer/src/index.ts +31 -0
  199. package/packages/arcgis-rest-feature-layer/src/query.ts +204 -0
  200. package/packages/arcgis-rest-feature-layer/src/queryRelated.ts +89 -0
  201. package/packages/arcgis-rest-feature-layer/src/update.ts +56 -0
  202. package/packages/arcgis-rest-feature-layer/src/updateAttachment.ts +59 -0
  203. package/packages/arcgis-rest-feature-layer/test/attachments.test.ts +200 -0
  204. package/packages/arcgis-rest-feature-layer/test/crud.test.ts +195 -0
  205. package/packages/arcgis-rest-feature-layer/test/decodeValues.test.ts +67 -0
  206. package/packages/arcgis-rest-feature-layer/test/getLayer.test.ts +31 -0
  207. package/packages/arcgis-rest-feature-layer/test/getService.test.ts +31 -0
  208. package/packages/arcgis-rest-feature-layer/test/mocks/cvdQueryResponse.ts +225 -0
  209. package/packages/arcgis-rest-feature-layer/test/mocks/feature.ts +302 -0
  210. package/packages/arcgis-rest-feature-layer/test/mocks/fields.ts +779 -0
  211. package/packages/arcgis-rest-feature-layer/test/mocks/foo.txt +1 -0
  212. package/packages/arcgis-rest-feature-layer/test/mocks/service.ts +398 -0
  213. package/packages/arcgis-rest-feature-layer/test/query.test.ts +167 -0
  214. package/packages/arcgis-rest-feature-layer/tsconfig.json +6 -0
  215. package/packages/arcgis-rest-geocoding/README.md +86 -0
  216. package/packages/arcgis-rest-geocoding/package-lock.json +11 -0
  217. package/packages/arcgis-rest-geocoding/package.json +64 -0
  218. package/packages/arcgis-rest-geocoding/src/bulk.ts +104 -0
  219. package/packages/arcgis-rest-geocoding/src/geocode.ts +133 -0
  220. package/packages/arcgis-rest-geocoding/src/helpers.ts +54 -0
  221. package/packages/arcgis-rest-geocoding/src/index.ts +15 -0
  222. package/packages/arcgis-rest-geocoding/src/reverse.ts +84 -0
  223. package/packages/arcgis-rest-geocoding/src/suggest.ts +45 -0
  224. package/packages/arcgis-rest-geocoding/test/bulk.test.ts +194 -0
  225. package/packages/arcgis-rest-geocoding/test/geocode.test.ts +249 -0
  226. package/packages/arcgis-rest-geocoding/test/helpers.test.ts +85 -0
  227. package/packages/arcgis-rest-geocoding/test/mocks/responses.ts +637 -0
  228. package/packages/arcgis-rest-geocoding/test/reverse.test.ts +126 -0
  229. package/packages/arcgis-rest-geocoding/test/suggest.test.ts +53 -0
  230. package/packages/arcgis-rest-geocoding/tsconfig.json +6 -0
  231. package/packages/arcgis-rest-portal/README.md +73 -0
  232. package/packages/arcgis-rest-portal/package-lock.json +11 -0
  233. package/packages/arcgis-rest-portal/package.json +64 -0
  234. package/packages/arcgis-rest-portal/src/groups/add-users.ts +140 -0
  235. package/packages/arcgis-rest-portal/src/groups/create.ts +43 -0
  236. package/packages/arcgis-rest-portal/src/groups/get.ts +184 -0
  237. package/packages/arcgis-rest-portal/src/groups/helpers.ts +14 -0
  238. package/packages/arcgis-rest-portal/src/groups/invite-users.ts +127 -0
  239. package/packages/arcgis-rest-portal/src/groups/join.ts +57 -0
  240. package/packages/arcgis-rest-portal/src/groups/notification.ts +77 -0
  241. package/packages/arcgis-rest-portal/src/groups/protect.ts +56 -0
  242. package/packages/arcgis-rest-portal/src/groups/remove-users.ts +76 -0
  243. package/packages/arcgis-rest-portal/src/groups/remove.ts +32 -0
  244. package/packages/arcgis-rest-portal/src/groups/search.ts +47 -0
  245. package/packages/arcgis-rest-portal/src/groups/update-user-membership.ts +63 -0
  246. package/packages/arcgis-rest-portal/src/groups/update.ts +39 -0
  247. package/packages/arcgis-rest-portal/src/index.ts +66 -0
  248. package/packages/arcgis-rest-portal/src/items/add.ts +138 -0
  249. package/packages/arcgis-rest-portal/src/items/content.ts +67 -0
  250. package/packages/arcgis-rest-portal/src/items/create.ts +150 -0
  251. package/packages/arcgis-rest-portal/src/items/export.ts +80 -0
  252. package/packages/arcgis-rest-portal/src/items/get.ts +437 -0
  253. package/packages/arcgis-rest-portal/src/items/helpers.ts +275 -0
  254. package/packages/arcgis-rest-portal/src/items/protect.ts +41 -0
  255. package/packages/arcgis-rest-portal/src/items/reassign.ts +61 -0
  256. package/packages/arcgis-rest-portal/src/items/remove.ts +135 -0
  257. package/packages/arcgis-rest-portal/src/items/search.ts +25 -0
  258. package/packages/arcgis-rest-portal/src/items/update.ts +184 -0
  259. package/packages/arcgis-rest-portal/src/items/upload.ts +125 -0
  260. package/packages/arcgis-rest-portal/src/orgs/notification.ts +131 -0
  261. package/packages/arcgis-rest-portal/src/sharing/access.ts +84 -0
  262. package/packages/arcgis-rest-portal/src/sharing/helpers.ts +81 -0
  263. package/packages/arcgis-rest-portal/src/sharing/is-item-shared-with-group.ts +42 -0
  264. package/packages/arcgis-rest-portal/src/sharing/share-item-with-group.ts +319 -0
  265. package/packages/arcgis-rest-portal/src/sharing/unshare-item-with-group.ts +105 -0
  266. package/packages/arcgis-rest-portal/src/users/get-user-tags.ts +52 -0
  267. package/packages/arcgis-rest-portal/src/users/get-user-url.ts +18 -0
  268. package/packages/arcgis-rest-portal/src/users/get-user.ts +58 -0
  269. package/packages/arcgis-rest-portal/src/users/invitation.ts +156 -0
  270. package/packages/arcgis-rest-portal/src/users/notification.ts +68 -0
  271. package/packages/arcgis-rest-portal/src/users/search-users.ts +37 -0
  272. package/packages/arcgis-rest-portal/src/users/update.ts +66 -0
  273. package/packages/arcgis-rest-portal/src/util/SearchQueryBuilder.ts +374 -0
  274. package/packages/arcgis-rest-portal/src/util/array.ts +16 -0
  275. package/packages/arcgis-rest-portal/src/util/generic-search.ts +99 -0
  276. package/packages/arcgis-rest-portal/src/util/get-portal-settings.ts +45 -0
  277. package/packages/arcgis-rest-portal/src/util/get-portal-url.ts +27 -0
  278. package/packages/arcgis-rest-portal/src/util/get-portal.ts +52 -0
  279. package/packages/arcgis-rest-portal/src/util/get-subscription-info.ts +43 -0
  280. package/packages/arcgis-rest-portal/src/util/scrub-control-chars.ts +12 -0
  281. package/packages/arcgis-rest-portal/src/util/search.ts +42 -0
  282. package/packages/arcgis-rest-portal/test/groups/add-users.test.ts +239 -0
  283. package/packages/arcgis-rest-portal/test/groups/crud.test.ts +180 -0
  284. package/packages/arcgis-rest-portal/test/groups/get.test.ts +176 -0
  285. package/packages/arcgis-rest-portal/test/groups/invite-users.test.ts +149 -0
  286. package/packages/arcgis-rest-portal/test/groups/join.test.ts +72 -0
  287. package/packages/arcgis-rest-portal/test/groups/notification.test.ts +112 -0
  288. package/packages/arcgis-rest-portal/test/groups/protect.test.ts +72 -0
  289. package/packages/arcgis-rest-portal/test/groups/remove-users.test.ts +140 -0
  290. package/packages/arcgis-rest-portal/test/groups/search.test.ts +151 -0
  291. package/packages/arcgis-rest-portal/test/groups/update-user-membership.test.ts +62 -0
  292. package/packages/arcgis-rest-portal/test/items/add.test.ts +323 -0
  293. package/packages/arcgis-rest-portal/test/items/content.test.ts +156 -0
  294. package/packages/arcgis-rest-portal/test/items/create.test.ts +399 -0
  295. package/packages/arcgis-rest-portal/test/items/export.test.ts +122 -0
  296. package/packages/arcgis-rest-portal/test/items/get.test.ts +583 -0
  297. package/packages/arcgis-rest-portal/test/items/helpers.test.ts +60 -0
  298. package/packages/arcgis-rest-portal/test/items/protect.test.ts +122 -0
  299. package/packages/arcgis-rest-portal/test/items/reassign.test.ts +131 -0
  300. package/packages/arcgis-rest-portal/test/items/remove.test.ts +238 -0
  301. package/packages/arcgis-rest-portal/test/items/search.test.ts +272 -0
  302. package/packages/arcgis-rest-portal/test/items/update.test.ts +554 -0
  303. package/packages/arcgis-rest-portal/test/items/upload.test.ts +282 -0
  304. package/packages/arcgis-rest-portal/test/mocks/groups/responses.ts +208 -0
  305. package/packages/arcgis-rest-portal/test/mocks/items/foo.zip +0 -0
  306. package/packages/arcgis-rest-portal/test/mocks/items/item.ts +526 -0
  307. package/packages/arcgis-rest-portal/test/mocks/items/resources.ts +38 -0
  308. package/packages/arcgis-rest-portal/test/mocks/items/search.ts +121 -0
  309. package/packages/arcgis-rest-portal/test/mocks/portal/response.ts +126 -0
  310. package/packages/arcgis-rest-portal/test/mocks/portal/settings-response.ts +56 -0
  311. package/packages/arcgis-rest-portal/test/mocks/sharing/sharing.ts +18 -0
  312. package/packages/arcgis-rest-portal/test/mocks/users/invitation.ts +70 -0
  313. package/packages/arcgis-rest-portal/test/mocks/users/notification.ts +34 -0
  314. package/packages/arcgis-rest-portal/test/mocks/users/user-search.ts +388 -0
  315. package/packages/arcgis-rest-portal/test/mocks/users/user-tags.ts +5 -0
  316. package/packages/arcgis-rest-portal/test/mocks/users/user.ts +174 -0
  317. package/packages/arcgis-rest-portal/test/orgs/notification.test.ts +142 -0
  318. package/packages/arcgis-rest-portal/test/sharing/access.test.ts +162 -0
  319. package/packages/arcgis-rest-portal/test/sharing/helpers.test.ts +55 -0
  320. package/packages/arcgis-rest-portal/test/sharing/share-item-with-group.test.ts +1325 -0
  321. package/packages/arcgis-rest-portal/test/sharing/unshare-item-with-group.test.ts +288 -0
  322. package/packages/arcgis-rest-portal/test/users/get-user-tags.test.ts +71 -0
  323. package/packages/arcgis-rest-portal/test/users/get-user-url.test.ts +40 -0
  324. package/packages/arcgis-rest-portal/test/users/get-user.test.ts +90 -0
  325. package/packages/arcgis-rest-portal/test/users/invitation.test.ts +127 -0
  326. package/packages/arcgis-rest-portal/test/users/notification.test.ts +77 -0
  327. package/packages/arcgis-rest-portal/test/users/search.test.ts +42 -0
  328. package/packages/arcgis-rest-portal/test/users/update.test.ts +151 -0
  329. package/packages/arcgis-rest-portal/test/util/SearchQueryBuilder.test.ts +340 -0
  330. package/packages/arcgis-rest-portal/test/util/array.test.ts +30 -0
  331. package/packages/arcgis-rest-portal/test/util/get-portal-settings.test.ts +68 -0
  332. package/packages/arcgis-rest-portal/test/util/get-portal-url.test.ts +37 -0
  333. package/packages/arcgis-rest-portal/test/util/portal.test.ts +148 -0
  334. package/packages/arcgis-rest-portal/test/util/scrub-control-chars.test.ts +22 -0
  335. package/packages/arcgis-rest-portal/tsconfig.json +6 -0
  336. package/packages/arcgis-rest-request/README.md +72 -0
  337. package/packages/arcgis-rest-request/package-lock.json +11 -0
  338. package/packages/arcgis-rest-request/package.json +60 -0
  339. package/packages/arcgis-rest-request/src/index.ts +25 -0
  340. package/packages/arcgis-rest-request/src/request.ts +413 -0
  341. package/packages/arcgis-rest-request/src/utils/ArcGISRequestError.ts +76 -0
  342. package/packages/arcgis-rest-request/src/utils/ErrorTypes.ts +29 -0
  343. package/packages/arcgis-rest-request/src/utils/GrantTypes.ts +5 -0
  344. package/packages/arcgis-rest-request/src/utils/HTTPMethods.ts +6 -0
  345. package/packages/arcgis-rest-request/src/utils/IAuthenticationManager.ts +21 -0
  346. package/packages/arcgis-rest-request/src/utils/IFetchTokenParams.ts +11 -0
  347. package/packages/arcgis-rest-request/src/utils/IGenerateTokenParams.ts +9 -0
  348. package/packages/arcgis-rest-request/src/utils/IParamBuilder.ts +3 -0
  349. package/packages/arcgis-rest-request/src/utils/IParams.ts +6 -0
  350. package/packages/arcgis-rest-request/src/utils/IParamsBuilder.ts +5 -0
  351. package/packages/arcgis-rest-request/src/utils/IRequestOptions.ts +49 -0
  352. package/packages/arcgis-rest-request/src/utils/ITokenRequestOptions.ts +9 -0
  353. package/packages/arcgis-rest-request/src/utils/ResponseFormats.ts +10 -0
  354. package/packages/arcgis-rest-request/src/utils/append-custom-params.ts +49 -0
  355. package/packages/arcgis-rest-request/src/utils/clean-url.ts +20 -0
  356. package/packages/arcgis-rest-request/src/utils/decode-query-string.ts +27 -0
  357. package/packages/arcgis-rest-request/src/utils/encode-form-data.ts +38 -0
  358. package/packages/arcgis-rest-request/src/utils/encode-query-string.ts +35 -0
  359. package/packages/arcgis-rest-request/src/utils/process-params.ts +108 -0
  360. package/packages/arcgis-rest-request/src/utils/retryAuthError.ts +10 -0
  361. package/packages/arcgis-rest-request/src/utils/warn.ts +11 -0
  362. package/packages/arcgis-rest-request/src/utils/with-options.ts +48 -0
  363. package/packages/arcgis-rest-request/test/mocks/errors.ts +76 -0
  364. package/packages/arcgis-rest-request/test/mocks/geojson-feature-collection.ts +13 -0
  365. package/packages/arcgis-rest-request/test/mocks/param-builder.ts +7 -0
  366. package/packages/arcgis-rest-request/test/mocks/sharing-rest-info.ts +41 -0
  367. package/packages/arcgis-rest-request/test/mocks/webmap.ts +41 -0
  368. package/packages/arcgis-rest-request/test/request.test.ts +571 -0
  369. package/packages/arcgis-rest-request/test/utils/ArcGISAuthError.test.ts +191 -0
  370. package/packages/arcgis-rest-request/test/utils/ArcGISRequestError.test.ts +51 -0
  371. package/packages/arcgis-rest-request/test/utils/check-for-errors.test.ts +111 -0
  372. package/packages/arcgis-rest-request/test/utils/clean-url.test.ts +50 -0
  373. package/packages/arcgis-rest-request/test/utils/encode-form-data.test.ts +133 -0
  374. package/packages/arcgis-rest-request/test/utils/encode-query-string.test.ts +18 -0
  375. package/packages/arcgis-rest-request/test/utils/process-params.test.ts +205 -0
  376. package/packages/arcgis-rest-request/test/utils/with-options.test.ts +133 -0
  377. package/packages/arcgis-rest-request/tsconfig.json +4 -0
  378. package/packages/arcgis-rest-routing/README.md +75 -0
  379. package/packages/arcgis-rest-routing/package-lock.json +11 -0
  380. package/packages/arcgis-rest-routing/package.json +63 -0
  381. package/packages/arcgis-rest-routing/src/helpers.ts +16 -0
  382. package/packages/arcgis-rest-routing/src/index.ts +11 -0
  383. package/packages/arcgis-rest-routing/src/solveRoute.ts +124 -0
  384. package/packages/arcgis-rest-routing/test/mocks/responses.ts +825 -0
  385. package/packages/arcgis-rest-routing/test/solveRoute.test.ts +509 -0
  386. package/packages/arcgis-rest-routing/tsconfig.json +6 -0
  387. package/packages/arcgis-rest-service-admin/README.md +73 -0
  388. package/packages/arcgis-rest-service-admin/package-lock.json +11 -0
  389. package/packages/arcgis-rest-service-admin/package.json +65 -0
  390. package/packages/arcgis-rest-service-admin/src/addTo.ts +70 -0
  391. package/packages/arcgis-rest-service-admin/src/create.ts +189 -0
  392. package/packages/arcgis-rest-service-admin/src/index.ts +11 -0
  393. package/packages/arcgis-rest-service-admin/src/update.ts +50 -0
  394. package/packages/arcgis-rest-service-admin/test/addTo.test.ts +350 -0
  395. package/packages/arcgis-rest-service-admin/test/create.test.ts +294 -0
  396. package/packages/arcgis-rest-service-admin/test/mocks/layerDefinition.ts +79 -0
  397. package/packages/arcgis-rest-service-admin/test/mocks/service.ts +81 -0
  398. package/packages/arcgis-rest-service-admin/test/update.test.ts +115 -0
  399. package/packages/arcgis-rest-service-admin/tsconfig.json +6 -0
  400. package/packages/arcgis-rest-types/README.md +66 -0
  401. package/packages/arcgis-rest-types/package.json +54 -0
  402. package/packages/arcgis-rest-types/src/feature.ts +39 -0
  403. package/packages/arcgis-rest-types/src/geometry.ts +272 -0
  404. package/packages/arcgis-rest-types/src/group.ts +72 -0
  405. package/packages/arcgis-rest-types/src/index.ts +9 -0
  406. package/packages/arcgis-rest-types/src/item.ts +81 -0
  407. package/packages/arcgis-rest-types/src/service.ts +114 -0
  408. package/packages/arcgis-rest-types/src/statisticDefinition.ts +33 -0
  409. package/packages/arcgis-rest-types/src/symbol.ts +170 -0
  410. package/packages/arcgis-rest-types/src/user.ts +49 -0
  411. package/packages/arcgis-rest-types/src/webmap.ts +1367 -0
  412. package/packages/arcgis-rest-types/tsconfig.json +10 -0
  413. package/support/changelog.js +393 -0
  414. package/support/deploy-doc-site.js +16 -0
  415. package/support/dev.sh +6 -0
  416. package/support/publish.sh +47 -0
  417. package/support/test-helpers.js +9 -0
  418. package/tsconfig.json +63 -0
  419. package/tslint.json +16 -0
  420. package/umd-base-profile.js +81 -0
  421. package/umd-production-profile.js +13 -0
@@ -0,0 +1,1206 @@
1
+ /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
2
+ * Apache-2.0 */
3
+
4
+ /**
5
+ * /generateToken returns a token that cannot be refreshed.
6
+ *
7
+ * oauth2/token can return a token *and* a refreshToken.
8
+ * up until the refreshToken expires, you can use it (and a clientId)
9
+ * to fetch fresh credentials without a username and password.
10
+ *
11
+ * the catch is that this 'authorization_code' flow is only utilized
12
+ * by server based OAuth 2 Node.js applications that call /authorize first.
13
+ */
14
+
15
+ import * as http from "http";
16
+ import {
17
+ request,
18
+ IRequestOptions,
19
+ ArcGISAuthError,
20
+ IAuthenticationManager,
21
+ ITokenRequestOptions,
22
+ cleanUrl,
23
+ encodeQueryString,
24
+ decodeQueryString,
25
+ } from "@esri/arcgis-rest-request";
26
+ import { IUser } from "@esri/arcgis-rest-types";
27
+ import { generateToken } from "./generate-token";
28
+ import { fetchToken, IFetchTokenResponse } from "./fetch-token";
29
+ import { canUseOnlineToken, isFederated } from "./federation-utils";
30
+ import { IAppAccess, validateAppAccess } from "./validate-app-access";
31
+
32
+ /**
33
+ * Internal utility for resolving a Promise from outside its constructor.
34
+ *
35
+ * See: http://lea.verou.me/2016/12/resolve-promises-externally-with-this-one-weird-trick/
36
+ */
37
+ interface IDeferred<T> {
38
+ promise: Promise<T>;
39
+ resolve: (v: T) => void;
40
+ reject: (v: any) => void;
41
+ }
42
+
43
+ export type AuthenticationProvider =
44
+ | "arcgis"
45
+ | "facebook"
46
+ | "google"
47
+ | "github"
48
+ | "apple";
49
+
50
+ /**
51
+ * Represents a [credential](https://developers.arcgis.com/javascript/latest/api-reference/esri-identity-Credential.html)
52
+ * object used to access a secure ArcGIS resource.
53
+ */
54
+ export interface ICredential {
55
+ expires: number;
56
+ server: string;
57
+ ssl: boolean;
58
+ token: string;
59
+ userId: string;
60
+ }
61
+
62
+ function defer<T>(): IDeferred<T> {
63
+ const deferred: any = {
64
+ promise: null,
65
+ resolve: null,
66
+ reject: null,
67
+ };
68
+
69
+ deferred.promise = new Promise((resolve, reject) => {
70
+ deferred.resolve = resolve;
71
+ deferred.reject = reject;
72
+ });
73
+
74
+ return deferred as IDeferred<T>;
75
+ }
76
+
77
+ /**
78
+ * Used to test if a URL is an ArcGIS Online URL
79
+ */
80
+ const arcgisOnlineUrlRegex = /^https?:\/\/\S+\.arcgis\.com.+/;
81
+
82
+ /**
83
+ * Used to test if a URL is production ArcGIS Online Portal
84
+ */
85
+ const arcgisOnlinePortalRegex = /^https?:\/\/www\.arcgis\.com\/sharing\/rest+/;
86
+
87
+ /**
88
+ * Used to test if a URL is an ArcGIS Online Organization Portal
89
+ */
90
+ const arcgisOnlineOrgPortalRegex = /^https?:\/\/(?:[a-z0-9-]+\.maps)?.\arcgis\.com\/sharing\/rest/;
91
+
92
+ /**
93
+ * Options for static OAuth 2.0 helper methods on `UserSession`.
94
+ */
95
+ export interface IOAuth2Options {
96
+ /**
97
+ * Client ID of your application. Can be obtained by registering an application
98
+ * on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
99
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
100
+ */
101
+ clientId: string;
102
+
103
+ /**
104
+ * 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),
105
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
106
+ */
107
+ redirectUri: string;
108
+
109
+ /**
110
+ * 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.
111
+ */
112
+ portal?: string;
113
+
114
+ /**
115
+ * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page.
116
+ */
117
+
118
+ provider?: AuthenticationProvider;
119
+
120
+ /**
121
+ * Duration (in minutes) that a token will be valid. Defaults to 20160 (two weeks).
122
+ */
123
+ duration?: number;
124
+
125
+ /**
126
+ * Determines whether to open the authorization window in a new tab/window or in the current window.
127
+ *
128
+ * @browserOnly
129
+ */
130
+ popup?: boolean;
131
+
132
+ /**
133
+ * 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`
134
+ *
135
+ * @browserOnly
136
+ */
137
+ popupWindowFeatures?: string;
138
+
139
+ /**
140
+ * Duration (in minutes) that a refresh token will be valid.
141
+ *
142
+ * @nodeOnly
143
+ */
144
+ refreshTokenTTL?: number;
145
+
146
+ /**
147
+ * The locale assumed to render the login page.
148
+ *
149
+ * @browserOnly
150
+ */
151
+ locale?: string;
152
+
153
+ /**
154
+ * Applications can specify an opaque value for this parameter to correlate the authorization request sent with the received response. By default, clientId is used.
155
+ *
156
+ * @browserOnly
157
+ */
158
+ state?: string;
159
+
160
+ [key: string]: any;
161
+ }
162
+
163
+ /**
164
+ * Options for the `UserSession` constructor.
165
+ */
166
+ export interface IUserSessionOptions {
167
+ /**
168
+ * Client ID of your application. Can be obtained by registering an application
169
+ * on [ArcGIS for Developers](https://developers.arcgis.com/documentation/core-concepts/security-and-authentication/signing-in-arcgis-online-users/#registering-your-application),
170
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
171
+ */
172
+ clientId?: string;
173
+
174
+ /**
175
+ * 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),
176
+ * [ArcGIS Online](http://doc.arcgis.com/en/arcgis-online/share-maps/add-items.htm#ESRI_SECTION1_0D1B620254F745AE84F394289F8AF44B) or on your instance of ArcGIS Enterprise.
177
+ */
178
+ redirectUri?: string;
179
+
180
+ /**
181
+ * OAuth 2.0 refresh token from a previous user session.
182
+ */
183
+ refreshToken?: string;
184
+
185
+ /**
186
+ * Expiration date of the `refreshToken`
187
+ */
188
+ refreshTokenExpires?: Date;
189
+
190
+ /**
191
+ * The authenticated user's username. Guaranteed to be unique across ArcGIS Online or your instance of ArcGIS Enterprise.
192
+ */
193
+ username?: string;
194
+
195
+ /**
196
+ * Password for this user. Used in CLI apps where users cannot do OAuth 2.0.
197
+ */
198
+ password?: string;
199
+
200
+ /**
201
+ * OAuth 2.0 access token from a previous user session.
202
+ */
203
+ token?: string;
204
+
205
+ /**
206
+ * Expiration date for the `token`
207
+ */
208
+ tokenExpires?: Date;
209
+
210
+ /**
211
+ * 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.
212
+ */
213
+ portal?: string;
214
+
215
+ /**
216
+ * This value is set to true automatically if the ArcGIS Organization requires that requests be made over https.
217
+ */
218
+ ssl?: boolean;
219
+
220
+ /**
221
+ * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page.
222
+ */
223
+ provider?: AuthenticationProvider;
224
+
225
+ /**
226
+ * 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.
227
+ */
228
+ tokenDuration?: number;
229
+
230
+ /**
231
+ * Duration (in minutes) that a refresh token will be valid.
232
+ */
233
+ refreshTokenTTL?: number;
234
+
235
+ /**
236
+ * An unfederated ArcGIS Server instance known to recognize credentials supplied manually.
237
+ * ```js
238
+ * {
239
+ * server: "https://sampleserver6.arcgisonline.com/arcgis",
240
+ * token: "SOSlV3v..",
241
+ * tokenExpires: new Date(1545415669763)
242
+ * }
243
+ * ```
244
+ */
245
+ server?: string;
246
+ }
247
+
248
+ /**
249
+ * ```js
250
+ * import { UserSession } from '@esri/arcgis-rest-auth';
251
+ * UserSession.beginOAuth2({
252
+ * // register an app of your own to create a unique clientId
253
+ * clientId: "abc123",
254
+ * redirectUri: 'https://yourapp.com/authenticate.html'
255
+ * })
256
+ * .then(session)
257
+ * // or
258
+ * new UserSession({
259
+ * username: "jsmith",
260
+ * password: "123456"
261
+ * })
262
+ * // or
263
+ * UserSession.deserialize(cache)
264
+ * ```
265
+ * Used to authenticate both ArcGIS Online and ArcGIS Enterprise users. `UserSession` includes helper methods for [OAuth 2.0](/arcgis-rest-js/guides/browser-authentication/) in both browser and server applications.
266
+ */
267
+ export class UserSession implements IAuthenticationManager {
268
+ /**
269
+ * The current ArcGIS Online or ArcGIS Enterprise `token`.
270
+ */
271
+ get token() {
272
+ return this._token;
273
+ }
274
+
275
+ /**
276
+ * The expiration time of the current `token`.
277
+ */
278
+ get tokenExpires() {
279
+ return this._tokenExpires;
280
+ }
281
+
282
+ /**
283
+ * The current token to ArcGIS Online or ArcGIS Enterprise.
284
+ */
285
+ get refreshToken() {
286
+ return this._refreshToken;
287
+ }
288
+
289
+ /**
290
+ * The expiration time of the current `refreshToken`.
291
+ */
292
+ get refreshTokenExpires() {
293
+ return this._refreshTokenExpires;
294
+ }
295
+ /**
296
+ * Begins a new browser-based OAuth 2.0 sign in. If `options.popup` is `true` the
297
+ * authentication window will open in a new tab/window otherwise the user will
298
+ * be redirected to the authorization page in their current tab/window.
299
+ *
300
+ * @browserOnly
301
+ */
302
+ /* istanbul ignore next */
303
+ public static beginOAuth2(options: IOAuth2Options, win: any = window) {
304
+ const {
305
+ portal,
306
+ provider,
307
+ clientId,
308
+ duration,
309
+ redirectUri,
310
+ popup,
311
+ popupWindowFeatures,
312
+ state,
313
+ locale,
314
+ params,
315
+ }: IOAuth2Options = {
316
+ ...{
317
+ portal: "https://www.arcgis.com/sharing/rest",
318
+ provider: "arcgis",
319
+ duration: 20160,
320
+ popup: true,
321
+ popupWindowFeatures: "height=400,width=600,menubar=no,location=yes,resizable=yes,scrollbars=yes,status=yes",
322
+ state: options.clientId,
323
+ locale: "",
324
+ },
325
+ ...options,
326
+ };
327
+ let url: string;
328
+ if (provider === "arcgis") {
329
+ url = `${portal}/oauth2/authorize?client_id=${clientId}&response_type=token&expiration=${duration}&redirect_uri=${encodeURIComponent(
330
+ redirectUri
331
+ )}&state=${state}&locale=${locale}`;
332
+ } else {
333
+ url = `${portal}/oauth2/social/authorize?client_id=${clientId}&socialLoginProviderName=${provider}&autoAccountCreateForSocial=true&response_type=token&expiration=${duration}&redirect_uri=${encodeURIComponent(
334
+ redirectUri
335
+ )}&state=${state}&locale=${locale}`;
336
+ }
337
+
338
+ // append additional params
339
+ if (params) {
340
+ url = `${url}&${encodeQueryString(params)}`;
341
+ }
342
+
343
+ if (!popup) {
344
+ win.location.href = url;
345
+ return undefined;
346
+ }
347
+
348
+ const session = defer<UserSession>();
349
+
350
+ win[`__ESRI_REST_AUTH_HANDLER_${clientId}`] = function(
351
+ errorString: any,
352
+ oauthInfoString: string
353
+ ) {
354
+ if (errorString) {
355
+ const error = JSON.parse(errorString);
356
+ session.reject(new ArcGISAuthError(error.errorMessage, error.error));
357
+ return;
358
+ }
359
+
360
+ if (oauthInfoString) {
361
+ const oauthInfo = JSON.parse(oauthInfoString);
362
+ session.resolve(
363
+ new UserSession({
364
+ clientId,
365
+ portal,
366
+ ssl: oauthInfo.ssl,
367
+ token: oauthInfo.token,
368
+ tokenExpires: new Date(oauthInfo.expires),
369
+ username: oauthInfo.username,
370
+ })
371
+ );
372
+ }
373
+ };
374
+
375
+ win.open(
376
+ url,
377
+ "oauth-window",
378
+ popupWindowFeatures
379
+ );
380
+
381
+ return session.promise;
382
+ }
383
+
384
+ /**
385
+ * Completes a browser-based OAuth 2.0 in. If `options.popup` is `true` the user
386
+ * will be returned to the previous window. Otherwise a new `UserSession`
387
+ * will be returned. You must pass the same values for `options.popup` and
388
+ * `options.portal` as you used in `beginOAuth2()`.
389
+ *
390
+ * @browserOnly
391
+ */
392
+ /* istanbul ignore next */
393
+ public static completeOAuth2(options: IOAuth2Options, win: any = window) {
394
+ const { portal, clientId, popup }: IOAuth2Options = {
395
+ ...{ portal: "https://www.arcgis.com/sharing/rest", popup: true },
396
+ ...options,
397
+ };
398
+
399
+ function completeSignIn(error: any, oauthInfo?: IFetchTokenResponse) {
400
+ try {
401
+ let handlerFn;
402
+ const handlerFnName = `__ESRI_REST_AUTH_HANDLER_${clientId}`;
403
+
404
+ if (popup) {
405
+ // Guard b/c IE does not support window.opener
406
+ if (win.opener) {
407
+ if (win.opener.parent && win.opener.parent[handlerFnName]) {
408
+ handlerFn = win.opener.parent[handlerFnName];
409
+ } else if (win.opener && win.opener[handlerFnName]) {
410
+ // support pop-out oauth from within an iframe
411
+ handlerFn = win.opener[handlerFnName];
412
+ }
413
+ } else {
414
+ // IE
415
+ if (win !== win.parent && win.parent && win.parent[handlerFnName]) {
416
+ handlerFn = win.parent[handlerFnName];
417
+ }
418
+ }
419
+ // if we have a handler fn, call it and close the window
420
+ if (handlerFn) {
421
+ handlerFn(
422
+ error ? JSON.stringify(error) : undefined,
423
+ JSON.stringify(oauthInfo)
424
+ );
425
+ win.close();
426
+ return undefined;
427
+ }
428
+ }
429
+ } catch (e) {
430
+ throw new ArcGISAuthError(
431
+ `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()".`
432
+ );
433
+ }
434
+
435
+ if (error) {
436
+ throw new ArcGISAuthError(error.errorMessage, error.error);
437
+ }
438
+
439
+ return new UserSession({
440
+ clientId,
441
+ portal,
442
+ ssl: oauthInfo.ssl,
443
+ token: oauthInfo.token,
444
+ tokenExpires: oauthInfo.expires,
445
+ username: oauthInfo.username,
446
+ });
447
+ }
448
+
449
+ const params = decodeQueryString(win.location.hash);
450
+
451
+ if (!params.access_token) {
452
+ let error;
453
+ let errorMessage = "Unknown error";
454
+
455
+ if (params.error) {
456
+ error = params.error;
457
+ errorMessage = params.error_description;
458
+ }
459
+
460
+ return completeSignIn({ error, errorMessage });
461
+ }
462
+
463
+ const token = params.access_token;
464
+ const expires = new Date(
465
+ Date.now() + parseInt(params.expires_in, 10) * 1000 - 60 * 1000
466
+ );
467
+ const username = params.username;
468
+ const ssl = params.ssl === "true";
469
+
470
+ return completeSignIn(undefined, {
471
+ token,
472
+ expires,
473
+ ssl,
474
+ username,
475
+ });
476
+ }
477
+
478
+ /**
479
+ * Request session information from the parent application
480
+ *
481
+ * When an application is embedded into another application via an IFrame, the embedded app can
482
+ * use `window.postMessage` to request credentials from the host application.
483
+ *
484
+ * @param parentOrigin origin of the parent frame. Passed into the embedded application as `parentOrigin` query param
485
+ * @browserOnly
486
+ */
487
+ public static fromParent(parentOrigin: string, win?: any): Promise<any> {
488
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
489
+ if (!win && window) {
490
+ win = window;
491
+ }
492
+ // Declar handler outside of promise scope so we can detach it
493
+ let handler: (event: any) => void;
494
+ // return a promise that will resolve when the handler recieves
495
+ // session information from the correct origin
496
+ return new Promise((resolve, reject) => {
497
+ // create an event handler that just wraps the parentMessageHandler
498
+ handler = (event: any) => {
499
+ // ensure we only listen to events from the specified parent
500
+ // if the origin is not the parent origin, we don't send any response
501
+ if (event.origin === parentOrigin) {
502
+ try {
503
+ return resolve(UserSession.parentMessageHandler(event));
504
+ } catch (err) {
505
+ return reject(err);
506
+ }
507
+ }
508
+ };
509
+ // add listener
510
+ win.addEventListener("message", handler, false);
511
+ win.parent.postMessage(
512
+ { type: "arcgis:auth:requestCredential" },
513
+ parentOrigin
514
+ );
515
+ }).then((session) => {
516
+ win.removeEventListener("message", handler, false);
517
+ return session;
518
+ });
519
+ }
520
+
521
+ /**
522
+ * Begins a new server-based OAuth 2.0 sign in. This will redirect the user to
523
+ * the ArcGIS Online or ArcGIS Enterprise authorization page.
524
+ *
525
+ * @nodeOnly
526
+ */
527
+ public static authorize(
528
+ options: IOAuth2Options,
529
+ response: http.ServerResponse
530
+ ) {
531
+ const { portal, clientId, duration, redirectUri }: IOAuth2Options = {
532
+ ...{ portal: "https://arcgis.com/sharing/rest", duration: 20160 },
533
+ ...options,
534
+ };
535
+
536
+ response.writeHead(301, {
537
+ Location: `${portal}/oauth2/authorize?client_id=${clientId}&duration=${duration}&response_type=code&redirect_uri=${encodeURIComponent(
538
+ redirectUri
539
+ )}`,
540
+ });
541
+
542
+ response.end();
543
+ }
544
+
545
+ /**
546
+ * Completes the server-based OAuth 2.0 sign in process by exchanging the `authorizationCode`
547
+ * for a `access_token`.
548
+ *
549
+ * @nodeOnly
550
+ */
551
+ public static exchangeAuthorizationCode(
552
+ options: IOAuth2Options,
553
+ authorizationCode: string
554
+ ): Promise<UserSession> {
555
+ const { portal, clientId, redirectUri, refreshTokenTTL }: IOAuth2Options = {
556
+ ...{
557
+ portal: "https://www.arcgis.com/sharing/rest",
558
+ refreshTokenTTL: 1440,
559
+ },
560
+ ...options,
561
+ };
562
+
563
+ return fetchToken(`${portal}/oauth2/token`, {
564
+ params: {
565
+ grant_type: "authorization_code",
566
+ client_id: clientId,
567
+ redirect_uri: redirectUri,
568
+ code: authorizationCode,
569
+ },
570
+ }).then((response) => {
571
+ return new UserSession({
572
+ clientId,
573
+ portal,
574
+ ssl: response.ssl,
575
+ redirectUri,
576
+ refreshToken: response.refreshToken,
577
+ refreshTokenTTL,
578
+ refreshTokenExpires: new Date(
579
+ Date.now() + (refreshTokenTTL - 1) * 1000
580
+ ),
581
+ token: response.token,
582
+ tokenExpires: response.expires,
583
+ username: response.username,
584
+ });
585
+ });
586
+ }
587
+
588
+ public static deserialize(str: string) {
589
+ const options = JSON.parse(str);
590
+ return new UserSession({
591
+ clientId: options.clientId,
592
+ refreshToken: options.refreshToken,
593
+ refreshTokenExpires: new Date(options.refreshTokenExpires),
594
+ username: options.username,
595
+ password: options.password,
596
+ token: options.token,
597
+ tokenExpires: new Date(options.tokenExpires),
598
+ portal: options.portal,
599
+ ssl: options.ssl,
600
+ tokenDuration: options.tokenDuration,
601
+ redirectUri: options.redirectUri,
602
+ refreshTokenTTL: options.refreshTokenTTL,
603
+ });
604
+ }
605
+
606
+ /**
607
+ * Translates authentication from the format used in the [ArcGIS API for JavaScript](https://developers.arcgis.com/javascript/).
608
+ *
609
+ * ```js
610
+ * UserSession.fromCredential({
611
+ * userId: "jsmith",
612
+ * token: "secret"
613
+ * });
614
+ * ```
615
+ *
616
+ * @returns UserSession
617
+ */
618
+ public static fromCredential(credential: ICredential) {
619
+ return new UserSession({
620
+ portal: credential.server.includes("sharing/rest")
621
+ ? credential.server
622
+ : credential.server + `/sharing/rest`,
623
+ ssl: credential.ssl,
624
+ token: credential.token,
625
+ username: credential.userId,
626
+ tokenExpires: new Date(credential.expires),
627
+ });
628
+ }
629
+
630
+ /**
631
+ * Handle the response from the parent
632
+ * @param event DOM Event
633
+ */
634
+ private static parentMessageHandler(event: any): UserSession {
635
+ if (event.data.type === "arcgis:auth:credential") {
636
+ return UserSession.fromCredential(event.data.credential);
637
+ }
638
+ if (event.data.type === "arcgis:auth:rejected") {
639
+ throw new Error(event.data.message);
640
+ } else {
641
+ throw new Error("Unknown message type.");
642
+ }
643
+ }
644
+
645
+ /**
646
+ * Client ID being used for authentication if provided in the `constructor`.
647
+ */
648
+ public readonly clientId: string;
649
+
650
+ /**
651
+ * The currently authenticated user if provided in the `constructor`.
652
+ */
653
+ public readonly username: string;
654
+
655
+ /**
656
+ * The currently authenticated user's password if provided in the `constructor`.
657
+ */
658
+ public readonly password: string;
659
+
660
+ /**
661
+ * The current portal the user is authenticated with.
662
+ */
663
+ public readonly portal: string;
664
+
665
+ /**
666
+ * This value is set to true automatically if the ArcGIS Organization requires that requests be made over https.
667
+ */
668
+ public readonly ssl: boolean;
669
+
670
+ /**
671
+ * The authentication provider to use.
672
+ */
673
+ public readonly provider: AuthenticationProvider;
674
+
675
+ /**
676
+ * Determines how long new tokens requested are valid.
677
+ */
678
+ public readonly tokenDuration: number;
679
+
680
+ /**
681
+ * A valid redirect URI for this application if provided in the `constructor`.
682
+ */
683
+ public readonly redirectUri: string;
684
+
685
+ /**
686
+ * Duration of new OAuth 2.0 refresh token validity.
687
+ */
688
+ public readonly refreshTokenTTL: number;
689
+
690
+ /**
691
+ * An unfederated ArcGIS Server instance known to recognize credentials supplied manually.
692
+ * ```js
693
+ * {
694
+ * server: "https://sampleserver6.arcgisonline.com/arcgis",
695
+ * token: "SOSlV3v..",
696
+ * tokenExpires: new Date(1545415669763)
697
+ * }
698
+ * ```
699
+ */
700
+ public readonly server: string;
701
+
702
+ /**
703
+ * Hydrated by a call to [getUser()](#getUser-summary).
704
+ */
705
+ private _user: IUser;
706
+
707
+ private _token: string;
708
+ private _tokenExpires: Date;
709
+ private _refreshToken: string;
710
+ private _refreshTokenExpires: Date;
711
+ private _pendingUserRequest: Promise<IUser>;
712
+
713
+ /**
714
+ * Internal object to keep track of pending token requests. Used to prevent
715
+ * duplicate token requests.
716
+ */
717
+ private _pendingTokenRequests: {
718
+ [key: string]: Promise<string>;
719
+ };
720
+
721
+ /**
722
+ * Internal list of trusted 3rd party servers (federated servers) that have
723
+ * been validated with `generateToken`.
724
+ */
725
+ private trustedServers: {
726
+ [key: string]: {
727
+ token: string;
728
+ expires: Date;
729
+ };
730
+ };
731
+
732
+ private _hostHandler: any;
733
+
734
+ constructor(options: IUserSessionOptions) {
735
+ this.clientId = options.clientId;
736
+ this._refreshToken = options.refreshToken;
737
+ this._refreshTokenExpires = options.refreshTokenExpires;
738
+ this.username = options.username;
739
+ this.password = options.password;
740
+ this._token = options.token;
741
+ this._tokenExpires = options.tokenExpires;
742
+ this.portal = options.portal
743
+ ? cleanUrl(options.portal)
744
+ : "https://www.arcgis.com/sharing/rest";
745
+ this.ssl = options.ssl;
746
+ this.provider = options.provider || "arcgis";
747
+ this.tokenDuration = options.tokenDuration || 20160;
748
+ this.redirectUri = options.redirectUri;
749
+ this.refreshTokenTTL = options.refreshTokenTTL || 1440;
750
+
751
+ this.trustedServers = {};
752
+ // if a non-federated server was passed explicitly, it should be trusted.
753
+ if (options.server) {
754
+ // if the url includes more than '/arcgis/', trim the rest
755
+ const root = this.getServerRootUrl(options.server);
756
+
757
+ this.trustedServers[root] = {
758
+ token: options.token,
759
+ expires: options.tokenExpires,
760
+ };
761
+ }
762
+ this._pendingTokenRequests = {};
763
+ }
764
+
765
+ /**
766
+ * Returns authentication in a format useable in the [ArcGIS API for JavaScript](https://developers.arcgis.com/javascript/).
767
+ *
768
+ * ```js
769
+ * esriId.registerToken(session.toCredential());
770
+ * ```
771
+ *
772
+ * @returns ICredential
773
+ */
774
+ public toCredential(): ICredential {
775
+ return {
776
+ expires: this.tokenExpires.getTime(),
777
+ server: this.portal,
778
+ ssl: this.ssl,
779
+ token: this.token,
780
+ userId: this.username,
781
+ };
782
+ }
783
+
784
+ /**
785
+ * 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.
786
+ *
787
+ * ```js
788
+ * session.getUser()
789
+ * .then(response => {
790
+ * console.log(response.role); // "org_admin"
791
+ * })
792
+ * ```
793
+ *
794
+ * @param requestOptions - Options for the request. NOTE: `rawResponse` is not supported by this operation.
795
+ * @returns A Promise that will resolve with the data from the response.
796
+ */
797
+ public getUser(requestOptions?: IRequestOptions): Promise<IUser> {
798
+ if (this._pendingUserRequest) {
799
+ return this._pendingUserRequest;
800
+ } else if (this._user) {
801
+ return Promise.resolve(this._user);
802
+ } else {
803
+ const url = `${this.portal}/community/self`;
804
+
805
+ const options = {
806
+ httpMethod: "GET",
807
+ authentication: this,
808
+ ...requestOptions,
809
+ rawResponse: false,
810
+ } as IRequestOptions;
811
+
812
+ this._pendingUserRequest = request(url, options).then((response) => {
813
+ this._user = response;
814
+ this._pendingUserRequest = null;
815
+ return response;
816
+ });
817
+
818
+ return this._pendingUserRequest;
819
+ }
820
+ }
821
+
822
+ /**
823
+ * 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.
824
+ *
825
+ * * ```js
826
+ * session.getUsername()
827
+ * .then(response => {
828
+ * console.log(response); // "casey_jones"
829
+ * })
830
+ * ```
831
+ */
832
+ public getUsername() {
833
+ if (this.username) {
834
+ return Promise.resolve(this.username);
835
+ } else if (this._user) {
836
+ return Promise.resolve(this._user.username);
837
+ } else {
838
+ return this.getUser().then((user) => {
839
+ return user.username;
840
+ });
841
+ }
842
+ }
843
+
844
+ /**
845
+ * Gets an appropriate token for the given URL. If `portal` is ArcGIS Online and
846
+ * the request is to an ArcGIS Online domain `token` will be used. If the request
847
+ * is to the current `portal` the current `token` will also be used. However if
848
+ * the request is to an unknown server we will validate the server with a request
849
+ * to our current `portal`.
850
+ */
851
+ public getToken(url: string, requestOptions?: ITokenRequestOptions) {
852
+ if (canUseOnlineToken(this.portal, url)) {
853
+ return this.getFreshToken(requestOptions);
854
+ } else if (new RegExp(this.portal, "i").test(url)) {
855
+ return this.getFreshToken(requestOptions);
856
+ } else {
857
+ return this.getTokenForServer(url, requestOptions);
858
+ }
859
+ }
860
+
861
+ /**
862
+ * Get application access information for the current user
863
+ * see `validateAppAccess` function for details
864
+ *
865
+ * @param clientId application client id
866
+ */
867
+ public validateAppAccess(clientId: string): Promise<IAppAccess> {
868
+ return this.getToken(this.portal).then((token) => {
869
+ return validateAppAccess(token, clientId);
870
+ });
871
+ }
872
+
873
+ public toJSON(): IUserSessionOptions {
874
+ return {
875
+ clientId: this.clientId,
876
+ refreshToken: this.refreshToken,
877
+ refreshTokenExpires: this.refreshTokenExpires,
878
+ username: this.username,
879
+ password: this.password,
880
+ token: this.token,
881
+ tokenExpires: this.tokenExpires,
882
+ portal: this.portal,
883
+ ssl: this.ssl,
884
+ tokenDuration: this.tokenDuration,
885
+ redirectUri: this.redirectUri,
886
+ refreshTokenTTL: this.refreshTokenTTL,
887
+ };
888
+ }
889
+
890
+ public serialize() {
891
+ return JSON.stringify(this);
892
+ }
893
+ /**
894
+ * For a "Host" app that embeds other platform apps via iframes, after authenticating the user
895
+ * and creating a UserSession, the app can then enable "post message" style authentication by calling
896
+ * this method.
897
+ *
898
+ * Internally this adds an event listener on window for the `message` event
899
+ *
900
+ * @param validChildOrigins Array of origins that are allowed to request authentication from the host app
901
+ */
902
+ public enablePostMessageAuth(validChildOrigins: string[], win?: any): any {
903
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
904
+ if (!win && window) {
905
+ win = window;
906
+ }
907
+ this._hostHandler = this.createPostMessageHandler(validChildOrigins);
908
+ win.addEventListener("message", this._hostHandler, false);
909
+ }
910
+
911
+ /**
912
+ * For a "Host" app that has embedded other platform apps via iframes, when the host needs
913
+ * to transition routes, it should call `UserSession.disablePostMessageAuth()` to remove
914
+ * the event listener and prevent memory leaks
915
+ */
916
+ public disablePostMessageAuth(win?: any) {
917
+ /* istanbul ignore next: must pass in a mockwindow for tests so we can't cover the other branch */
918
+ if (!win && window) {
919
+ win = window;
920
+ }
921
+ win.removeEventListener("message", this._hostHandler, false);
922
+ }
923
+
924
+ /**
925
+ * Manually refreshes the current `token` and `tokenExpires`.
926
+ */
927
+ public refreshSession(
928
+ requestOptions?: ITokenRequestOptions
929
+ ): Promise<UserSession> {
930
+ // make sure subsequent calls to getUser() don't returned cached metadata
931
+ this._user = null;
932
+
933
+ if (this.username && this.password) {
934
+ return this.refreshWithUsernameAndPassword(requestOptions);
935
+ }
936
+
937
+ if (this.clientId && this.refreshToken) {
938
+ return this.refreshWithRefreshToken();
939
+ }
940
+
941
+ return Promise.reject(new ArcGISAuthError("Unable to refresh token."));
942
+ }
943
+
944
+ /**
945
+ * Determines the root of the ArcGIS Server or Portal for a given URL.
946
+ *
947
+ * @param url the URl to determine the root url for.
948
+ */
949
+ public getServerRootUrl(url: string) {
950
+ const [root] = cleanUrl(url).split(
951
+ /\/rest(\/admin)?\/services(?:\/|#|\?|$)/
952
+ );
953
+ const [match, protocol, domainAndPath] = root.match(/(https?:\/\/)(.+)/);
954
+ const [domain, ...path] = domainAndPath.split("/");
955
+
956
+ // only the domain is lowercased becasue in some cases an org id might be
957
+ // in the path which cannot be lowercased.
958
+ return `${protocol}${domain.toLowerCase()}/${path.join("/")}`;
959
+ }
960
+ /**
961
+ * Return a function that closes over the validOrigins array and
962
+ * can be used as an event handler for the `message` event
963
+ *
964
+ * @param validOrigins Array of valid origins
965
+ */
966
+ private createPostMessageHandler(
967
+ validOrigins: string[]
968
+ ): (event: any) => void {
969
+ // return a function that closes over the validOrigins and
970
+ // has access to the credential
971
+ return (event: any) => {
972
+ // Note: do not use regex's here. validOrigins is an array so we're checking that the event's origin
973
+ // is in the array via exact match. More info about avoiding postMessave xss issues here
974
+ // https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html#tipsbypasses-in-postmessage-vulnerabilities
975
+ if (validOrigins.indexOf(event.origin) > -1) {
976
+ const credential = this.toCredential();
977
+ event.source.postMessage(
978
+ { type: "arcgis:auth:credential", credential },
979
+ event.origin
980
+ );
981
+ } else {
982
+ event.source.postMessage(
983
+ {
984
+ type: "arcgis:auth:rejected",
985
+ message: `Rejected authentication request.`,
986
+ },
987
+ event.origin
988
+ );
989
+ }
990
+ };
991
+ }
992
+
993
+ /**
994
+ * Validates that a given URL is properly federated with our current `portal`.
995
+ * Attempts to use the internal `trustedServers` cache first.
996
+ */
997
+ private getTokenForServer(
998
+ url: string,
999
+ requestOptions?: ITokenRequestOptions
1000
+ ) {
1001
+ // requests to /rest/services/ and /rest/admin/services/ are both valid
1002
+ // Federated servers may have inconsistent casing, so lowerCase it
1003
+ const root = this.getServerRootUrl(url);
1004
+ const existingToken = this.trustedServers[root];
1005
+
1006
+ if (
1007
+ existingToken &&
1008
+ existingToken.expires &&
1009
+ existingToken.expires.getTime() > Date.now()
1010
+ ) {
1011
+ return Promise.resolve(existingToken.token);
1012
+ }
1013
+
1014
+ if (this._pendingTokenRequests[root]) {
1015
+ return this._pendingTokenRequests[root];
1016
+ }
1017
+
1018
+ this._pendingTokenRequests[root] = request(`${root}/rest/info`)
1019
+ .then((response) => {
1020
+ if (response.owningSystemUrl) {
1021
+ /**
1022
+ * if this server is not owned by this portal
1023
+ * bail out with an error since we know we wont
1024
+ * be able to generate a token
1025
+ */
1026
+ if (!isFederated(response.owningSystemUrl, this.portal)) {
1027
+ throw new ArcGISAuthError(
1028
+ `${url} is not federated with ${this.portal}.`,
1029
+ "NOT_FEDERATED"
1030
+ );
1031
+ } else {
1032
+ /**
1033
+ * if the server is federated, use the relevant token endpoint.
1034
+ */
1035
+ return request(
1036
+ `${response.owningSystemUrl}/sharing/rest/info`,
1037
+ requestOptions
1038
+ );
1039
+ }
1040
+ } else if (
1041
+ response.authInfo &&
1042
+ this.trustedServers[root] !== undefined
1043
+ ) {
1044
+ /**
1045
+ * if its a stand-alone instance of ArcGIS Server that doesn't advertise
1046
+ * federation, but the root server url is recognized, use its built in token endpoint.
1047
+ */
1048
+ return Promise.resolve({ authInfo: response.authInfo });
1049
+ } else {
1050
+ throw new ArcGISAuthError(
1051
+ `${url} is not federated with any portal and is not explicitly trusted.`,
1052
+ "NOT_FEDERATED"
1053
+ );
1054
+ }
1055
+ })
1056
+ .then((response: any) => {
1057
+ return response.authInfo.tokenServicesUrl;
1058
+ })
1059
+ .then((tokenServicesUrl: string) => {
1060
+ // an expired token cant be used to generate a new token
1061
+ if (this.token && this.tokenExpires.getTime() > Date.now()) {
1062
+ return generateToken(tokenServicesUrl, {
1063
+ params: {
1064
+ token: this.token,
1065
+ serverUrl: url,
1066
+ expiration: this.tokenDuration,
1067
+ client: "referer",
1068
+ },
1069
+ });
1070
+ // generate an entirely fresh token if necessary
1071
+ } else {
1072
+ return generateToken(tokenServicesUrl, {
1073
+ params: {
1074
+ username: this.username,
1075
+ password: this.password,
1076
+ expiration: this.tokenDuration,
1077
+ client: "referer",
1078
+ },
1079
+ }).then((response: any) => {
1080
+ this._token = response.token;
1081
+ this._tokenExpires = new Date(response.expires);
1082
+ return response;
1083
+ });
1084
+ }
1085
+ })
1086
+ .then((response) => {
1087
+ this.trustedServers[root] = {
1088
+ expires: new Date(response.expires),
1089
+ token: response.token,
1090
+ };
1091
+ delete this._pendingTokenRequests[root];
1092
+ return response.token;
1093
+ });
1094
+
1095
+ return this._pendingTokenRequests[root];
1096
+ }
1097
+
1098
+ /**
1099
+ * Returns an unexpired token for the current `portal`.
1100
+ */
1101
+ private getFreshToken(requestOptions?: ITokenRequestOptions) {
1102
+ if (this.token && !this.tokenExpires) {
1103
+ return Promise.resolve(this.token);
1104
+ }
1105
+
1106
+ if (
1107
+ this.token &&
1108
+ this.tokenExpires &&
1109
+ this.tokenExpires.getTime() > Date.now()
1110
+ ) {
1111
+ return Promise.resolve(this.token);
1112
+ }
1113
+
1114
+ if (!this._pendingTokenRequests[this.portal]) {
1115
+ this._pendingTokenRequests[this.portal] = this.refreshSession(
1116
+ requestOptions
1117
+ ).then((session) => {
1118
+ this._pendingTokenRequests[this.portal] = null;
1119
+ return session.token;
1120
+ });
1121
+ }
1122
+
1123
+ return this._pendingTokenRequests[this.portal];
1124
+ }
1125
+
1126
+ /**
1127
+ * Refreshes the current `token` and `tokenExpires` with `username` and
1128
+ * `password`.
1129
+ */
1130
+ private refreshWithUsernameAndPassword(
1131
+ requestOptions?: ITokenRequestOptions
1132
+ ) {
1133
+ const options = {
1134
+ params: {
1135
+ username: this.username,
1136
+ password: this.password,
1137
+ expiration: this.tokenDuration,
1138
+ },
1139
+ ...requestOptions,
1140
+ };
1141
+ return generateToken(`${this.portal}/generateToken`, options).then(
1142
+ (response: any) => {
1143
+ this._token = response.token;
1144
+ this._tokenExpires = new Date(response.expires);
1145
+ return this;
1146
+ }
1147
+ );
1148
+ }
1149
+
1150
+ /**
1151
+ * Refreshes the current `token` and `tokenExpires` with `refreshToken`.
1152
+ */
1153
+ private refreshWithRefreshToken(requestOptions?: ITokenRequestOptions) {
1154
+ if (
1155
+ this.refreshToken &&
1156
+ this.refreshTokenExpires &&
1157
+ this.refreshTokenExpires.getTime() < Date.now()
1158
+ ) {
1159
+ return this.refreshRefreshToken(requestOptions);
1160
+ }
1161
+
1162
+ const options: ITokenRequestOptions = {
1163
+ params: {
1164
+ client_id: this.clientId,
1165
+ refresh_token: this.refreshToken,
1166
+ grant_type: "refresh_token",
1167
+ },
1168
+ ...requestOptions,
1169
+ };
1170
+ return fetchToken(`${this.portal}/oauth2/token`, options).then(
1171
+ (response) => {
1172
+ this._token = response.token;
1173
+ this._tokenExpires = response.expires;
1174
+ return this;
1175
+ }
1176
+ );
1177
+ }
1178
+
1179
+ /**
1180
+ * Exchanges an unexpired `refreshToken` for a new one, also updates `token` and
1181
+ * `tokenExpires`.
1182
+ */
1183
+ private refreshRefreshToken(requestOptions?: ITokenRequestOptions) {
1184
+ const options: ITokenRequestOptions = {
1185
+ params: {
1186
+ client_id: this.clientId,
1187
+ refresh_token: this.refreshToken,
1188
+ redirect_uri: this.redirectUri,
1189
+ grant_type: "exchange_refresh_token",
1190
+ },
1191
+ ...requestOptions,
1192
+ };
1193
+
1194
+ return fetchToken(`${this.portal}/oauth2/token`, options).then(
1195
+ (response) => {
1196
+ this._token = response.token;
1197
+ this._tokenExpires = response.expires;
1198
+ this._refreshToken = response.refreshToken;
1199
+ this._refreshTokenExpires = new Date(
1200
+ Date.now() + (this.refreshTokenTTL - 1) * 60 * 1000
1201
+ );
1202
+ return this;
1203
+ }
1204
+ );
1205
+ }
1206
+ }