@openstax/ts-utils 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/README.md +90 -62
  2. package/dist/cjs/assertions/index.d.ts +89 -0
  3. package/dist/cjs/assertions/index.js +157 -0
  4. package/dist/cjs/aws/ssmService.d.ts +5 -0
  5. package/dist/cjs/aws/ssmService.js +9 -0
  6. package/dist/cjs/config/awsParameterConfig.d.ts +10 -0
  7. package/dist/cjs/config/awsParameterConfig.js +26 -0
  8. package/dist/cjs/config/envConfig.d.ts +24 -0
  9. package/dist/cjs/config/envConfig.js +57 -0
  10. package/{packages/utils/src/config/index.ts → dist/cjs/config/index.d.ts} +13 -29
  11. package/dist/cjs/config/index.js +35 -0
  12. package/dist/cjs/config/lambdaParameterConfig.d.ts +12 -0
  13. package/dist/cjs/config/lambdaParameterConfig.js +45 -0
  14. package/dist/cjs/config/replaceConfig.d.ts +14 -0
  15. package/dist/cjs/config/replaceConfig.js +22 -0
  16. package/dist/cjs/config/resolveConfigValue.d.ts +5 -0
  17. package/dist/cjs/config/resolveConfigValue.js +12 -0
  18. package/dist/cjs/errors/index.d.ts +88 -0
  19. package/dist/cjs/errors/index.js +123 -0
  20. package/dist/cjs/fetch/fetchStatusRetry.d.ts +8 -0
  21. package/dist/cjs/fetch/fetchStatusRetry.js +27 -0
  22. package/dist/cjs/fetch/index.d.ts +64 -0
  23. package/dist/cjs/fetch/index.js +55 -0
  24. package/{packages/utils/src/guards/index.ts → dist/cjs/guards/index.d.ts} +7 -10
  25. package/dist/cjs/guards/index.js +44 -0
  26. package/dist/cjs/index.js +20 -0
  27. package/dist/cjs/middleware/apiErrorHandler.d.ts +24 -0
  28. package/dist/cjs/middleware/apiErrorHandler.js +42 -0
  29. package/dist/cjs/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  30. package/dist/cjs/middleware/apiSlowResponseMiddleware.js +54 -0
  31. package/{packages/utils/src/middleware/index.ts → dist/cjs/middleware/index.d.ts} +5 -53
  32. package/dist/cjs/middleware/index.js +48 -0
  33. package/dist/cjs/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  34. package/dist/cjs/middleware/lambdaCorsResponseMiddleware.js +44 -0
  35. package/dist/cjs/middleware/throwNotFoundMiddleware.d.ts +4 -0
  36. package/dist/cjs/middleware/throwNotFoundMiddleware.js +14 -0
  37. package/dist/cjs/misc/hashValue.d.ts +10 -0
  38. package/dist/cjs/misc/hashValue.js +17 -0
  39. package/dist/cjs/misc/helpers.d.ts +124 -0
  40. package/dist/cjs/misc/helpers.js +214 -0
  41. package/dist/cjs/misc/merge.d.ts +21 -0
  42. package/dist/cjs/misc/merge.js +45 -0
  43. package/dist/cjs/misc/partitionSequence.d.ts +35 -0
  44. package/dist/cjs/misc/partitionSequence.js +55 -0
  45. package/dist/cjs/pagination/index.d.ts +91 -0
  46. package/dist/cjs/pagination/index.js +83 -0
  47. package/dist/cjs/routing/helpers.d.ts +57 -0
  48. package/dist/cjs/routing/helpers.js +90 -0
  49. package/dist/cjs/routing/index.d.ts +290 -0
  50. package/dist/cjs/routing/index.js +295 -0
  51. package/dist/cjs/routing/validators/zod.d.ts +4 -0
  52. package/dist/cjs/routing/validators/zod.js +14 -0
  53. package/dist/cjs/services/accountsGateway/index.d.ts +92 -0
  54. package/dist/cjs/services/accountsGateway/index.js +138 -0
  55. package/dist/cjs/services/apiGateway/index.d.ts +68 -0
  56. package/dist/cjs/services/apiGateway/index.js +118 -0
  57. package/dist/cjs/services/authProvider/browser.d.ts +40 -0
  58. package/dist/cjs/services/authProvider/browser.js +155 -0
  59. package/dist/cjs/services/authProvider/decryption.d.ts +19 -0
  60. package/dist/cjs/services/authProvider/decryption.js +73 -0
  61. package/dist/cjs/services/authProvider/index.d.ts +63 -0
  62. package/dist/cjs/services/authProvider/index.js +34 -0
  63. package/dist/cjs/services/authProvider/subrequest.d.ts +13 -0
  64. package/dist/cjs/services/authProvider/subrequest.js +49 -0
  65. package/dist/cjs/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  66. package/dist/cjs/services/authProvider/utils/decryptAndVerify.js +91 -0
  67. package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  68. package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.js +47 -0
  69. package/dist/cjs/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  70. package/dist/cjs/services/authProvider/utils/userRoleValidator.js +37 -0
  71. package/dist/cjs/services/authProvider/utils/userSubrequest.d.ts +3 -0
  72. package/dist/cjs/services/authProvider/utils/userSubrequest.js +13 -0
  73. package/dist/cjs/services/documentStore/dynamoEncoding.d.ts +10 -0
  74. package/dist/cjs/services/documentStore/dynamoEncoding.js +52 -0
  75. package/dist/cjs/services/documentStore/fileSystemAssert.d.ts +1 -0
  76. package/dist/cjs/services/documentStore/fileSystemAssert.js +14 -0
  77. package/{packages/utils/src/services/documentStore/index.ts → dist/cjs/services/documentStore/index.d.ts} +8 -8
  78. package/dist/cjs/services/documentStore/index.js +2 -0
  79. package/dist/cjs/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  80. package/dist/cjs/services/documentStore/unversioned/dynamodb.js +233 -0
  81. package/dist/cjs/services/documentStore/unversioned/file-system.d.ts +32 -0
  82. package/dist/cjs/services/documentStore/unversioned/file-system.js +214 -0
  83. package/{packages/utils/src/services/documentStore/unversioned/index.ts → dist/cjs/services/documentStore/unversioned/index.d.ts} +0 -2
  84. package/dist/cjs/services/documentStore/unversioned/index.js +2 -0
  85. package/dist/cjs/services/documentStore/versioned/dynamodb.d.ts +25 -0
  86. package/dist/cjs/services/documentStore/versioned/dynamodb.js +143 -0
  87. package/dist/cjs/services/documentStore/versioned/file-system.d.ts +25 -0
  88. package/dist/cjs/services/documentStore/versioned/file-system.js +73 -0
  89. package/dist/cjs/services/documentStore/versioned/index.d.ts +17 -0
  90. package/dist/cjs/services/documentStore/versioned/index.js +2 -0
  91. package/dist/cjs/services/exercisesGateway/index.d.ts +67 -0
  92. package/dist/cjs/services/exercisesGateway/index.js +107 -0
  93. package/dist/cjs/services/fileServer/index.d.ts +30 -0
  94. package/dist/cjs/services/fileServer/index.js +19 -0
  95. package/dist/cjs/services/fileServer/localFileServer.d.ts +13 -0
  96. package/dist/cjs/services/fileServer/localFileServer.js +132 -0
  97. package/dist/cjs/services/fileServer/s3FileServer.d.ts +14 -0
  98. package/dist/cjs/services/fileServer/s3FileServer.js +131 -0
  99. package/dist/cjs/services/launchParams/index.js +7 -0
  100. package/dist/cjs/services/launchParams/signer.d.ts +23 -0
  101. package/dist/cjs/services/launchParams/signer.js +58 -0
  102. package/dist/cjs/services/launchParams/verifier.d.ts +21 -0
  103. package/dist/cjs/services/launchParams/verifier.js +129 -0
  104. package/dist/cjs/services/logger/console.d.ts +4 -0
  105. package/dist/cjs/services/logger/console.js +12 -0
  106. package/{packages/utils/src/services/logger/index.ts → dist/cjs/services/logger/index.d.ts} +9 -23
  107. package/dist/cjs/services/logger/index.js +31 -0
  108. package/dist/cjs/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  109. package/dist/cjs/services/lrsGateway/addStatementDefaultFields.js +21 -0
  110. package/dist/cjs/services/lrsGateway/attempt-utils.d.ts +72 -0
  111. package/dist/cjs/services/lrsGateway/attempt-utils.js +283 -0
  112. package/dist/cjs/services/lrsGateway/file-system.d.ts +15 -0
  113. package/dist/cjs/services/lrsGateway/file-system.js +150 -0
  114. package/dist/cjs/services/lrsGateway/index.d.ts +122 -0
  115. package/dist/cjs/services/lrsGateway/index.js +148 -0
  116. package/dist/cjs/services/lrsGateway/xapiUtils.d.ts +71 -0
  117. package/dist/cjs/services/lrsGateway/xapiUtils.js +145 -0
  118. package/dist/cjs/services/postgresConnection/index.d.ts +28 -0
  119. package/dist/cjs/services/postgresConnection/index.js +65 -0
  120. package/dist/cjs/services/searchProvider/index.d.ts +69 -0
  121. package/dist/cjs/services/searchProvider/index.js +2 -0
  122. package/dist/cjs/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  123. package/dist/cjs/services/searchProvider/memorySearchTheBadWay.js +191 -0
  124. package/dist/cjs/services/searchProvider/openSearch.d.ts +28 -0
  125. package/dist/cjs/services/searchProvider/openSearch.js +162 -0
  126. package/dist/cjs/services/searchProvider/streamIndexer.d.ts +17 -0
  127. package/dist/cjs/services/searchProvider/streamIndexer.js +41 -0
  128. package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -0
  129. package/{packages/utils/src/types.ts → dist/cjs/types.d.ts} +6 -34
  130. package/dist/cjs/types.js +2 -0
  131. package/dist/esm/assertions/index.d.ts +89 -0
  132. package/{packages/utils/src/assertions/index.ts → dist/esm/assertions/index.js} +49 -64
  133. package/dist/esm/aws/ssmService.d.ts +5 -0
  134. package/dist/esm/aws/ssmService.js +6 -0
  135. package/dist/esm/config/awsParameterConfig.d.ts +10 -0
  136. package/dist/esm/config/awsParameterConfig.js +22 -0
  137. package/dist/esm/config/envConfig.d.ts +24 -0
  138. package/dist/esm/config/envConfig.js +53 -0
  139. package/dist/esm/config/index.d.ts +48 -0
  140. package/dist/esm/config/index.js +17 -0
  141. package/dist/esm/config/lambdaParameterConfig.d.ts +12 -0
  142. package/dist/esm/config/lambdaParameterConfig.js +38 -0
  143. package/dist/esm/config/replaceConfig.d.ts +14 -0
  144. package/{packages/utils/src/config/replaceConfig.ts → dist/esm/config/replaceConfig.js} +6 -16
  145. package/dist/esm/config/resolveConfigValue.d.ts +5 -0
  146. package/dist/esm/config/resolveConfigValue.js +8 -0
  147. package/dist/esm/errors/index.d.ts +88 -0
  148. package/{packages/utils/src/errors/index.ts → dist/esm/errors/index.js} +41 -57
  149. package/dist/esm/fetch/fetchStatusRetry.d.ts +8 -0
  150. package/dist/esm/fetch/fetchStatusRetry.js +23 -0
  151. package/dist/esm/fetch/index.d.ts +64 -0
  152. package/dist/esm/fetch/index.js +46 -0
  153. package/dist/esm/guards/index.d.ts +38 -0
  154. package/dist/esm/guards/index.js +36 -0
  155. package/dist/esm/index.d.ts +4 -0
  156. package/dist/esm/index.js +4 -0
  157. package/dist/esm/middleware/apiErrorHandler.d.ts +24 -0
  158. package/dist/esm/middleware/apiErrorHandler.js +38 -0
  159. package/dist/esm/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  160. package/dist/esm/middleware/apiSlowResponseMiddleware.js +50 -0
  161. package/dist/esm/middleware/index.d.ts +47 -0
  162. package/dist/esm/middleware/index.js +44 -0
  163. package/dist/esm/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  164. package/dist/esm/middleware/lambdaCorsResponseMiddleware.js +40 -0
  165. package/dist/esm/middleware/throwNotFoundMiddleware.d.ts +4 -0
  166. package/dist/esm/middleware/throwNotFoundMiddleware.js +10 -0
  167. package/dist/esm/misc/hashValue.d.ts +10 -0
  168. package/dist/esm/misc/hashValue.js +13 -0
  169. package/dist/esm/misc/helpers.d.ts +124 -0
  170. package/dist/esm/misc/helpers.js +199 -0
  171. package/dist/esm/misc/merge.d.ts +21 -0
  172. package/dist/esm/misc/merge.js +40 -0
  173. package/dist/esm/misc/partitionSequence.d.ts +35 -0
  174. package/{packages/utils/src/misc/partitionSequence.ts → dist/esm/misc/partitionSequence.js} +15 -23
  175. package/dist/esm/pagination/index.d.ts +91 -0
  176. package/dist/esm/pagination/index.js +77 -0
  177. package/dist/esm/routing/helpers.d.ts +57 -0
  178. package/{packages/utils/src/routing/helpers.ts → dist/esm/routing/helpers.js} +30 -42
  179. package/dist/esm/routing/index.d.ts +290 -0
  180. package/dist/esm/routing/index.js +246 -0
  181. package/dist/esm/routing/validators/zod.d.ts +4 -0
  182. package/dist/esm/routing/validators/zod.js +10 -0
  183. package/dist/esm/services/accountsGateway/index.d.ts +92 -0
  184. package/dist/esm/services/accountsGateway/index.js +131 -0
  185. package/dist/esm/services/apiGateway/index.d.ts +68 -0
  186. package/dist/esm/services/apiGateway/index.js +77 -0
  187. package/dist/esm/services/authProvider/browser.d.ts +40 -0
  188. package/dist/esm/services/authProvider/browser.js +151 -0
  189. package/dist/esm/services/authProvider/decryption.d.ts +19 -0
  190. package/dist/esm/services/authProvider/decryption.js +69 -0
  191. package/dist/esm/services/authProvider/index.d.ts +63 -0
  192. package/dist/esm/services/authProvider/index.js +26 -0
  193. package/dist/esm/services/authProvider/subrequest.d.ts +13 -0
  194. package/dist/esm/services/authProvider/subrequest.js +45 -0
  195. package/dist/esm/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  196. package/dist/esm/services/authProvider/utils/decryptAndVerify.js +85 -0
  197. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  198. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.js +40 -0
  199. package/dist/esm/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  200. package/dist/esm/services/authProvider/utils/userRoleValidator.js +33 -0
  201. package/dist/esm/services/authProvider/utils/userSubrequest.d.ts +3 -0
  202. package/dist/esm/services/authProvider/utils/userSubrequest.js +6 -0
  203. package/dist/esm/services/documentStore/dynamoEncoding.d.ts +10 -0
  204. package/dist/esm/services/documentStore/dynamoEncoding.js +45 -0
  205. package/dist/esm/services/documentStore/fileSystemAssert.d.ts +1 -0
  206. package/dist/esm/services/documentStore/fileSystemAssert.js +10 -0
  207. package/dist/esm/services/documentStore/index.d.ts +14 -0
  208. package/dist/esm/services/documentStore/index.js +1 -0
  209. package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  210. package/dist/esm/services/documentStore/unversioned/dynamodb.js +226 -0
  211. package/dist/esm/services/documentStore/unversioned/file-system.d.ts +32 -0
  212. package/dist/esm/services/documentStore/unversioned/file-system.js +174 -0
  213. package/dist/esm/services/documentStore/unversioned/index.d.ts +2 -0
  214. package/dist/esm/services/documentStore/unversioned/index.js +1 -0
  215. package/dist/esm/services/documentStore/versioned/dynamodb.d.ts +25 -0
  216. package/dist/esm/services/documentStore/versioned/dynamodb.js +139 -0
  217. package/dist/esm/services/documentStore/versioned/file-system.d.ts +25 -0
  218. package/dist/esm/services/documentStore/versioned/file-system.js +69 -0
  219. package/dist/esm/services/documentStore/versioned/index.d.ts +17 -0
  220. package/dist/esm/services/documentStore/versioned/index.js +1 -0
  221. package/dist/esm/services/exercisesGateway/index.d.ts +67 -0
  222. package/dist/esm/services/exercisesGateway/index.js +70 -0
  223. package/dist/esm/services/fileServer/index.d.ts +30 -0
  224. package/dist/esm/services/fileServer/index.js +13 -0
  225. package/dist/esm/services/fileServer/localFileServer.d.ts +13 -0
  226. package/dist/esm/services/fileServer/localFileServer.js +125 -0
  227. package/dist/esm/services/fileServer/s3FileServer.d.ts +14 -0
  228. package/dist/esm/services/fileServer/s3FileServer.js +124 -0
  229. package/dist/esm/services/launchParams/index.d.ts +2 -0
  230. package/dist/esm/services/launchParams/index.js +2 -0
  231. package/dist/esm/services/launchParams/signer.d.ts +23 -0
  232. package/dist/esm/services/launchParams/signer.js +51 -0
  233. package/dist/esm/services/launchParams/verifier.d.ts +21 -0
  234. package/dist/esm/services/launchParams/verifier.js +92 -0
  235. package/dist/esm/services/logger/console.d.ts +4 -0
  236. package/{packages/utils/src/services/logger/console.ts → dist/esm/services/logger/console.js} +2 -5
  237. package/dist/esm/services/logger/index.d.ts +39 -0
  238. package/dist/esm/services/logger/index.js +27 -0
  239. package/dist/esm/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  240. package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +14 -0
  241. package/dist/esm/services/lrsGateway/attempt-utils.d.ts +72 -0
  242. package/dist/esm/services/lrsGateway/attempt-utils.js +261 -0
  243. package/dist/esm/services/lrsGateway/file-system.d.ts +15 -0
  244. package/dist/esm/services/lrsGateway/file-system.js +110 -0
  245. package/dist/esm/services/lrsGateway/index.d.ts +122 -0
  246. package/dist/esm/services/lrsGateway/index.js +111 -0
  247. package/dist/esm/services/lrsGateway/xapiUtils.d.ts +71 -0
  248. package/dist/esm/services/lrsGateway/xapiUtils.js +134 -0
  249. package/dist/esm/services/postgresConnection/index.d.ts +28 -0
  250. package/dist/esm/services/postgresConnection/index.js +58 -0
  251. package/dist/esm/services/searchProvider/index.d.ts +69 -0
  252. package/dist/esm/services/searchProvider/index.js +1 -0
  253. package/dist/esm/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  254. package/dist/esm/services/searchProvider/memorySearchTheBadWay.js +187 -0
  255. package/dist/esm/services/searchProvider/openSearch.d.ts +28 -0
  256. package/dist/esm/services/searchProvider/openSearch.js +158 -0
  257. package/dist/esm/services/searchProvider/streamIndexer.d.ts +17 -0
  258. package/dist/esm/services/searchProvider/streamIndexer.js +37 -0
  259. package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -0
  260. package/dist/esm/types.d.ts +31 -0
  261. package/dist/esm/types.js +1 -0
  262. package/package.json +234 -12
  263. package/.cfnlintrc +0 -2
  264. package/.github/CODEOWNERS +0 -1
  265. package/.github/workflows/ci.yml +0 -36
  266. package/.github/workflows/lint.yml +0 -55
  267. package/.nvmrc +0 -1
  268. package/.syncignore +0 -4
  269. package/.syncpackrc +0 -18
  270. package/CONTRIBUTING.md +0 -96
  271. package/LICENSE +0 -661
  272. package/Procfile +0 -1
  273. package/app.json +0 -23
  274. package/cspell.json +0 -32
  275. package/deploy/constants.env +0 -21
  276. package/deploy/deploy.bash +0 -157
  277. package/deploy/deployment-alt-region.cfn.yml +0 -70
  278. package/deploy/deployment.cfn.yml +0 -650
  279. package/deploy/destroy-deployment.bash +0 -23
  280. package/deploy/shared.cfn.yml +0 -94
  281. package/docs/lambda-build.md +0 -35
  282. package/packages/frontend/README.md +0 -46
  283. package/packages/frontend/package.json +0 -101
  284. package/packages/frontend/public/favicon.ico +0 -0
  285. package/packages/frontend/public/index.html +0 -107
  286. package/packages/frontend/public/maintenance.html +0 -59
  287. package/packages/frontend/public/manifest.json +0 -15
  288. package/packages/frontend/public/robots.txt +0 -3
  289. package/packages/frontend/script/make-certificate.bash +0 -49
  290. package/packages/frontend/script/server/cli.js +0 -11
  291. package/packages/frontend/script/server/index.js +0 -47
  292. package/packages/frontend/script/start.bash +0 -22
  293. package/packages/frontend/script/trust-localhost.bash +0 -7
  294. package/packages/frontend/src/auth/authProvider.ts +0 -10
  295. package/packages/frontend/src/auth/useAuth.ts +0 -33
  296. package/packages/frontend/src/components/Pagination.tsx +0 -26
  297. package/packages/frontend/src/configProvider/index.ts +0 -53
  298. package/packages/frontend/src/configProvider/use.ts +0 -41
  299. package/packages/frontend/src/core/context/services.spec.tsx +0 -39
  300. package/packages/frontend/src/core/context/services.tsx +0 -16
  301. package/packages/frontend/src/core/index.spec.ts +0 -7
  302. package/packages/frontend/src/core/index.ts +0 -20
  303. package/packages/frontend/src/core/services.tsx +0 -14
  304. package/packages/frontend/src/core/types.ts +0 -3
  305. package/packages/frontend/src/example/api.ts +0 -28
  306. package/packages/frontend/src/example/components/Layout.tsx +0 -23
  307. package/packages/frontend/src/example/screens/Home.spec.tsx +0 -68
  308. package/packages/frontend/src/example/screens/Home.tsx +0 -78
  309. package/packages/frontend/src/example/screens/ThingList.spec.tsx +0 -60
  310. package/packages/frontend/src/example/screens/ThingList.tsx +0 -75
  311. package/packages/frontend/src/example/screens/ThingView.spec.tsx +0 -71
  312. package/packages/frontend/src/example/screens/ThingView.tsx +0 -47
  313. package/packages/frontend/src/example/screens/index.ts +0 -9
  314. package/packages/frontend/src/index.css +0 -159
  315. package/packages/frontend/src/index.tsx +0 -67
  316. package/packages/frontend/src/react-app-env.d.ts +0 -1
  317. package/packages/frontend/src/routing/components/RouteLink.spec.tsx +0 -55
  318. package/packages/frontend/src/routing/components/RouteLink.tsx +0 -35
  319. package/packages/frontend/src/routing/middleware.ts +0 -6
  320. package/packages/frontend/src/routing/useQuery.ts +0 -14
  321. package/packages/frontend/src/setupProxy.js +0 -19
  322. package/packages/frontend/src/setupTests.ts +0 -9
  323. package/packages/frontend/src/tests/testServices.tsx +0 -23
  324. package/packages/frontend/tsconfig.json +0 -27
  325. package/packages/lambda/.eslintrc.js +0 -64
  326. package/packages/lambda/jest-global-setup.js +0 -3
  327. package/packages/lambda/jest-setup-after-env.js +0 -1
  328. package/packages/lambda/jest.config.js +0 -31
  329. package/packages/lambda/jest.resolver.js +0 -17
  330. package/packages/lambda/package.json +0 -68
  331. package/packages/lambda/script/build.bash +0 -19
  332. package/packages/lambda/script/bundle-functions.bash +0 -10
  333. package/packages/lambda/script/lambdaLocalProxy.js +0 -16
  334. package/packages/lambda/script/lambdaLocalProxy.spec.ts +0 -147
  335. package/packages/lambda/script/utils/getRouteData.ts +0 -7
  336. package/packages/lambda/script/utils/routeDataLoader.js +0 -8
  337. package/packages/lambda/script/utils/routeDataLoader.spec.ts +0 -8
  338. package/packages/lambda/src/functions/serviceApi/core/index.ts +0 -7
  339. package/packages/lambda/src/functions/serviceApi/core/request.spec.ts +0 -38
  340. package/packages/lambda/src/functions/serviceApi/core/request.ts +0 -42
  341. package/packages/lambda/src/functions/serviceApi/core/routes.spec.ts +0 -7
  342. package/packages/lambda/src/functions/serviceApi/core/routes.ts +0 -10
  343. package/packages/lambda/src/functions/serviceApi/core/services.ts +0 -9
  344. package/packages/lambda/src/functions/serviceApi/core/types.ts +0 -13
  345. package/packages/lambda/src/functions/serviceApi/entry/lambda/https-xray.ts +0 -4
  346. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.spec.ts +0 -48
  347. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.ts +0 -58
  348. package/packages/lambda/src/functions/serviceApi/entry/lambda/services.ts +0 -36
  349. package/packages/lambda/src/functions/serviceApi/entry/local.ts +0 -71
  350. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.spec.ts +0 -16
  351. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.ts +0 -41
  352. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.spec.ts +0 -78
  353. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.ts +0 -70
  354. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.spec.ts +0 -306
  355. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.ts +0 -176
  356. package/packages/lambda/src/functions/serviceApi/versions/v0/index.spec.ts +0 -263
  357. package/packages/lambda/src/functions/serviceApi/versions/v0/index.ts +0 -134
  358. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.spec.ts +0 -23
  359. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.ts +0 -32
  360. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.spec.ts +0 -10
  361. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.ts +0 -7
  362. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.spec.ts +0 -13
  363. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.ts +0 -23
  364. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.spec.ts +0 -9
  365. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.ts +0 -9
  366. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.spec.ts +0 -12
  367. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.ts +0 -21
  368. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.spec.ts +0 -21
  369. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.ts +0 -18
  370. package/packages/lambda/tsconfig.json +0 -30
  371. package/packages/lambda/webpack.config.js +0 -97
  372. package/packages/utils/.eslintrc.js +0 -64
  373. package/packages/utils/README.md +0 -118
  374. package/packages/utils/jest-global-setup.js +0 -3
  375. package/packages/utils/jest.config.js +0 -25
  376. package/packages/utils/jest.resolver.js +0 -17
  377. package/packages/utils/package.json +0 -238
  378. package/packages/utils/src/assertions/index.spec.ts +0 -126
  379. package/packages/utils/src/aws/ssmService.ts +0 -7
  380. package/packages/utils/src/config/awsParameterConfig.ts +0 -24
  381. package/packages/utils/src/config/envConfig.ts +0 -58
  382. package/packages/utils/src/config/index.spec.ts +0 -165
  383. package/packages/utils/src/config/lambdaParameterConfig.ts +0 -49
  384. package/packages/utils/src/config/resolveConfigValue.ts +0 -10
  385. package/packages/utils/src/errors/index.spec.ts +0 -35
  386. package/packages/utils/src/fetch/fetchStatusRetry.spec.ts +0 -197
  387. package/packages/utils/src/fetch/fetchStatusRetry.ts +0 -33
  388. package/packages/utils/src/fetch/index.spec.ts +0 -34
  389. package/packages/utils/src/fetch/index.ts +0 -87
  390. package/packages/utils/src/guards/index.spec.ts +0 -58
  391. package/packages/utils/src/index.spec.ts +0 -471
  392. package/packages/utils/src/middleware/apiErrorHandler.spec.ts +0 -65
  393. package/packages/utils/src/middleware/apiErrorHandler.ts +0 -67
  394. package/packages/utils/src/middleware/apiSlowResponseMiddleware.spec.ts +0 -184
  395. package/packages/utils/src/middleware/apiSlowResponseMiddleware.ts +0 -71
  396. package/packages/utils/src/middleware/index.spec.ts +0 -99
  397. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.spec.ts +0 -103
  398. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.ts +0 -52
  399. package/packages/utils/src/middleware/throwNotFoundMiddleware.spec.ts +0 -20
  400. package/packages/utils/src/middleware/throwNotFoundMiddleware.ts +0 -11
  401. package/packages/utils/src/misc/hashValue.ts +0 -18
  402. package/packages/utils/src/misc/helpers.ts +0 -259
  403. package/packages/utils/src/misc/merge.ts +0 -48
  404. package/packages/utils/src/pagination/index.spec.ts +0 -150
  405. package/packages/utils/src/pagination/index.ts +0 -117
  406. package/packages/utils/src/routing/index.spec.ts +0 -553
  407. package/packages/utils/src/routing/index.ts +0 -424
  408. package/packages/utils/src/routing/validators/zod.spec.ts +0 -16
  409. package/packages/utils/src/routing/validators/zod.ts +0 -14
  410. package/packages/utils/src/services/accountsGateway/README.md +0 -3
  411. package/packages/utils/src/services/accountsGateway/index.spec.ts +0 -518
  412. package/packages/utils/src/services/accountsGateway/index.ts +0 -251
  413. package/packages/utils/src/services/apiGateway/README.md +0 -93
  414. package/packages/utils/src/services/apiGateway/index.spec.ts +0 -254
  415. package/packages/utils/src/services/apiGateway/index.ts +0 -189
  416. package/packages/utils/src/services/authProvider/README.md +0 -21
  417. package/packages/utils/src/services/authProvider/browser.spec.ts +0 -391
  418. package/packages/utils/src/services/authProvider/browser.ts +0 -209
  419. package/packages/utils/src/services/authProvider/decryption.spec.ts +0 -337
  420. package/packages/utils/src/services/authProvider/decryption.ts +0 -98
  421. package/packages/utils/src/services/authProvider/index.ts +0 -93
  422. package/packages/utils/src/services/authProvider/stub.spec.ts +0 -29
  423. package/packages/utils/src/services/authProvider/subrequest.spec.ts +0 -105
  424. package/packages/utils/src/services/authProvider/subrequest.ts +0 -68
  425. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.spec.ts +0 -128
  426. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.ts +0 -106
  427. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.spec.ts +0 -26
  428. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.ts +0 -57
  429. package/packages/utils/src/services/authProvider/utils/userRoleValidator.spec.ts +0 -135
  430. package/packages/utils/src/services/authProvider/utils/userRoleValidator.ts +0 -49
  431. package/packages/utils/src/services/authProvider/utils/userSubrequest.spec.ts +0 -26
  432. package/packages/utils/src/services/authProvider/utils/userSubrequest.ts +0 -10
  433. package/packages/utils/src/services/documentStore/dynamoEncoding.ts +0 -57
  434. package/packages/utils/src/services/documentStore/fileSystemAssert.spec.ts +0 -43
  435. package/packages/utils/src/services/documentStore/fileSystemAssert.ts +0 -10
  436. package/packages/utils/src/services/documentStore/unversioned/README.md +0 -13
  437. package/packages/utils/src/services/documentStore/unversioned/dynamodb.spec.ts +0 -859
  438. package/packages/utils/src/services/documentStore/unversioned/dynamodb.ts +0 -243
  439. package/packages/utils/src/services/documentStore/unversioned/file-system.spec.ts +0 -629
  440. package/packages/utils/src/services/documentStore/unversioned/file-system.ts +0 -194
  441. package/packages/utils/src/services/documentStore/versioned/README.md +0 -13
  442. package/packages/utils/src/services/documentStore/versioned/dynamodb.spec.ts +0 -376
  443. package/packages/utils/src/services/documentStore/versioned/dynamodb.ts +0 -167
  444. package/packages/utils/src/services/documentStore/versioned/file-system.spec.ts +0 -262
  445. package/packages/utils/src/services/documentStore/versioned/file-system.ts +0 -90
  446. package/packages/utils/src/services/documentStore/versioned/index.ts +0 -25
  447. package/packages/utils/src/services/exercisesGateway/README.md +0 -5
  448. package/packages/utils/src/services/exercisesGateway/index.spec.ts +0 -326
  449. package/packages/utils/src/services/exercisesGateway/index.ts +0 -163
  450. package/packages/utils/src/services/fileServer/index.spec.ts +0 -88
  451. package/packages/utils/src/services/fileServer/index.ts +0 -43
  452. package/packages/utils/src/services/fileServer/localFileServer.spec.ts +0 -182
  453. package/packages/utils/src/services/fileServer/localFileServer.ts +0 -159
  454. package/packages/utils/src/services/fileServer/s3FileServer.spec.ts +0 -266
  455. package/packages/utils/src/services/fileServer/s3FileServer.ts +0 -155
  456. package/packages/utils/src/services/launchParams/index.spec.ts +0 -366
  457. package/packages/utils/src/services/launchParams/signer.ts +0 -73
  458. package/packages/utils/src/services/launchParams/verifier.ts +0 -120
  459. package/packages/utils/src/services/logger/console.spec.ts +0 -29
  460. package/packages/utils/src/services/logger/index.spec.ts +0 -65
  461. package/packages/utils/src/services/lrsGateway/README.md +0 -5
  462. package/packages/utils/src/services/lrsGateway/addStatementDefaultFields.ts +0 -22
  463. package/packages/utils/src/services/lrsGateway/attempt-utils.spec.ts +0 -847
  464. package/packages/utils/src/services/lrsGateway/attempt-utils.ts +0 -358
  465. package/packages/utils/src/services/lrsGateway/file-system.spec.ts +0 -363
  466. package/packages/utils/src/services/lrsGateway/file-system.ts +0 -165
  467. package/packages/utils/src/services/lrsGateway/index.spec.ts +0 -194
  468. package/packages/utils/src/services/lrsGateway/index.ts +0 -257
  469. package/packages/utils/src/services/lrsGateway/xapiUtils.spec.ts +0 -887
  470. package/packages/utils/src/services/lrsGateway/xapiUtils.ts +0 -262
  471. package/packages/utils/src/services/postgresConnection/index.spec.ts +0 -170
  472. package/packages/utils/src/services/postgresConnection/index.ts +0 -84
  473. package/packages/utils/src/services/searchProvider/README.md +0 -3
  474. package/packages/utils/src/services/searchProvider/index.ts +0 -59
  475. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.spec.ts +0 -526
  476. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.ts +0 -223
  477. package/packages/utils/src/services/searchProvider/openSearch.spec.ts +0 -926
  478. package/packages/utils/src/services/searchProvider/openSearch.ts +0 -195
  479. package/packages/utils/tsconfig.json +0 -31
  480. package/packages/utils/tsconfig.without-specs.cjs.json +0 -7
  481. package/packages/utils/tsconfig.without-specs.esm.json +0 -7
  482. package/packages/utils/tsconfig.without-specs.json +0 -6
  483. package/scripts/build.bash +0 -24
  484. package/scripts/ci.bash +0 -10
  485. package/scripts/start.bash +0 -29
  486. /package/{packages/utils/src/index.ts → dist/cjs/index.d.ts} +0 -0
  487. /package/{packages/utils/src/services/launchParams/index.ts → dist/cjs/services/launchParams/index.d.ts} +0 -0
  488. /package/{packages/utils/script → script}/bin/copy-from-template.bash +0 -0
  489. /package/{packages/utils/script → script}/bin/delete-stack.bash +0 -0
  490. /package/{packages/utils/script → script}/bin/deploy.bash +0 -0
  491. /package/{packages/utils/script → script}/bin/destroy-deployment.bash +0 -0
  492. /package/{packages/utils/script → script}/bin/empty-bucket.bash +0 -0
  493. /package/{packages/utils/script → script}/bin/get-arg.bash +0 -0
  494. /package/{packages/utils/script → script}/bin/get-deployed-environments.bash +0 -0
  495. /package/{packages/utils/script → script}/bin/get-env-param.bash +0 -0
  496. /package/{packages/utils/script → script}/bin/get-kwarg.bash +0 -0
  497. /package/{packages/utils/script → script}/bin/get-stack-param.bash +0 -0
  498. /package/{packages/utils/script → script}/bin/has-flag.bash +0 -0
  499. /package/{packages/utils/script → script}/bin/init-constants-script.bash +0 -0
  500. /package/{packages/utils/script → script}/bin/init-params-script.bash +0 -0
  501. /package/{packages/utils/script → script}/bin/stack-exists.bash +0 -0
  502. /package/{packages/utils/script → script}/bin/update-utils.bash +0 -0
  503. /package/{packages/utils/script → script}/bin/upload-pager-duty-endpoints.bash +0 -0
  504. /package/{packages/utils/script → script}/bin/upload-params.bash +0 -0
  505. /package/{packages/utils/script → script}/bin/which.bash +0 -0
  506. /package/{packages/utils/script → script}/bin-entry.bash +0 -0
  507. /package/{packages/utils/script → script}/build.bash +0 -0
