@openstax/ts-utils 1.47.0 → 1.48.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 (44) hide show
  1. package/dist/cjs/misc/hashValue.js +2 -2
  2. package/dist/cjs/misc/jwks.d.ts +5 -2
  3. package/dist/cjs/services/apiGateway/index.js +1 -2
  4. package/dist/cjs/services/authProvider/index.js +3 -6
  5. package/dist/cjs/services/authProvider/utils/userSubrequest.js +2 -5
  6. package/dist/cjs/services/fileServer/localFileServer.js +2 -3
  7. package/dist/cjs/services/fileServer/s3FileServer.js +2 -2
  8. package/dist/cjs/services/httpMessage/verifier.d.ts +2 -2
  9. package/dist/cjs/services/keyStore/index.d.ts +3 -6
  10. package/dist/cjs/services/keyStore/index.js +20 -9
  11. package/dist/cjs/services/launchParams/verifier.d.ts +2 -2
  12. package/dist/cjs/services/lrsGateway/addStatementDefaultFields.js +1 -2
  13. package/dist/cjs/services/lrsGateway/file-system.js +2 -2
  14. package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
  15. package/dist/esm/misc/hashValue.js +2 -2
  16. package/dist/esm/misc/jwks.d.ts +5 -2
  17. package/dist/esm/services/apiGateway/index.js +1 -2
  18. package/dist/esm/services/authProvider/index.js +3 -3
  19. package/dist/esm/services/authProvider/utils/userSubrequest.js +2 -2
  20. package/dist/esm/services/fileServer/localFileServer.js +2 -3
  21. package/dist/esm/services/fileServer/s3FileServer.js +2 -2
  22. package/dist/esm/services/httpMessage/verifier.d.ts +2 -2
  23. package/dist/esm/services/keyStore/index.d.ts +3 -6
  24. package/dist/esm/services/keyStore/index.js +20 -9
  25. package/dist/esm/services/launchParams/verifier.d.ts +2 -2
  26. package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +1 -2
  27. package/dist/esm/services/lrsGateway/file-system.js +2 -2
  28. package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
  29. package/package.json +11 -15
  30. package/script/bin/clone-template-temp.bash +13 -0
  31. package/script/bin/copy-from-template.bash +6 -11
  32. package/script/bin/delete-stack.bash +2 -2
  33. package/script/bin/deploy.bash +14 -3
  34. package/script/bin/destroy-deployment.bash +4 -4
  35. package/script/bin/get-deployed-environments.bash +1 -1
  36. package/script/bin/get-env-param.bash +4 -4
  37. package/script/bin/init-constants-script.bash +1 -1
  38. package/script/bin/init-params-script.bash +1 -1
  39. package/script/bin/log-from-template.bash +16 -0
  40. package/script/bin/update-utils.bash +3 -3
  41. package/script/bin/upload-pager-duty-endpoints.bash +3 -3
  42. package/script/bin/upload-params.bash +5 -5
  43. package/script/bin-entry.bash +1 -1
  44. package/script/build.bash +4 -4
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hashValue = void 0;
4
- const crypto_1 = require("crypto");
4
+ const js_sha1_1 = require("js-sha1");
5
5
  /**
6
6
  * creates a string hash of lots of different kinds of things.
7
7
  *
@@ -13,6 +13,6 @@ const hashValue = (value) => {
13
13
  const allKeys = new Set();
14
14
  JSON.stringify(value, (k, v) => (allKeys.add(k), v));
15
15
  const strValue = (_a = JSON.stringify(value, Array.from(allKeys).sort())) !== null && _a !== void 0 ? _a : 'undefined';
16
- return (0, crypto_1.createHash)('sha1').update(strValue).digest('hex');
16
+ return (0, js_sha1_1.sha1)(strValue);
17
17
  };
18
18
  exports.hashValue = hashValue;
@@ -1,7 +1,10 @@
1
+ import type { webcrypto } from 'crypto';
1
2
  import { JwksClient } from 'jwks-rsa';
2
- import type { JWK } from 'node-jose';
3
+ export type PublicJsonWebKey = webcrypto.JsonWebKey & {
4
+ kid: string;
5
+ };
3
6
  export type JwksFetcher = (uri: string) => Promise<{
4
- keys: JWK.RawKey[];
7
+ keys: PublicJsonWebKey[];
5
8
  }>;
6
9
  export declare const getJwksClient: (jwksUri: string, fetcher?: JwksFetcher) => JwksClient;
7
10
  export declare const getJwksKey: (iss: string, kid?: string, fetcher?: JwksFetcher) => Promise<import("jwks-rsa").SigningKey>;
@@ -39,7 +39,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.createApiGateway = exports.loadResponse = void 0;
40
40
  const pathToRegexp = __importStar(require("path-to-regexp"));
41
41
  const query_string_1 = __importDefault(require("query-string"));
42
- const uuid_1 = require("uuid");
43
42
  const index_js_1 = require("../../config/index.js");
44
43
  const index_js_2 = require("../../errors/index.js");
45
44
  const fetchStatusRetry_js_1 = require("../../fetch/fetchStatusRetry.js");
@@ -72,7 +71,7 @@ const makeRouteClient = (initializer, config, route, app) => {
72
71
  const url = await renderUrl({ params, query });
73
72
  const body = payload ? JSON.stringify(payload) : undefined;
74
73
  const baseOptions = (0, index_js_3.merge)((await ((_a = app === null || app === void 0 ? void 0 : app.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthorizedFetchConfig())) || {}, fetchConfig || {});
75
- const requestId = (0, uuid_1.v4)();
74
+ const requestId = globalThis.crypto.randomUUID();
76
75
  const requestLogger = (_b = app === null || app === void 0 ? void 0 : app.logger) === null || _b === void 0 ? void 0 : _b.createSubContext();
77
76
  requestLogger === null || requestLogger === void 0 ? void 0 : requestLogger.setContext({ requestId, url, timeStamp: new Date().getTime() });
78
77
  const fetcher = (0, fetchStatusRetry_js_1.fetchStatusRetry)(fetch, { retries: 1, status: [502], logger: requestLogger });
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getAuthTokenOrCookie = exports.stubAuthProvider = void 0;
7
- const cookie_1 = __importDefault(require("cookie"));
4
+ const cookie_1 = require("cookie");
8
5
  const helpers_js_1 = require("../../misc/helpers.js");
9
6
  const helpers_js_2 = require("../../routing/helpers.js");
10
7
  const stubAuthProvider = (user) => {
@@ -22,13 +19,13 @@ const getAuthTokenOrCookie = (request, cookieName, queryKey = 'auth') => {
22
19
  var _a, _b;
23
20
  const authParam = request.queryStringParameters ? request.queryStringParameters[queryKey] : undefined;
24
21
  const authHeader = (0, helpers_js_2.getHeader)(request.headers, 'authorization');
25
- const cookieValue = cookie_1.default.parse((_b = (_a = request.cookies) === null || _a === void 0 ? void 0 : _a.join('; ')) !== null && _b !== void 0 ? _b : '')[cookieName];
22
+ const cookieValue = (0, cookie_1.parse)((_b = (_a = request.cookies) === null || _a === void 0 ? void 0 : _a.join('; ')) !== null && _b !== void 0 ? _b : '')[cookieName];
26
23
  return typeof authParam === 'string'
27
24
  ? (0, helpers_js_1.tuple)(authParam, { Authorization: `Bearer ${authParam}` })
28
25
  : authHeader && authHeader.length >= 8 && authHeader.startsWith('Bearer ')
29
26
  ? (0, helpers_js_1.tuple)(authHeader.slice(7), { Authorization: authHeader })
30
27
  : cookieValue
31
- ? (0, helpers_js_1.tuple)(cookieValue, { cookie: cookie_1.default.serialize(cookieName, cookieValue) })
28
+ ? (0, helpers_js_1.tuple)(cookieValue, { cookie: (0, cookie_1.serialize)(cookieName, cookieValue) })
32
29
  : (0, helpers_js_1.tuple)(null, {});
33
30
  };
34
31
  exports.getAuthTokenOrCookie = getAuthTokenOrCookie;
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.loadUserData = void 0;
7
- const cookie_1 = __importDefault(require("cookie"));
4
+ const cookie_1 = require("cookie");
8
5
  const loadUserData = (fetch, accountsBase, cookieName, token) => {
9
- const headers = { cookie: cookie_1.default.serialize(cookieName, token) };
6
+ const headers = { cookie: (0, cookie_1.serialize)(cookieName, token) };
10
7
  // this returns `{"error_id":null}` when the token is invalid
11
8
  return fetch(accountsBase.replace(/\/+$/, '') + '/api/user', { headers })
12
9
  .then(response => response.json())
@@ -11,7 +11,6 @@ const https_1 = __importDefault(require("https"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const promises_1 = require("stream/promises");
13
13
  const busboy_1 = __importDefault(require("busboy"));
14
- const uuid_1 = require("uuid");
15
14
  const index_js_1 = require("../../assertions/index.js");
16
15
  const index_js_2 = require("../../config/index.js");
17
16
  const index_js_3 = require("../../guards/index.js");
@@ -45,7 +44,7 @@ const handleUpload = (req, res, uploadDir) => {
45
44
  });
46
45
  busboy.on('file', (_name, file, info) => {
47
46
  originalName = info.filename;
48
- tempPath = path_1.default.join(uploadDir, (0, uuid_1.v4)());
47
+ tempPath = path_1.default.join(uploadDir, crypto_1.default.randomUUID());
49
48
  file.pipe(fs_1.default.createWriteStream(tempPath));
50
49
  });
51
50
  busboy.on('finish', async () => {
@@ -139,7 +138,7 @@ const localFileServer = (initializer) => (configProvider) => {
139
138
  return source;
140
139
  };
141
140
  const getSignedFileUploadConfig = async () => {
142
- const prefix = 'uploads/' + (0, uuid_1.v4)();
141
+ const prefix = 'uploads/' + crypto_1.default.randomUUID();
143
142
  return {
144
143
  url: `https://${await host}:${await port}/`,
145
144
  payload: {
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.s3FileServer = void 0;
7
7
  /* spell-checker: ignore presigner */
