@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.
- package/dist/cjs/misc/hashValue.js +2 -2
- package/dist/cjs/misc/jwks.d.ts +5 -2
- package/dist/cjs/services/apiGateway/index.js +1 -2
- package/dist/cjs/services/authProvider/index.js +3 -6
- package/dist/cjs/services/authProvider/utils/userSubrequest.js +2 -5
- package/dist/cjs/services/fileServer/localFileServer.js +2 -3
- package/dist/cjs/services/fileServer/s3FileServer.js +2 -2
- package/dist/cjs/services/httpMessage/verifier.d.ts +2 -2
- package/dist/cjs/services/keyStore/index.d.ts +3 -6
- package/dist/cjs/services/keyStore/index.js +20 -9
- package/dist/cjs/services/launchParams/verifier.d.ts +2 -2
- package/dist/cjs/services/lrsGateway/addStatementDefaultFields.js +1 -2
- package/dist/cjs/services/lrsGateway/file-system.js +2 -2
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/esm/misc/hashValue.js +2 -2
- package/dist/esm/misc/jwks.d.ts +5 -2
- package/dist/esm/services/apiGateway/index.js +1 -2
- package/dist/esm/services/authProvider/index.js +3 -3
- package/dist/esm/services/authProvider/utils/userSubrequest.js +2 -2
- package/dist/esm/services/fileServer/localFileServer.js +2 -3
- package/dist/esm/services/fileServer/s3FileServer.js +2 -2
- package/dist/esm/services/httpMessage/verifier.d.ts +2 -2
- package/dist/esm/services/keyStore/index.d.ts +3 -6
- package/dist/esm/services/keyStore/index.js +20 -9
- package/dist/esm/services/launchParams/verifier.d.ts +2 -2
- package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +1 -2
- package/dist/esm/services/lrsGateway/file-system.js +2 -2
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/package.json +11 -15
- package/script/bin/clone-template-temp.bash +13 -0
- package/script/bin/copy-from-template.bash +6 -11
- package/script/bin/delete-stack.bash +2 -2
- package/script/bin/deploy.bash +14 -3
- package/script/bin/destroy-deployment.bash +4 -4
- package/script/bin/get-deployed-environments.bash +1 -1
- package/script/bin/get-env-param.bash +4 -4
- package/script/bin/init-constants-script.bash +1 -1
- package/script/bin/init-params-script.bash +1 -1
- package/script/bin/log-from-template.bash +16 -0
- package/script/bin/update-utils.bash +3 -3
- package/script/bin/upload-pager-duty-endpoints.bash +3 -3
- package/script/bin/upload-params.bash +5 -5
- package/script/bin-entry.bash +1 -1
- 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
|
|
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,
|
|
16
|
+
return (0, js_sha1_1.sha1)(strValue);
|
|
17
17
|
};
|
|
18
18
|
exports.hashValue = hashValue;
|
package/dist/cjs/misc/jwks.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { webcrypto } from 'crypto';
|
|
1
2
|
import { JwksClient } from 'jwks-rsa';
|
|
2
|
-
|
|
3
|
+
export type PublicJsonWebKey = webcrypto.JsonWebKey & {
|
|
4
|
+
kid: string;
|
|
5
|
+
};
|
|
3
6
|
export type JwksFetcher = (uri: string) => Promise<{
|
|
4
|
-
keys:
|
|
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 =
|
|
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 =
|
|
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.
|
|
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.
|
|
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 =
|
|
4
|
+
const cookie_1 = require("cookie");
|
|
8
5
|
const loadUserData = (fetch, accountsBase, cookieName, token) => {
|
|
9
|
-
const headers = { cookie: cookie_1.
|
|
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,
|
|
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/' +
|
|
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,
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
11
|
-
const
|
|
12
|
-
|
|
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 {
|
|
19
|
-
return
|
|
29
|
+
const { pem, kid } = await store();
|
|
30
|
+
return { kid, pem };
|
|
20
31
|
},
|
|
21
32
|
jwks: async () => {
|
|
22
|
-
const {
|
|
23
|
-
return
|
|
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:
|
|
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:
|
|
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,
|
|
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
|
}));
|