@@ -1,155 +0,0 @@
1
- /* cspell:ignore presigner */
2
- import path from 'path';
3
- import { CopyObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
4
- import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
5
- import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
6
- import { v4 as uuid } from 'uuid';
7
- import { once } from '../..';
8
- import { assertDefined } from '../../assertions';
9
- import { ConfigProviderForConfig, resolveConfigValue } from '../../config';
10
- import { ifDefined } from '../../guards';
11
- import { FileServerAdapter, FileValue } from '.';
12
-
13
- export type Config = {
14
- bucketName: string;
15
- bucketRegion: string;
16
- // optional, if not provided attempting to get a public URL will throw an error
17
- publicViewerDomain?: string;
18
- };
19
- interface Initializer<C> {
20
- configSpace?: C;
21
- getS3Client?: (...args: ConstructorParameters<typeof S3Client>) => S3Client;
22
- }
23
-
24
- export const s3FileServer = <C extends string = 'deployed'>(initializer: Initializer<C>) => (configProvider: {[_key in C]: ConfigProviderForConfig<Config>}): FileServerAdapter => {
25
- const config = configProvider[ifDefined(initializer.configSpace, 'deployed' as C)];
26
- const bucketName = once(() => resolveConfigValue(config.bucketName));
27
- const bucketRegion = once(() => resolveConfigValue(config.bucketRegion));
28
- const publicViewerDomain = once(() => 'publicViewerDomain' in config && config.publicViewerDomain
29
- ? resolveConfigValue(config.publicViewerDomain)
30
- : undefined
31
- );
32
- const s3Service = once(async () => {
33
- const args = {apiVersion: '2012-08-10', region: await bucketRegion()};
34
- return initializer.getS3Client?.(args) ?? new S3Client(args);
35
- });
36
-
37
- /*
38
- * https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
39
- */
40
- const getSignedViewerUrl = async (source: FileValue) => {
41
- const bucket = (await bucketName());
42
- const command = new GetObjectCommand({Bucket: bucket, Key: source.path});
43
- return getSignedUrl(await s3Service(), command, {
44
- expiresIn: 3600, // 1 hour
45
- });
46
- };
47
- const getPublicViewerUrl = async (source: FileValue) => {
48
- const host = assertDefined(await publicViewerDomain(),
49
- new Error(`Tried to get public viewer URL for ${source.path} but no publicViewerDomain configured`)
50
- );
51
- return `https://${host}/${source.path}`;
52
- };
53
- const getFileContent = async (source: FileValue) => {
54
- const bucket = await bucketName();
55
- const command = new GetObjectCommand({Bucket: bucket, Key: source.path});
56
- const response = await (await s3Service()).send(command);
57
-
58
- return Buffer.from(await assertDefined(response.Body, new Error('Invalid Response from s3')).transformToByteArray());
59
- };
60
- const putFileContent = async (source: FileValue, content: string) => {
61
- const bucket = await bucketName();
62
- const command = new PutObjectCommand({
63
- Bucket: bucket,
64
- Key: source.path,
65
- Body: content,
66
- ContentType: source.mimeType,
67
- });
68
- await (await s3Service()).send(command);
69
- return source;
70
- };
71
-
72
- /*
73
- * https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_s3_presigned_post.html
74
- * https://docs.aws.amazon.com/AmazonS3/latest/userguide/HTTPPOSTExamples.html
75
- * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
76
- */
77
- const getSignedFileUploadConfig = async() => {
78
- const prefix = 'uploads/' + uuid();
79
- const bucket = (await bucketName());
80
-
81
- const Conditions = [
82
- { acl: 'private' },
83
- { bucket } as {bucket: string},
84
- ['starts-with', '$key', prefix] as ['starts-with', string, string]
85
- ];
86
-
87
- const defaultFields = {
88
- acl: 'private',
89
- };
90
- const { url, fields } = await createPresignedPost(await s3Service(), {
91
- Bucket: bucket,
92
- Key: prefix + '/${filename}',
93
- Conditions,
94
- Fields: defaultFields,
95
- Expires: 3600, // 1 hour
96
- });
97
-
98
- return {
99
- url, payload: fields
100
- };
101
- };
102
-
103
- const copyFileTo = async (source: FileValue, destinationPath: string) => {
104
- const bucket = (await bucketName());
105
- const destinationPathWithoutLeadingSlash = destinationPath.replace(/^\//, '');
106
-
107
- const command = new CopyObjectCommand({
108
- Bucket: bucket,
109
- Key: destinationPathWithoutLeadingSlash,
110
- CopySource: path.join(bucket, source.path),
111
- });
112
- await (await s3Service()).send(command);
113
-
114
- return {
115
- ...source,
116
- path: destinationPathWithoutLeadingSlash
117
- };
118
- };
119
-
120
- const copyFileToDirectory = async (source: FileValue, destination: string) => {
121
- const destinationPath = path.join(destination, source.label);
122
- return copyFileTo(source, destinationPath);
123
- };
124
-
125
- const isTemporaryUpload = (source: FileValue) => {
126
- return source.path.indexOf('uploads/') === 0;
127
- };
128
-
129
- const getFileChecksum = async (source: FileValue) => {
130
- const bucket = (await bucketName());
131
- const command = new HeadObjectCommand({Bucket: bucket, Key: source.path});
132
- const response = await (await s3Service()).send(command);
133
- return assertDefined(response.ETag);
134
- };
135
-
136
- const filesEqual = async (sourceA: FileValue, sourceB: FileValue) => {
137
- const [aSum, bSum] = await Promise.all(
138
- [getFileChecksum(sourceA), getFileChecksum(sourceB)]
139
- );
140
- return aSum === bSum;
141
- };
142
-
143
- return {
144
- getFileContent,
145
- putFileContent,
146
- getSignedViewerUrl,
147
- getPublicViewerUrl,
148
- getSignedFileUploadConfig,
149
- copyFileTo,
150
- copyFileToDirectory,
151
- isTemporaryUpload,
152
- getFileChecksum,
153
- filesEqual,
154
- };
155
- };
@@ -1,366 +0,0 @@
1
- /* spell-checker: ignore Xgub Jpbmci Blbn Imlzcy XVCIs */
2
- import jwt from 'jsonwebtoken';
3
- import { JwksClient } from 'jwks-rsa';
4
- import ms from 'ms';
5
- import { z } from 'zod';
6
- import { SessionExpiredError } from '../../errors';
7
- import { createLaunchSigner, createLaunchVerifier } from '.';
8
-
9
- const alg = 'RS256' as const;
10
- const expiresIn = '1m';
11
- const iss = 'https://openstax.org';
12
- // privateKey generated for testing only
13
- const privateKey = `-----BEGIN PRIVATE KEY-----
14
- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdyPcrfMDym/eS
15
- jFEddXdbVh5PhvcikruXvzyJ/Ehocd0lgV/OMaSvdSqbmw1lJvC7NwuuhnslxwoD
16
- 0zHaUq+XR6dkaw09wPG4jzj76FByKyvFOKB8E+z3ARFDZkiRK6rdVTVnVwFG0TCl
17
- Zwdb6FSX8DL8qOqRIDzxuXBmp02Y79srcarYpaHKwwOBt8Fjs8XSADj6OR+/abXP
18
- 5cAwtqM/P18efcSfGVqoraJMSNh7tJGTdOMiSrSY8n/F7xJytZf7YeVoppjIdjvG
19
- TyHf3R3vg6xFJP63ISE1fdz8gDHR/Ix6kmWQN+t83/uYcxmcmA5CgszJXtKNxKAy
20
- WtucJhj7AgMBAAECggEAWNKuov0ArWlneoq1xc2QssTHuOP9wBvyA3E0hrLCMQpB
21
- Hk81FnhtU1Pib5VmhPdWfDQseoYjddrEGQoRMjXhWv34fVAeangGlvrNQJ4m8cJ2
22
- cjMemvLD+Zy01EB3maRadvA0RiHjQgBvsh6UJOvkTUGGugfQgbTek5TH/mTMwA24
23
- 02DsewnNk5UnLkUsh5tDeJkq9UhI2sSdkLkUoUAyZYXdUF0RRxotPK9IIorA22Vu
24
- Hw/WQ3Sr8RDyNDW0eVsmvh2jWj+vTKndqvryNqqHztpxeXh3BC9/flZjLZPgAFZ9
25
- NVnB3nj2a3A9kqz/gu/jyK1DoC9e7a8xnetp1KxK+QKBgQD07n9yBmSh06kL71Sn
26
- 8YXD5BGKWCLW+w5GM2EqzwtwXy5TGP6A6ctQESQycYEer9P0PfOG8/T4eHe0xleB
27
- OEVM/k+FfaxHuY3FU09gb0X04jKZnE3D9gNEzJfuejb12RLJkbFPGpzmrOSy+rgb
28
- Kw9LUmppk3tkNE9aTGR+Wyj+5wKBgQDnzrHyorFuomebcih5HEXfozHg2XmLUwlW
29
- ajF9c/VPKcLuzDsK0v10ZjLY30mR9i9tcwURb+YGMo3RxAxAXwcUvKzsi32fYpnn
30
- oVn2vJeauasTL+NjKp/8SSlVQykyuVNHc5WD+CrfyMRuDQWitmZVmH0oX38xejML
31
- OttDAaD2zQKBgQDieRySnGK0V3f5tyR53ZMoHFwzpWchjSYXty5jXOpgz0GQSI4b
32
- ORJrSE5F7jnL3ByJvDbPVAfxL8LP/o2uyA8cMBHrhtajw2jZSj0dGAaBdh3/d01Y
33
- osNG/D6Hna3wCPWcOADQ+fSWPsuAyt8tD9WmeeA3Gs1/S/cLsZNCWpw/hQKBgQDi
34
- MbE2gEb/G/5ZksWnmE0ecpJjRBL0PuynpCvyrMo8mxWaCzO51jR39pm7Qfb6NO4G
35
- sOvLHhOpDH+SpukFjzTLqWhb0amdc4uWmL2+pDyTQIWMzXfm9lryxTlN96El2+1F
36
- laXaBrlfcPssIAzVv4KQF6JZWQY2c3WHicEW22oEKQKBgHt6n+j0ZO+Quq7k7FNr
37
- 6RAKDmAURh/+rPc3o357inI9u5oxktXvxI41ijHXTQRKrakAmiSYikPQOb/aOgjO
38
- PNpj6gag4Srw7QkLI8ttl0yUCP155dxvnrK8Dd/t+oTsKTCR0EINSUUM8omDnHCL
39
- 5kaLB/QpHAKj0pF54unD8VzI
40
- -----END PRIVATE KEY-----`;
41
-
42
- const signerConfig = {
43
- test: {
44
- alg,
45
- expiresIn,
46
- iss,
47
- privateKey,
48
- }
49
- };
50
-
51
- const launchSigner = createLaunchSigner({ configSpace: 'test' })(signerConfig);
52
-
53
- describe('launchSigner', () => {
54
- describe('jwks', () => {
55
- it('outputs the public part of the key', async() => {
56
- // cspell:disable
57
- expect(await launchSigner.jwks()).toMatchInlineSnapshot(`
58
- {
59
- "keys": [
60
- {
61
- "e": "AQAB",
62
- "kid": "wKgbD-KbvgA_GIKnggurrTGH_tGYVI8cDU01BuM6zC8",
63
- "kty": "RSA",
64
- "n": "3cj3K3zA8pv3koxRHXV3W1YeT4b3IpK7l788ifxIaHHdJYFfzjGkr3Uqm5sNZSbwuzcLroZ7JccKA9Mx2lKvl0enZGsNPcDxuI84--hQcisrxTigfBPs9wERQ2ZIkSuq3VU1Z1cBRtEwpWcHW-hUl_Ay_KjqkSA88blwZqdNmO_bK3Gq2KWhysMDgbfBY7PF0gA4-jkfv2m1z-XAMLajPz9fHn3EnxlaqK2iTEjYe7SRk3TjIkq0mPJ_xe8ScrWX-2HlaKaYyHY7xk8h390d74OsRST-tyEhNX3c_IAx0fyMepJlkDfrfN_7mHMZnJgOQoLMyV7SjcSgMlrbnCYY-w",
65
- },
66
- ],
67
- }
68
- `);
69
- // cspell:enable
70
- });
71
- });
72
-
73
- describe('sign', () => {
74
- let publicKey: string;
75
-
76
- beforeEach(async() => {
77
- const jwksUri = 'https://localhost/test';
78
- const fetcher = (uri: string) => {
79
- if (uri !== jwksUri) { throw new Error(`Unexpected URI: "${uri}"`); }
80
- return launchSigner.jwks();
81
- };
82
- const jwksClient = new JwksClient({ fetcher, jwksUri });
83
- const key = await jwksClient.getSigningKey();
84
- publicKey = key.getPublicKey();
85
- });
86
-
87
- it('returns a signed token', async() => {
88
- const token = await launchSigner.sign({}, 'userId');
89
- const { header, payload } = jwt.verify(token, publicKey, { complete: true });
90
- if (typeof payload !== 'object') { throw new Error('Unexpected string payload'); }
91
-
92
- expect(header.alg).toBe(alg);
93
- expect(header.typ).toBe('JWT');
94
-
95
- expect(payload.exp).toBeLessThanOrEqual(Math.floor(Date.now() / 1000) + 60);
96
- expect(payload.sub).toBe('userId');
97
- });
98
-
99
- it('can set token duration using a unix timestamp', async() => {
100
- const maxExp = Math.floor(Date.now() / 1000) + 30;
101
- const token = await launchSigner.sign({}, 'userId', maxExp);
102
- const { payload } = jwt.verify(token, publicKey, { complete: true });
103
- if (typeof payload !== 'object') { throw new Error('Unexpected string payload'); }
104
- expect(payload.exp).toBeLessThanOrEqual(maxExp);
105
- expect(payload.exp).toBeGreaterThanOrEqual(maxExp - 5);
106
- });
107
-
108
- it('cannot exceed the configured max token duration', async() => {
109
- const now = Math.floor(Date.now()/1000);
110
- const maxExp = now + 86400; // 1 day
111
- const actualMax = now + Math.floor(ms(expiresIn)/1000);
112
- const token = await launchSigner.sign({}, 'userId', maxExp);
113
- const { payload } = jwt.verify(token, publicKey, { complete: true });
114
- if (typeof payload !== 'object') { throw new Error('Unexpected string payload'); }
115
- expect(payload.exp).toBeLessThanOrEqual(actualMax);
116
- expect(payload.exp).toBeGreaterThanOrEqual(actualMax - 5);
117
- });
118
-
119
- it('throws when alg is invalid', () => {
120
- const invalidLaunchSigner = createLaunchSigner({ configSpace: 'test' })({ test: { ...signerConfig.test, alg: 'none' } });
121
- return expect(invalidLaunchSigner.sign({}, 'userId')).rejects.toThrow('"none" is not a valid algorithm');
122
- });
123
- });
124
- });
125
-
126
- describe('launchVerifier', () => {
127
- const verifierConfig = {
128
- test: {
129
- trustedDomain: 'openstax.org',
130
- bypassSignatureVerification: 'false',
131
- }
132
- };
133
-
134
- const fetcher = (uri: string) => {
135
- if (uri !== new URL('/.well-known/jwks.json', iss).toString()) { throw new Error(`Unexpected URI: "${uri}"`); }
136
- return launchSigner.jwks();
137
- };
138
-
139
- const services = {};
140
- const launchVerifier = createLaunchVerifier({ configSpace: 'test', fetcher })(verifierConfig);
141
-
142
- describe('with legacy format token', () => {
143
- it('can verify string value tokens signed by the launchSigner reading value from .sub', async() => {
144
- const token = await launchSigner.sign({}, 'testSuccessful=true');
145
- expect((await launchVerifier(services).verify(token)).sub).toMatchInlineSnapshot('"testSuccessful=true"');
146
- });
147
-
148
- it('can verify json value tokens signed by the launchSigner reading value from .sub', async() => {
149
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
150
- expect((await launchVerifier(services).verify(token)).sub).toMatchInlineSnapshot('"{"testSuccessful":true}"');
151
- });
152
-
153
- it('can verify json value tokens signed by the launchSigner reading value from token', async() => {
154
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
155
- expect((await launchVerifier(services).verify(token)).testSuccessful).toMatchInlineSnapshot('true');
156
- });
157
-
158
- it('can verify extended claim tokens signed by the launchSigner reading value from token', async() => {
159
- const token = await launchSigner.sign({testSuccessful:true}, 'userId');
160
- expect((await launchVerifier(services).verify(token)).testSuccessful).toMatchInlineSnapshot('true');
161
- });
162
-
163
- describe('with a validator', () => {
164
- it('can use a default token', async() => {
165
- const token = await launchSigner.sign({}, 'userId');
166
- const validator = z.object({sub: z.string()});
167
- expect((await launchVerifier(services, () => token).verify(validator.parse)).sub).toBe('userId');
168
- });
169
-
170
- it('throws with no token provided', async() => {
171
- const validator = z.object({sub: z.string()});
172
- await expect(() => launchVerifier(services).verify(validator.parse)).rejects
173
- .toThrowErrorMatchingInlineSnapshot('"Missing token for launch verification"')
174
- ;
175
- });
176
-
177
- it('can verify string value tokens signed by the launchSigner reading value from .sub', async() => {
178
- const token = await launchSigner.sign({}, 'testSuccessful=true');
179
- const validator = z.object({sub: z.string()});
180
- expect((await launchVerifier(services).verify(token, validator.parse)).sub).toMatchInlineSnapshot('"testSuccessful=true"');
181
- });
182
-
183
- it('can verify json value tokens signed by the launchSigner reading value from .sub', async() => {
184
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
185
- const validator = z.object({sub: z.string()});
186
- expect((await launchVerifier(services).verify(token, validator.parse)).sub).toMatchInlineSnapshot('"{"testSuccessful":true}"');
187
- });
188
-
189
- it('can verify json value tokens signed by the launchSigner reading extracted value', async() => {
190
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
191
- const validator = z.object({testSuccessful: z.boolean()});
192
- expect((await launchVerifier(services).verify(token, validator.parse)).testSuccessful).toMatchInlineSnapshot('true');
193
- });
194
-
195
- it('can verify extended claim tokens signed by the launchSigner reading extracted value', async() => {
196
- const token = await launchSigner.sign({testSuccessful:true}, 'userId');
197
- const validator = z.object({testSuccessful: z.boolean()});
198
- expect((await launchVerifier(services).verify(token, validator.parse)).testSuccessful).toMatchInlineSnapshot('true');
199
- });
200
-
201
- it('strips unknown claims from result', async() => {
202
- const token = await launchSigner.sign({}, '{"testSuccessful":true,"unknown":"value"}');
203
- const validator = z.object({sub: z.string(), iss: z.string(), testSuccessful: z.boolean()});
204
- expect(await launchVerifier(services).verify(token, validator.parse)).toMatchInlineSnapshot(`
205
- {
206
- "iss": "https://openstax.org",
207
- "sub": "{"testSuccessful":true,"unknown":"value"}",
208
- "testSuccessful": true,
209
- }
210
- `);
211
- });
212
-
213
- it('throws on invalid token parameters', async() => {
214
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
215
- const validator = z.object({testSuccessfullyBad: z.boolean()});
216
- await expect(() => launchVerifier(services).verify(token, validator.parse)).rejects.toThrowErrorMatchingInlineSnapshot(`
217
- "error in secret or public key callback: [
218
- {
219
- "expected": "boolean",
220
- "code": "invalid_type",
221
- "path": [
222
- "testSuccessfullyBad"
223
- ],
224
- "message": "Invalid input: expected boolean, received undefined"
225
- }
226
- ]"
227
- `);
228
- });
229
- });
230
- });
231
-
232
- it('throws when the token is invalid', () => {
233
- const token = 'R4ND0M';
234
- return expect(launchVerifier(services).verify(token)).rejects.toThrow('jwt malformed');
235
- });
236
-
237
- it('throws when the token header is missing the iss claim', () => {
238
- const token = jwt.sign({}, privateKey, { algorithm: alg, expiresIn, issuer: iss });
239
- return expect(launchVerifier(services).verify(token)).rejects.toThrow('error in secret or public key callback: JWT header missing iss claim');
240
- });
241
-
242
- it('throws when the token is expired', () => {
243
- const header = { alg, iss };
244
- const token = jwt.sign({}, privateKey, { algorithm: alg, expiresIn: -1, header });
245
- return expect(launchVerifier(services).verify(token)).rejects.toThrow(SessionExpiredError);
246
- });
247
-
248
- it('throws when the token iss is an invalid URL', () => {
249
- const issuer = 'openstax.org';
250
- const header = { alg, iss: issuer };
251
- const token = jwt.sign({}, privateKey, { algorithm: alg, expiresIn, header, issuer });
252
- return expect(launchVerifier(services).verify(token)).rejects.toThrow('error in secret or public key callback: Invalid URL');
253
- });
254
-
255
- it('throws when the token iss is untrusted', () => {
256
- const issuer = 'https://example.com';
257
- const header = { alg, iss: issuer };
258
- const token = jwt.sign({}, privateKey, { algorithm: alg, expiresIn, header, issuer });
259
- return expect(launchVerifier(services).verify(token)).rejects.toThrow(
260
- 'error in secret or public key callback: Untrusted launch domain: "example.com"'
261
- );
262
- });
263
-
264
- it('throws when the token payload is a string', () => {
265
- const header = { alg, iss };
266
- const token = jwt.sign('testSuccessful=true', privateKey, { header });
267
- return expect(launchVerifier(services).verify(token)).rejects.toThrow('received JWT token with unexpected non-JSON payload');
268
- });
269
-
270
- it('throws when the token payload is missing the sub claim', () => {
271
- const header = { alg, iss };
272
- const token = jwt.sign({}, privateKey, { expiresIn, header, issuer: iss });
273
- return expect(launchVerifier(services).verify(token)).rejects.toThrow('JWT payload missing sub claim');
274
- });
275
-
276
- describe('with bypassSignatureVerification enabled', () => {
277
- const bypassVerifierConfig = {
278
- test: {
279
- trustedDomain: 'openstax.org',
280
- bypassSignatureVerification: 'true',
281
- }
282
- };
283
-
284
- const bypassLaunchVerifier = createLaunchVerifier({ configSpace: 'test', fetcher })(bypassVerifierConfig);
285
-
286
- it('can verify tokens without signature verification', async() => {
287
- const token = await launchSigner.sign({}, 'testSuccessful=true');
288
- expect((await bypassLaunchVerifier(services).verify(token)).sub).toMatchInlineSnapshot('"testSuccessful=true"');
289
- });
290
-
291
- it('can verify json value tokens reading value from token', async() => {
292
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
293
- expect((await bypassLaunchVerifier(services).verify(token)).testSuccessful).toMatchInlineSnapshot('true');
294
- });
295
-
296
- it('can verify extended claim tokens reading value from token', async() => {
297
- const token = await launchSigner.sign({testSuccessful:true}, 'userId');
298
- expect((await bypassLaunchVerifier(services).verify(token)).testSuccessful).toMatchInlineSnapshot('true');
299
- });
300
-
301
- it('can verify tokens with invalid signatures when bypass is enabled', async() => {
302
- // Create a malformed token that would normally fail signature verification
303
- // but should succeed when bypass is enabled
304
- const validToken = await launchSigner.sign({testSuccessful: true}, 'userId');
305
- const [header, payload] = validToken.split('.');
306
- const invalidToken = `${header}.${payload}.invalid_signature`;
307
-
308
- expect((await bypassLaunchVerifier(services).verify(invalidToken)).testSuccessful).toBe(true);
309
- });
310
-
311
- it('can verify expired tokens when bypass is enabled', async() => {
312
- const expiredToken = jwt.sign({testSuccessful: true}, privateKey, {
313
- algorithm: alg,
314
- expiresIn: -1,
315
- subject: 'userId',
316
- issuer: iss
317
- });
318
-
319
- expect((await bypassLaunchVerifier(services).verify(expiredToken)).testSuccessful).toBe(true);
320
- });
321
-
322
- it('still throws when the token payload is missing the sub claim', async() => {
323
- const tokenWithoutSub = jwt.sign({testSuccessful: true}, privateKey, {
324
- algorithm: alg,
325
- expiresIn,
326
- issuer: iss
327
- });
328
-
329
- await expect(bypassLaunchVerifier(services).verify(tokenWithoutSub)).rejects.toThrow('JWT payload missing sub claim');
330
- });
331
-
332
- it('still throws when the token payload is not an object', async() => {
333
- // Create a malformed token that would decode to a string
334
- const malformedToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImlzcyI6Imh0dHBzOi8vb3BlbnN0YXgub3JnIn0.InRlc3RTdHJpbmci.signature';
335
-
336
- await expect(bypassLaunchVerifier(services).verify(malformedToken)).rejects.toThrow('received JWT token with unexpected non-JSON payload');
337
- });
338
-
339
- it('works with validator when bypass is enabled', async() => {
340
- const token = await launchSigner.sign({}, '{"testSuccessful":true}');
341
- const validator = z.object({testSuccessful: z.boolean()});
342
- expect((await bypassLaunchVerifier(services).verify(token, validator.parse)).testSuccessful).toBe(true);
343
- });
344
-
345
- });
346
-
347
- describe('with bypassSignatureVerification disabled', () => {
348
- const normalVerifierConfig = {
349
- test: {
350
- trustedDomain: 'openstax.org',
351
- bypassSignatureVerification: 'false',
352
- }
353
- };
354
-
355
- const normalLaunchVerifier = createLaunchVerifier({ configSpace: 'test', fetcher })(normalVerifierConfig);
356
-
357
- it('still performs signature verification when bypass is explicitly disabled', async() => {
358
- // Create a token with invalid signature that should fail verification when bypass is disabled
359
- const validToken = await launchSigner.sign({testSuccessful: true}, 'userId');
360
- const [header, payload] = validToken.split('.');
361
- const invalidToken = `${header}.${payload}.invalid_signature`;
362
-
363
- await expect(normalLaunchVerifier(services).verify(invalidToken)).rejects.toThrow();
364
- });
365
- });
366
- });
@@ -1,73 +0,0 @@
1
- import jwt from 'jsonwebtoken';
2
- import ms from 'ms';
3
- import { JWK } from 'node-jose';
4
- import { once } from '../..';
5
- import { ConfigProviderForConfig, resolveConfigValue } from '../../config';
6
- import { ifDefined } from '../../guards';
7
- import type { JsonCompatibleStruct } from '../../routing';
8
-
9
- type Config = {
10
- alg: string;
11
- expiresIn: string;
12
- iss: string;
13
- privateKey: string;
14
- };
15
- interface Initializer<C> {
16
- configSpace?: C;
17
- }
18
-
19
- // jsonwebtoken does not export this list
20
- type SupportedAlgorithm = Exclude<jwt.Algorithm, 'none'>;
21
- const SUPPORTED_ALGORITHMS: SupportedAlgorithm[] & ReadonlyArray<string> = [
22
- 'RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'PS256', 'PS384', 'PS512'
23
- ];
24
- const assertAlg = (alg: string) => {
25
- if ((SUPPORTED_ALGORITHMS).includes(alg)) {
26
- return alg as SupportedAlgorithm;
27
- }
28
-
29
- throw new Error(`"${alg}" is not a valid algorithm`);
30
- };
31
-
32
- /**
33
- * Creates a class that can sign launch params
34
- */
35
- export const createLaunchSigner = <C extends string = 'launch'>({configSpace}: Initializer<C>) => (configProvider: {[_key in C]: ConfigProviderForConfig<Config>}) => {
36
- const config = configProvider[ifDefined(configSpace, 'launch' as C)];
37
- const getAlg = once(async() => assertAlg(await resolveConfigValue(config.alg)));
38
- const getExpiresIn = once(() => resolveConfigValue(config.expiresIn));
39
- const getIss = once(() => resolveConfigValue(config.iss));
40
- const getPrivateKey = once(() => resolveConfigValue(config.privateKey));
41
- const getKeyStore = once(async() => {
42
- const keystore = JWK.createKeyStore();
43
- await keystore.add(await getPrivateKey(), 'pem');
44
- return keystore;
45
- });
46
-
47
- const jwks = async() => (await getKeyStore()).toJSON(false) as { keys: JWK.RawKey[] };
48
-
49
- const getExpiresInWithMax = async(maxExp?: number | null) => {
50
- const expiresIn = await getExpiresIn();
51
-
52
- // The ms library used by jsonwebtoken can handle a value in seconds as well as a string like '1d'
53
- if (!maxExp) { return expiresIn; }
54
-
55
- // Convert both values to seconds for comparison
56
- const expiresInSeconds = Math.floor(ms(expiresIn)/1000);
57
- const maxExpSeconds = maxExp - Math.floor(Date.now()/1000);
58
- return Math.min(expiresInSeconds, maxExpSeconds);
59
- };
60
-
61
- const sign = async(data: JsonCompatibleStruct, subject: string, maxExp?: number | null) => {
62
- const alg = await getAlg();
63
- // expiresIn can be a number of seconds or a string like '1h' or '1d'
64
- const expiresIn = await getExpiresInWithMax(maxExp);
65
- const iss = await getIss();
66
- const header = { alg, iss };
67
- return jwt.sign(data, await getPrivateKey(), { algorithm: alg, expiresIn, header, issuer: iss, subject });
68
- };
69
-
70
- return { jwks, sign };
71
- };
72
-
73
- export type LaunchSigner = ReturnType<ReturnType<typeof createLaunchSigner>>;