@openstax/ts-utils 1.34.0 → 1.34.1

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 (503) 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 +67 -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 +154 -0
  126. package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -0
  127. package/{packages/utils/src/types.ts → dist/cjs/types.d.ts} +6 -34
  128. package/dist/cjs/types.js +2 -0
  129. package/dist/esm/assertions/index.d.ts +89 -0
  130. package/{packages/utils/src/assertions/index.ts → dist/esm/assertions/index.js} +49 -64
  131. package/dist/esm/aws/ssmService.d.ts +5 -0
  132. package/dist/esm/aws/ssmService.js +6 -0
  133. package/dist/esm/config/awsParameterConfig.d.ts +10 -0
  134. package/dist/esm/config/awsParameterConfig.js +22 -0
  135. package/dist/esm/config/envConfig.d.ts +24 -0
  136. package/dist/esm/config/envConfig.js +53 -0
  137. package/dist/esm/config/index.d.ts +48 -0
  138. package/dist/esm/config/index.js +17 -0
  139. package/dist/esm/config/lambdaParameterConfig.d.ts +12 -0
  140. package/dist/esm/config/lambdaParameterConfig.js +38 -0
  141. package/dist/esm/config/replaceConfig.d.ts +14 -0
  142. package/{packages/utils/src/config/replaceConfig.ts → dist/esm/config/replaceConfig.js} +6 -16
  143. package/dist/esm/config/resolveConfigValue.d.ts +5 -0
  144. package/dist/esm/config/resolveConfigValue.js +8 -0
  145. package/dist/esm/errors/index.d.ts +88 -0
  146. package/{packages/utils/src/errors/index.ts → dist/esm/errors/index.js} +41 -57
  147. package/dist/esm/fetch/fetchStatusRetry.d.ts +8 -0
  148. package/dist/esm/fetch/fetchStatusRetry.js +23 -0
  149. package/dist/esm/fetch/index.d.ts +64 -0
  150. package/dist/esm/fetch/index.js +46 -0
  151. package/dist/esm/guards/index.d.ts +38 -0
  152. package/dist/esm/guards/index.js +36 -0
  153. package/dist/esm/index.d.ts +4 -0
  154. package/dist/esm/index.js +4 -0
  155. package/dist/esm/middleware/apiErrorHandler.d.ts +24 -0
  156. package/dist/esm/middleware/apiErrorHandler.js +38 -0
  157. package/dist/esm/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  158. package/dist/esm/middleware/apiSlowResponseMiddleware.js +50 -0
  159. package/dist/esm/middleware/index.d.ts +47 -0
  160. package/dist/esm/middleware/index.js +44 -0
  161. package/dist/esm/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  162. package/dist/esm/middleware/lambdaCorsResponseMiddleware.js +40 -0
  163. package/dist/esm/middleware/throwNotFoundMiddleware.d.ts +4 -0
  164. package/dist/esm/middleware/throwNotFoundMiddleware.js +10 -0
  165. package/dist/esm/misc/hashValue.d.ts +10 -0
  166. package/dist/esm/misc/hashValue.js +13 -0
  167. package/dist/esm/misc/helpers.d.ts +124 -0
  168. package/dist/esm/misc/helpers.js +199 -0
  169. package/dist/esm/misc/merge.d.ts +21 -0
  170. package/dist/esm/misc/merge.js +40 -0
  171. package/dist/esm/misc/partitionSequence.d.ts +35 -0
  172. package/{packages/utils/src/misc/partitionSequence.ts → dist/esm/misc/partitionSequence.js} +15 -23
  173. package/dist/esm/pagination/index.d.ts +91 -0
  174. package/dist/esm/pagination/index.js +77 -0
  175. package/dist/esm/routing/helpers.d.ts +57 -0
  176. package/{packages/utils/src/routing/helpers.ts → dist/esm/routing/helpers.js} +30 -42
  177. package/dist/esm/routing/index.d.ts +290 -0
  178. package/dist/esm/routing/index.js +246 -0
  179. package/dist/esm/routing/validators/zod.d.ts +4 -0
  180. package/dist/esm/routing/validators/zod.js +10 -0
  181. package/dist/esm/services/accountsGateway/index.d.ts +92 -0
  182. package/dist/esm/services/accountsGateway/index.js +131 -0
  183. package/dist/esm/services/apiGateway/index.d.ts +68 -0
  184. package/dist/esm/services/apiGateway/index.js +77 -0
  185. package/dist/esm/services/authProvider/browser.d.ts +40 -0
  186. package/dist/esm/services/authProvider/browser.js +151 -0
  187. package/dist/esm/services/authProvider/decryption.d.ts +19 -0
  188. package/dist/esm/services/authProvider/decryption.js +69 -0
  189. package/dist/esm/services/authProvider/index.d.ts +63 -0
  190. package/dist/esm/services/authProvider/index.js +26 -0
  191. package/dist/esm/services/authProvider/subrequest.d.ts +13 -0
  192. package/dist/esm/services/authProvider/subrequest.js +45 -0
  193. package/dist/esm/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  194. package/dist/esm/services/authProvider/utils/decryptAndVerify.js +85 -0
  195. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  196. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.js +40 -0
  197. package/dist/esm/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  198. package/dist/esm/services/authProvider/utils/userRoleValidator.js +33 -0
  199. package/dist/esm/services/authProvider/utils/userSubrequest.d.ts +3 -0
  200. package/dist/esm/services/authProvider/utils/userSubrequest.js +6 -0
  201. package/dist/esm/services/documentStore/dynamoEncoding.d.ts +10 -0
  202. package/dist/esm/services/documentStore/dynamoEncoding.js +45 -0
  203. package/dist/esm/services/documentStore/fileSystemAssert.d.ts +1 -0
  204. package/dist/esm/services/documentStore/fileSystemAssert.js +10 -0
  205. package/dist/esm/services/documentStore/index.d.ts +14 -0
  206. package/dist/esm/services/documentStore/index.js +1 -0
  207. package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  208. package/dist/esm/services/documentStore/unversioned/dynamodb.js +226 -0
  209. package/dist/esm/services/documentStore/unversioned/file-system.d.ts +32 -0
  210. package/dist/esm/services/documentStore/unversioned/file-system.js +174 -0
  211. package/dist/esm/services/documentStore/unversioned/index.d.ts +2 -0
  212. package/dist/esm/services/documentStore/unversioned/index.js +1 -0
  213. package/dist/esm/services/documentStore/versioned/dynamodb.d.ts +25 -0
  214. package/dist/esm/services/documentStore/versioned/dynamodb.js +139 -0
  215. package/dist/esm/services/documentStore/versioned/file-system.d.ts +25 -0
  216. package/dist/esm/services/documentStore/versioned/file-system.js +69 -0
  217. package/dist/esm/services/documentStore/versioned/index.d.ts +17 -0
  218. package/dist/esm/services/documentStore/versioned/index.js +1 -0
  219. package/dist/esm/services/exercisesGateway/index.d.ts +67 -0
  220. package/dist/esm/services/exercisesGateway/index.js +70 -0
  221. package/dist/esm/services/fileServer/index.d.ts +30 -0
  222. package/dist/esm/services/fileServer/index.js +13 -0
  223. package/dist/esm/services/fileServer/localFileServer.d.ts +13 -0
  224. package/dist/esm/services/fileServer/localFileServer.js +125 -0
  225. package/dist/esm/services/fileServer/s3FileServer.d.ts +14 -0
  226. package/dist/esm/services/fileServer/s3FileServer.js +124 -0
  227. package/dist/esm/services/launchParams/index.d.ts +2 -0
  228. package/dist/esm/services/launchParams/index.js +2 -0
  229. package/dist/esm/services/launchParams/signer.d.ts +23 -0
  230. package/dist/esm/services/launchParams/signer.js +51 -0
  231. package/dist/esm/services/launchParams/verifier.d.ts +21 -0
  232. package/dist/esm/services/launchParams/verifier.js +92 -0
  233. package/dist/esm/services/logger/console.d.ts +4 -0
  234. package/{packages/utils/src/services/logger/console.ts → dist/esm/services/logger/console.js} +2 -5
  235. package/dist/esm/services/logger/index.d.ts +39 -0
  236. package/dist/esm/services/logger/index.js +27 -0
  237. package/dist/esm/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  238. package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +14 -0
  239. package/dist/esm/services/lrsGateway/attempt-utils.d.ts +72 -0
  240. package/dist/esm/services/lrsGateway/attempt-utils.js +261 -0
  241. package/dist/esm/services/lrsGateway/file-system.d.ts +15 -0
  242. package/dist/esm/services/lrsGateway/file-system.js +110 -0
  243. package/dist/esm/services/lrsGateway/index.d.ts +122 -0
  244. package/dist/esm/services/lrsGateway/index.js +111 -0
  245. package/dist/esm/services/lrsGateway/xapiUtils.d.ts +71 -0
  246. package/dist/esm/services/lrsGateway/xapiUtils.js +134 -0
  247. package/dist/esm/services/postgresConnection/index.d.ts +28 -0
  248. package/dist/esm/services/postgresConnection/index.js +58 -0
  249. package/dist/esm/services/searchProvider/index.d.ts +67 -0
  250. package/dist/esm/services/searchProvider/index.js +1 -0
  251. package/dist/esm/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  252. package/dist/esm/services/searchProvider/memorySearchTheBadWay.js +187 -0
  253. package/dist/esm/services/searchProvider/openSearch.d.ts +28 -0
  254. package/dist/esm/services/searchProvider/openSearch.js +150 -0
  255. package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -0
  256. package/dist/esm/types.d.ts +31 -0
  257. package/dist/esm/types.js +1 -0
  258. package/package.json +228 -12
  259. package/.cfnlintrc +0 -2
  260. package/.github/CODEOWNERS +0 -1
  261. package/.github/workflows/ci.yml +0 -36
  262. package/.github/workflows/lint.yml +0 -55
  263. package/.nvmrc +0 -1
  264. package/.syncignore +0 -4
  265. package/.syncpackrc +0 -18
  266. package/CONTRIBUTING.md +0 -96
  267. package/LICENSE +0 -661
  268. package/Procfile +0 -1
  269. package/app.json +0 -23
  270. package/cspell.json +0 -32
  271. package/deploy/constants.env +0 -21
  272. package/deploy/deploy.bash +0 -157
  273. package/deploy/deployment-alt-region.cfn.yml +0 -70
  274. package/deploy/deployment.cfn.yml +0 -650
  275. package/deploy/destroy-deployment.bash +0 -23
  276. package/deploy/shared.cfn.yml +0 -94
  277. package/docs/lambda-build.md +0 -35
  278. package/packages/frontend/README.md +0 -46
  279. package/packages/frontend/package.json +0 -101
  280. package/packages/frontend/public/favicon.ico +0 -0
  281. package/packages/frontend/public/index.html +0 -107
  282. package/packages/frontend/public/maintenance.html +0 -59
  283. package/packages/frontend/public/manifest.json +0 -15
  284. package/packages/frontend/public/robots.txt +0 -3
  285. package/packages/frontend/script/make-certificate.bash +0 -49
  286. package/packages/frontend/script/server/cli.js +0 -11
  287. package/packages/frontend/script/server/index.js +0 -47
  288. package/packages/frontend/script/start.bash +0 -22
  289. package/packages/frontend/script/trust-localhost.bash +0 -7
  290. package/packages/frontend/src/auth/authProvider.ts +0 -10
  291. package/packages/frontend/src/auth/useAuth.ts +0 -33
  292. package/packages/frontend/src/components/Pagination.tsx +0 -26
  293. package/packages/frontend/src/configProvider/index.ts +0 -53
  294. package/packages/frontend/src/configProvider/use.ts +0 -41
  295. package/packages/frontend/src/core/context/services.spec.tsx +0 -39
  296. package/packages/frontend/src/core/context/services.tsx +0 -16
  297. package/packages/frontend/src/core/index.spec.ts +0 -7
  298. package/packages/frontend/src/core/index.ts +0 -20
  299. package/packages/frontend/src/core/services.tsx +0 -14
  300. package/packages/frontend/src/core/types.ts +0 -3
  301. package/packages/frontend/src/example/api.ts +0 -28
  302. package/packages/frontend/src/example/components/Layout.tsx +0 -23
  303. package/packages/frontend/src/example/screens/Home.spec.tsx +0 -68
  304. package/packages/frontend/src/example/screens/Home.tsx +0 -78
  305. package/packages/frontend/src/example/screens/ThingList.spec.tsx +0 -60
  306. package/packages/frontend/src/example/screens/ThingList.tsx +0 -75
  307. package/packages/frontend/src/example/screens/ThingView.spec.tsx +0 -71
  308. package/packages/frontend/src/example/screens/ThingView.tsx +0 -47
  309. package/packages/frontend/src/example/screens/index.ts +0 -9
  310. package/packages/frontend/src/index.css +0 -159
  311. package/packages/frontend/src/index.tsx +0 -67
  312. package/packages/frontend/src/react-app-env.d.ts +0 -1
  313. package/packages/frontend/src/routing/components/RouteLink.spec.tsx +0 -55
  314. package/packages/frontend/src/routing/components/RouteLink.tsx +0 -35
  315. package/packages/frontend/src/routing/middleware.ts +0 -6
  316. package/packages/frontend/src/routing/useQuery.ts +0 -14
  317. package/packages/frontend/src/setupProxy.js +0 -19
  318. package/packages/frontend/src/setupTests.ts +0 -9
  319. package/packages/frontend/src/tests/testServices.tsx +0 -23
  320. package/packages/frontend/tsconfig.json +0 -27
  321. package/packages/lambda/.eslintrc.js +0 -64
  322. package/packages/lambda/jest-global-setup.js +0 -3
  323. package/packages/lambda/jest-setup-after-env.js +0 -1
  324. package/packages/lambda/jest.config.js +0 -31
  325. package/packages/lambda/jest.resolver.js +0 -17
  326. package/packages/lambda/package.json +0 -68
  327. package/packages/lambda/script/build.bash +0 -19
  328. package/packages/lambda/script/bundle-functions.bash +0 -10
  329. package/packages/lambda/script/lambdaLocalProxy.js +0 -16
  330. package/packages/lambda/script/lambdaLocalProxy.spec.ts +0 -147
  331. package/packages/lambda/script/utils/getRouteData.ts +0 -7
  332. package/packages/lambda/script/utils/routeDataLoader.js +0 -8
  333. package/packages/lambda/script/utils/routeDataLoader.spec.ts +0 -8
  334. package/packages/lambda/src/functions/serviceApi/core/index.ts +0 -7
  335. package/packages/lambda/src/functions/serviceApi/core/request.spec.ts +0 -38
  336. package/packages/lambda/src/functions/serviceApi/core/request.ts +0 -42
  337. package/packages/lambda/src/functions/serviceApi/core/routes.spec.ts +0 -7
  338. package/packages/lambda/src/functions/serviceApi/core/routes.ts +0 -10
  339. package/packages/lambda/src/functions/serviceApi/core/services.ts +0 -9
  340. package/packages/lambda/src/functions/serviceApi/core/types.ts +0 -13
  341. package/packages/lambda/src/functions/serviceApi/entry/lambda/https-xray.ts +0 -4
  342. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.spec.ts +0 -48
  343. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.ts +0 -58
  344. package/packages/lambda/src/functions/serviceApi/entry/lambda/services.ts +0 -36
  345. package/packages/lambda/src/functions/serviceApi/entry/local.ts +0 -71
  346. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.spec.ts +0 -16
  347. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.ts +0 -41
  348. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.spec.ts +0 -78
  349. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.ts +0 -70
  350. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.spec.ts +0 -306
  351. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.ts +0 -176
  352. package/packages/lambda/src/functions/serviceApi/versions/v0/index.spec.ts +0 -263
  353. package/packages/lambda/src/functions/serviceApi/versions/v0/index.ts +0 -134
  354. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.spec.ts +0 -23
  355. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.ts +0 -32
  356. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.spec.ts +0 -10
  357. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.ts +0 -7
  358. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.spec.ts +0 -13
  359. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.ts +0 -23
  360. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.spec.ts +0 -9
  361. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.ts +0 -9
  362. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.spec.ts +0 -12
  363. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.ts +0 -21
  364. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.spec.ts +0 -21
  365. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.ts +0 -18
  366. package/packages/lambda/tsconfig.json +0 -30
  367. package/packages/lambda/webpack.config.js +0 -97
  368. package/packages/utils/.eslintrc.js +0 -64
  369. package/packages/utils/README.md +0 -118
  370. package/packages/utils/jest-global-setup.js +0 -3
  371. package/packages/utils/jest.config.js +0 -25
  372. package/packages/utils/jest.resolver.js +0 -17
  373. package/packages/utils/package.json +0 -238
  374. package/packages/utils/src/assertions/index.spec.ts +0 -126
  375. package/packages/utils/src/aws/ssmService.ts +0 -7
  376. package/packages/utils/src/config/awsParameterConfig.ts +0 -24
  377. package/packages/utils/src/config/envConfig.ts +0 -58
  378. package/packages/utils/src/config/index.spec.ts +0 -165
  379. package/packages/utils/src/config/lambdaParameterConfig.ts +0 -49
  380. package/packages/utils/src/config/resolveConfigValue.ts +0 -10
  381. package/packages/utils/src/errors/index.spec.ts +0 -35
  382. package/packages/utils/src/fetch/fetchStatusRetry.spec.ts +0 -197
  383. package/packages/utils/src/fetch/fetchStatusRetry.ts +0 -33
  384. package/packages/utils/src/fetch/index.spec.ts +0 -34
  385. package/packages/utils/src/fetch/index.ts +0 -87
  386. package/packages/utils/src/guards/index.spec.ts +0 -58
  387. package/packages/utils/src/index.spec.ts +0 -471
  388. package/packages/utils/src/middleware/apiErrorHandler.spec.ts +0 -65
  389. package/packages/utils/src/middleware/apiErrorHandler.ts +0 -67
  390. package/packages/utils/src/middleware/apiSlowResponseMiddleware.spec.ts +0 -184
  391. package/packages/utils/src/middleware/apiSlowResponseMiddleware.ts +0 -71
  392. package/packages/utils/src/middleware/index.spec.ts +0 -99
  393. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.spec.ts +0 -103
  394. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.ts +0 -52
  395. package/packages/utils/src/middleware/throwNotFoundMiddleware.spec.ts +0 -20
  396. package/packages/utils/src/middleware/throwNotFoundMiddleware.ts +0 -11
  397. package/packages/utils/src/misc/hashValue.ts +0 -18
  398. package/packages/utils/src/misc/helpers.ts +0 -259
  399. package/packages/utils/src/misc/merge.ts +0 -48
  400. package/packages/utils/src/pagination/index.spec.ts +0 -150
  401. package/packages/utils/src/pagination/index.ts +0 -117
  402. package/packages/utils/src/routing/index.spec.ts +0 -553
  403. package/packages/utils/src/routing/index.ts +0 -424
  404. package/packages/utils/src/routing/validators/zod.spec.ts +0 -16
  405. package/packages/utils/src/routing/validators/zod.ts +0 -14
  406. package/packages/utils/src/services/accountsGateway/README.md +0 -3
  407. package/packages/utils/src/services/accountsGateway/index.spec.ts +0 -518
  408. package/packages/utils/src/services/accountsGateway/index.ts +0 -251
  409. package/packages/utils/src/services/apiGateway/README.md +0 -93
  410. package/packages/utils/src/services/apiGateway/index.spec.ts +0 -254
  411. package/packages/utils/src/services/apiGateway/index.ts +0 -189
  412. package/packages/utils/src/services/authProvider/README.md +0 -21
  413. package/packages/utils/src/services/authProvider/browser.spec.ts +0 -391
  414. package/packages/utils/src/services/authProvider/browser.ts +0 -209
  415. package/packages/utils/src/services/authProvider/decryption.spec.ts +0 -337
  416. package/packages/utils/src/services/authProvider/decryption.ts +0 -98
  417. package/packages/utils/src/services/authProvider/index.ts +0 -93
  418. package/packages/utils/src/services/authProvider/stub.spec.ts +0 -29
  419. package/packages/utils/src/services/authProvider/subrequest.spec.ts +0 -105
  420. package/packages/utils/src/services/authProvider/subrequest.ts +0 -68
  421. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.spec.ts +0 -128
  422. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.ts +0 -106
  423. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.spec.ts +0 -26
  424. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.ts +0 -57
  425. package/packages/utils/src/services/authProvider/utils/userRoleValidator.spec.ts +0 -135
  426. package/packages/utils/src/services/authProvider/utils/userRoleValidator.ts +0 -49
  427. package/packages/utils/src/services/authProvider/utils/userSubrequest.spec.ts +0 -26
  428. package/packages/utils/src/services/authProvider/utils/userSubrequest.ts +0 -10
  429. package/packages/utils/src/services/documentStore/dynamoEncoding.ts +0 -57
  430. package/packages/utils/src/services/documentStore/fileSystemAssert.spec.ts +0 -43
  431. package/packages/utils/src/services/documentStore/fileSystemAssert.ts +0 -10
  432. package/packages/utils/src/services/documentStore/unversioned/README.md +0 -13
  433. package/packages/utils/src/services/documentStore/unversioned/dynamodb.spec.ts +0 -859
  434. package/packages/utils/src/services/documentStore/unversioned/dynamodb.ts +0 -243
  435. package/packages/utils/src/services/documentStore/unversioned/file-system.spec.ts +0 -629
  436. package/packages/utils/src/services/documentStore/unversioned/file-system.ts +0 -194
  437. package/packages/utils/src/services/documentStore/versioned/README.md +0 -13
  438. package/packages/utils/src/services/documentStore/versioned/dynamodb.spec.ts +0 -376
  439. package/packages/utils/src/services/documentStore/versioned/dynamodb.ts +0 -167
  440. package/packages/utils/src/services/documentStore/versioned/file-system.spec.ts +0 -262
  441. package/packages/utils/src/services/documentStore/versioned/file-system.ts +0 -90
  442. package/packages/utils/src/services/documentStore/versioned/index.ts +0 -25
  443. package/packages/utils/src/services/exercisesGateway/README.md +0 -5
  444. package/packages/utils/src/services/exercisesGateway/index.spec.ts +0 -326
  445. package/packages/utils/src/services/exercisesGateway/index.ts +0 -163
  446. package/packages/utils/src/services/fileServer/index.spec.ts +0 -88
  447. package/packages/utils/src/services/fileServer/index.ts +0 -43
  448. package/packages/utils/src/services/fileServer/localFileServer.spec.ts +0 -182
  449. package/packages/utils/src/services/fileServer/localFileServer.ts +0 -159
  450. package/packages/utils/src/services/fileServer/s3FileServer.spec.ts +0 -266
  451. package/packages/utils/src/services/fileServer/s3FileServer.ts +0 -155
  452. package/packages/utils/src/services/launchParams/index.spec.ts +0 -366
  453. package/packages/utils/src/services/launchParams/signer.ts +0 -73
  454. package/packages/utils/src/services/launchParams/verifier.ts +0 -120
  455. package/packages/utils/src/services/logger/console.spec.ts +0 -29
  456. package/packages/utils/src/services/logger/index.spec.ts +0 -65
  457. package/packages/utils/src/services/lrsGateway/README.md +0 -5
  458. package/packages/utils/src/services/lrsGateway/addStatementDefaultFields.ts +0 -22
  459. package/packages/utils/src/services/lrsGateway/attempt-utils.spec.ts +0 -847
  460. package/packages/utils/src/services/lrsGateway/attempt-utils.ts +0 -358
  461. package/packages/utils/src/services/lrsGateway/file-system.spec.ts +0 -363
  462. package/packages/utils/src/services/lrsGateway/file-system.ts +0 -165
  463. package/packages/utils/src/services/lrsGateway/index.spec.ts +0 -194
  464. package/packages/utils/src/services/lrsGateway/index.ts +0 -257
  465. package/packages/utils/src/services/lrsGateway/xapiUtils.spec.ts +0 -887
  466. package/packages/utils/src/services/lrsGateway/xapiUtils.ts +0 -262
  467. package/packages/utils/src/services/postgresConnection/index.spec.ts +0 -170
  468. package/packages/utils/src/services/postgresConnection/index.ts +0 -84
  469. package/packages/utils/src/services/searchProvider/README.md +0 -3
  470. package/packages/utils/src/services/searchProvider/index.ts +0 -59
  471. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.spec.ts +0 -526
  472. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.ts +0 -223
  473. package/packages/utils/src/services/searchProvider/openSearch.spec.ts +0 -926
  474. package/packages/utils/src/services/searchProvider/openSearch.ts +0 -195
  475. package/packages/utils/tsconfig.json +0 -31
  476. package/packages/utils/tsconfig.without-specs.cjs.json +0 -7
  477. package/packages/utils/tsconfig.without-specs.esm.json +0 -7
  478. package/packages/utils/tsconfig.without-specs.json +0 -6
  479. package/scripts/build.bash +0 -24
  480. package/scripts/ci.bash +0 -10
  481. package/scripts/start.bash +0 -29
  482. /package/{packages/utils/src/index.ts → dist/cjs/index.d.ts} +0 -0
  483. /package/{packages/utils/src/services/launchParams/index.ts → dist/cjs/services/launchParams/index.d.ts} +0 -0
  484. /package/{packages/utils/script → script}/bin/copy-from-template.bash +0 -0
  485. /package/{packages/utils/script → script}/bin/delete-stack.bash +0 -0
  486. /package/{packages/utils/script → script}/bin/deploy.bash +0 -0
  487. /package/{packages/utils/script → script}/bin/destroy-deployment.bash +0 -0
  488. /package/{packages/utils/script → script}/bin/empty-bucket.bash +0 -0
  489. /package/{packages/utils/script → script}/bin/get-arg.bash +0 -0
  490. /package/{packages/utils/script → script}/bin/get-deployed-environments.bash +0 -0
  491. /package/{packages/utils/script → script}/bin/get-env-param.bash +0 -0
  492. /package/{packages/utils/script → script}/bin/get-kwarg.bash +0 -0
  493. /package/{packages/utils/script → script}/bin/get-stack-param.bash +0 -0
  494. /package/{packages/utils/script → script}/bin/has-flag.bash +0 -0
  495. /package/{packages/utils/script → script}/bin/init-constants-script.bash +0 -0
  496. /package/{packages/utils/script → script}/bin/init-params-script.bash +0 -0
  497. /package/{packages/utils/script → script}/bin/stack-exists.bash +0 -0
  498. /package/{packages/utils/script → script}/bin/update-utils.bash +0 -0
  499. /package/{packages/utils/script → script}/bin/upload-pager-duty-endpoints.bash +0 -0
  500. /package/{packages/utils/script → script}/bin/upload-params.bash +0 -0
  501. /package/{packages/utils/script → script}/bin/which.bash +0 -0
  502. /package/{packages/utils/script → script}/bin-entry.bash +0 -0
  503. /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>>;