8
+ const crypto_1 = require("crypto");
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const client_s3_1 = require("@aws-sdk/client-s3");
10
11
  const s3_presigned_post_1 = require("@aws-sdk/s3-presigned-post");
11
12
  const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
12
- const uuid_1 = require("uuid");
13
13
  const index_js_1 = require("../../assertions/index.js");
14
14
  const index_js_2 = require("../../config/index.js");
15
15
  const index_js_3 = require("../../guards/index.js");
@@ -63,7 +63,7 @@ const s3FileServer = (initializer) => (configProvider) => {
63
63
  * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
64
64
  */
65
65
  const getSignedFileUploadConfig = async () => {
66
- const prefix = 'uploads/' + (0, uuid_1.v4)();
66
+ const prefix = 'uploads/' + (0, crypto_1.randomUUID)();
67
67
  const bucket = (await bucketName());
68
68
  const Conditions = [
69
69
  { acl: 'private' },
@@ -1,7 +1,7 @@
1
1
  import { APIGatewayProxyEventV2 } from 'aws-lambda';
2
2
  import { VerifyConfig } from 'http-message-signatures';
3
- import { JWK } from 'node-jose';
4
3
  import { ConfigProviderForConfig } from '../../config/index.js';
4
+ import { type PublicJsonWebKey } from '../../misc/jwks.js';
5
5
  type Config = {
6
6
  apiHost: string;
7
7
  bypassSignatureVerification: string;
@@ -9,7 +9,7 @@ type Config = {
9
9
  interface Initializer<C> {
10
10
  configSpace?: C;
11
11
  fetcher?: (uri: string) => Promise<{
12
- keys: JWK.RawKey[];
12
+ keys: PublicJsonWebKey[];
13
13
  }>;
14
14
  }
15
15
  export type SignatureAgentVerifier = (signatureAgent: string) => boolean | Promise<boolean>;
@@ -1,5 +1,5 @@
1
- import { JWK } from 'node-jose';
2
1
  import { ConfigProviderForConfig } from '../../config/index.js';
2
+ import type { PublicJsonWebKey } from '../../misc/jwks.js';
3
3
  type Config = {
4
4
  privateKey: string;
5
5
  };
@@ -8,12 +8,9 @@ export type PrivateKey = {
8
8
  pem: string;
9
9
  };
10
10
  export declare const createKeyStore: (config: ConfigProviderForConfig<Config>) => {
11
- getPrivateKey: () => Promise<{
12
- kid: string;
13
- pem: string;
14
- }>;
11
+ getPrivateKey: () => Promise<PrivateKey>;
15
12
  jwks: () => Promise<{
16
- keys: JWK.RawKey[];
13
+ keys: PublicJsonWebKey[];
17
14
  }>;
18
15
  };
19
16
  export type KeyStore = ReturnType<typeof createKeyStore>;
@@ -1,26 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createKeyStore = void 0;
4
- const node_jose_1 = require("node-jose");
4
+ const crypto_1 = require("crypto");
5
5
  const index_js_1 = require("../../config/index.js");
6
6
  const helpers_js_1 = require("../../misc/helpers.js");
7
+ // RFC 7638 required members per key type, in lexicographic order
8
+ const thumbprintMembers = {
9
+ RSA: ['e', 'kty', 'n'],
10
+ EC: ['crv', 'kty', 'x', 'y'],
11
+ OKP: ['crv', 'kty', 'x'],
12
+ oct: ['k', 'kty'],
13
+ };
14
+ const jwkThumbprint = (jwk) => {
15
+ const members = thumbprintMembers[jwk.kty];
16
+ const canonical = Object.fromEntries(members.map((m) => [m, jwk[m]]));
17
+ return (0, crypto_1.createHash)('sha256').update(JSON.stringify(canonical)).digest('base64url');
18
+ };
7
19
  const createKeyStore = (config) => {
8
20
  const store = (0, helpers_js_1.once)(async () => {
9
21
  const pem = await (0, index_js_1.resolveConfigValue)(config.privateKey);
10
- const keyStore = node_jose_1.JWK.createKeyStore();
11
- const { kid } = await keyStore.add(pem, 'pem');
12
- const keys = [{ kid, pem }];
13
- return { keyStore, keys };
22
+ const publicJwk = (0, crypto_1.createPublicKey)(pem).export({ format: 'jwk' });
23
+ const kid = jwkThumbprint(publicJwk);
24
+ return { pem, publicJwk, kid };
14
25
  });
15
26
  return {
16
27
  // this method only supports one key for now (always returns the first key)
17
28
  getPrivateKey: async () => {
18
- const { keys } = await store();
19
- return keys[0];
29
+ const { pem, kid } = await store();
30
+ return { kid, pem };
20
31
  },
21
32
  jwks: async () => {
22
- const { keyStore } = await store();
23
- return keyStore.toJSON(false);
33
+ const { publicJwk, kid } = await store();
34
+ return { keys: [{ ...publicJwk, kid }] };
24
35
  },
25
36
  };
26
37
  };
@@ -1,6 +1,6 @@
1
1
  import jwt from 'jsonwebtoken';
2
- import type { JWK } from 'node-jose';
3
2
  import { ConfigProviderForConfig } from '../../config/index.js';
3
+ import { type PublicJsonWebKey } from '../../misc/jwks.js';
4
4
  type Config = {
5
5
  trustedDomain: string;
6
6
  bypassSignatureVerification: string;
@@ -8,7 +8,7 @@ type Config = {
8
8
  interface Initializer<C> {
9
9
  configSpace?: C;
10
10
  fetcher?: (uri: string) => Promise<{
11
- keys: JWK.RawKey[];
11
+ keys: PublicJsonWebKey[];
12
12
  }>;
13
13
  }
14
14
  /**
@@ -5,10 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.addStatementDefaultFields = void 0;
7
7
  const formatISO_1 = __importDefault(require("date-fns/formatISO"));
8
- const uuid_1 = require("uuid");
9
8
  const attempt_utils_js_1 = require("./attempt-utils.js");
10
9
  const addStatementDefaultFields = (statement, user) => ({
11
- id: (0, uuid_1.v4)(),
10
+ id: globalThis.crypto.randomUUID(),
12
11
  actor: (0, attempt_utils_js_1.formatAgent)(user.uuid),
13
12
  timestamp: (0, formatISO_1.default)(new Date()),
14
13
  ...statement,
@@ -37,10 +37,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.fileSystemLrsGateway = void 0;
40
+ const crypto_1 = require("crypto");
40
41
  const fsModule = __importStar(require("fs"));
41
42
  const path_1 = __importDefault(require("path"));
42
43
  const formatISO_1 = __importDefault(require("date-fns/formatISO"));
43
- const uuid_1 = require("uuid");
44
44
  const index_js_1 = require("../../assertions/index.js");
45
45
  const index_js_2 = require("../../config/index.js");
46
46
  const index_js_3 = require("../../errors/index.js");
@@ -108,7 +108,7 @@ const fileSystemLrsGateway = (initializer) => (configProvider) => ({ authProvide
108
108
  : (0, index_js_1.assertDefined)(await authProvider.getUser(), new index_js_3.UnauthorizedError);
109
109
  const statementsWithDefaults = statements.map(statement => ({
110
110
  ...statement,
111
- id: (0, uuid_1.v4)(),
111
+ id: (0, crypto_1.randomUUID)(),
112
112
  actor: (0, attempt_utils_js_1.formatAgent)(author.uuid),
113
113
  timestamp: (0, formatISO_1.default)(new Date()),
114
114
  }));