@openstax/ts-utils 1.45.1 → 1.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/services/httpMessage/index.d.ts +2 -0
- package/dist/cjs/services/httpMessage/index.js +7 -0
- package/dist/cjs/services/httpMessage/signer.d.ts +15 -0
- package/dist/cjs/services/httpMessage/signer.js +42 -0
- package/dist/cjs/services/keyStore/index.d.ts +20 -0
- package/dist/cjs/services/keyStore/index.js +27 -0
- package/dist/cjs/services/launchParams/signer.d.ts +4 -6
- package/dist/cjs/services/launchParams/signer.js +6 -12
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/esm/services/httpMessage/index.d.ts +2 -0
- package/dist/esm/services/httpMessage/index.js +2 -0
- package/dist/esm/services/httpMessage/signer.d.ts +15 -0
- package/dist/esm/services/httpMessage/signer.js +38 -0
- package/dist/esm/services/keyStore/index.d.ts +20 -0
- package/dist/esm/services/keyStore/index.js +23 -0
- package/dist/esm/services/launchParams/signer.d.ts +4 -6
- package/dist/esm/services/launchParams/signer.js +6 -12
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/package.json +10 -5
- /package/dist/cjs/services/{httpMessageVerifier/index.d.ts → httpMessage/verifier.d.ts} +0 -0
- /package/dist/cjs/services/{httpMessageVerifier/index.js → httpMessage/verifier.js} +0 -0
- /package/dist/esm/services/{httpMessageVerifier/index.d.ts → httpMessage/verifier.d.ts} +0 -0
- /package/dist/esm/services/{httpMessageVerifier/index.js → httpMessage/verifier.js} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createHttpMessageVerifier = exports.createHttpMessageSigner = void 0;
|
|
4
|
+
var signer_js_1 = require("./signer.js");
|
|
5
|
+
Object.defineProperty(exports, "createHttpMessageSigner", { enumerable: true, get: function () { return signer_js_1.createHttpMessageSigner; } });
|
|
6
|
+
var verifier_js_1 = require("./verifier.js");
|
|
7
|
+
Object.defineProperty(exports, "createHttpMessageVerifier", { enumerable: true, get: function () { return verifier_js_1.createHttpMessageVerifier; } });
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ConfigProviderForConfig } from '../../config/index.js';
|
|
2
|
+
import { KeyStore } from '../keyStore/index.js';
|
|
3
|
+
type Config = {
|
|
4
|
+
iss: string;
|
|
5
|
+
};
|
|
6
|
+
interface Initializer<C> {
|
|
7
|
+
configSpace?: C;
|
|
8
|
+
}
|
|
9
|
+
export declare const createHttpMessageSigner: <C extends string = "signer">({ configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }, services: {
|
|
10
|
+
keyStore: KeyStore;
|
|
11
|
+
}) => {
|
|
12
|
+
signRequest: (method: string, url: string, bodyString: string) => Promise<Record<string, string>>;
|
|
13
|
+
};
|
|
14
|
+
export type HttpMessageSigner = ReturnType<ReturnType<typeof createHttpMessageSigner>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createHttpMessageSigner = void 0;
|
|
4
|
+
/* spell-checker: ignore httpbis meunier keyid */
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const http_message_signatures_1 = require("http-message-signatures");
|
|
7
|
+
const index_js_1 = require("../../config/index.js");
|
|
8
|
+
const helpers_js_1 = require("../../misc/helpers.js");
|
|
9
|
+
const createHttpMessageSigner = ({ configSpace }) => (configProvider, services) => {
|
|
10
|
+
const config = configProvider[configSpace !== null && configSpace !== void 0 ? configSpace : 'signer'];
|
|
11
|
+
const getIss = (0, helpers_js_1.once)(async () => (await (0, index_js_1.resolveConfigValue)(config.iss)).replace(/\/+$/, ''));
|
|
12
|
+
const getKey = (0, helpers_js_1.once)(() => services.keyStore.getPrivateKey());
|
|
13
|
+
const getSigner = (0, helpers_js_1.once)(async () => {
|
|
14
|
+
const { pem } = await getKey();
|
|
15
|
+
return (0, http_message_signatures_1.createSigner)(pem, 'rsa-v1_5-sha256');
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
signRequest: async (method, url, bodyString) => {
|
|
19
|
+
const { kid } = await getKey();
|
|
20
|
+
const digest = (0, crypto_1.createHash)('sha256').update(bodyString).digest('base64');
|
|
21
|
+
const key = await getSigner();
|
|
22
|
+
const signed = await http_message_signatures_1.httpbis.signMessage({
|
|
23
|
+
key,
|
|
24
|
+
// draft-meunier-http-message-signatures-directory requires signature-agent
|
|
25
|
+
// to be a covered component alongside the standard RFC 9421 derived components
|
|
26
|
+
fields: ['@method', '@target-uri', 'content-digest', 'signature-agent'],
|
|
27
|
+
params: ['keyid', 'alg'],
|
|
28
|
+
paramValues: { keyid: kid, alg: 'rsa-v1_5-sha256' },
|
|
29
|
+
}, {
|
|
30
|
+
method,
|
|
31
|
+
url,
|
|
32
|
+
headers: {
|
|
33
|
+
// RFC 8941 byte sequence: sha-256=:base64value:
|
|
34
|
+
'Content-Digest': `sha-256=:${digest}:`,
|
|
35
|
+
'Signature-Agent': `${await getIss()}/.well-known/jwks.json`,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
return signed.headers;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
exports.createHttpMessageSigner = createHttpMessageSigner;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { JWK } from 'node-jose';
|
|
2
|
+
import { ConfigProviderForConfig } from '../../config/index.js';
|
|
3
|
+
type Config = {
|
|
4
|
+
privateKey: string;
|
|
5
|
+
};
|
|
6
|
+
export type PrivateKey = {
|
|
7
|
+
kid: string;
|
|
8
|
+
pem: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const createKeyStore: (config: ConfigProviderForConfig<Config>) => {
|
|
11
|
+
getPrivateKey: () => Promise<{
|
|
12
|
+
kid: string;
|
|
13
|
+
pem: string;
|
|
14
|
+
}>;
|
|
15
|
+
jwks: () => Promise<{
|
|
16
|
+
keys: JWK.RawKey[];
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export type KeyStore = ReturnType<typeof createKeyStore>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createKeyStore = void 0;
|
|
4
|
+
const node_jose_1 = require("node-jose");
|
|
5
|
+
const index_js_1 = require("../../config/index.js");
|
|
6
|
+
const helpers_js_1 = require("../../misc/helpers.js");
|
|
7
|
+
const createKeyStore = (config) => {
|
|
8
|
+
const store = (0, helpers_js_1.once)(async () => {
|
|
9
|
+
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 };
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
// this method only supports one key for now (always returns the first key)
|
|
17
|
+
getPrivateKey: async () => {
|
|
18
|
+
const { keys } = await store();
|
|
19
|
+
return keys[0];
|
|
20
|
+
},
|
|
21
|
+
jwks: async () => {
|
|
22
|
+
const { keyStore } = await store();
|
|
23
|
+
return keyStore.toJSON(false);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.createKeyStore = createKeyStore;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { JWK } from 'node-jose';
|
|
2
1
|
import { ConfigProviderForConfig } from '../../config/index.js';
|
|
3
2
|
import type { JsonCompatibleStruct } from '../../routing/index.js';
|
|
3
|
+
import { KeyStore } from '../keyStore/index.js';
|
|
4
4
|
type Config = {
|
|
5
5
|
alg: string;
|
|
6
6
|
expiresIn: string;
|
|
7
7
|
iss: string;
|
|
8
|
-
privateKey: string;
|
|
9
8
|
};
|
|
10
9
|
interface Initializer<C> {
|
|
11
10
|
configSpace?: C;
|
|
@@ -13,10 +12,9 @@ interface Initializer<C> {
|
|
|
13
12
|
/**
|
|
14
13
|
* Creates a class that can sign launch params
|
|
15
14
|
*/
|
|
16
|
-
export declare const createLaunchSigner: <C extends string = "launch">({ configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}>;
|
|
15
|
+
export declare const createLaunchSigner: <C extends string = "launch">({ configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }, services: {
|
|
16
|
+
keyStore: KeyStore;
|
|
17
|
+
}) => {
|
|
20
18
|
sign: (data: JsonCompatibleStruct, subject: string, maxExp?: number | null) => Promise<string>;
|
|
21
19
|
};
|
|
22
20
|
export type LaunchSigner = ReturnType<ReturnType<typeof createLaunchSigner>>;
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.createLaunchSigner = void 0;
|
|
7
7
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
8
|
const ms_1 = __importDefault(require("ms"));
|
|
9
|
-
const node_jose_1 = require("node-jose");
|
|
10
9
|
const index_js_1 = require("../../config/index.js");
|
|
11
10
|
const index_js_2 = require("../../guards/index.js");
|
|
12
11
|
const index_js_3 = require("../../index.js");
|
|
@@ -22,18 +21,12 @@ const assertAlg = (alg) => {
|
|
|
22
21
|
/**
|
|
23
22
|
* Creates a class that can sign launch params
|
|
24
23
|
*/
|
|
25
|
-
const createLaunchSigner = ({ configSpace }) => (configProvider) => {
|
|
24
|
+
const createLaunchSigner = ({ configSpace }) => (configProvider, services) => {
|
|
26
25
|
const config = configProvider[(0, index_js_2.ifDefined)(configSpace, 'launch')];
|
|
27
26
|
const getAlg = (0, index_js_3.once)(async () => assertAlg(await (0, index_js_1.resolveConfigValue)(config.alg)));
|
|
28
27
|
const getExpiresIn = (0, index_js_3.once)(() => (0, index_js_1.resolveConfigValue)(config.expiresIn));
|
|
29
28
|
const getIss = (0, index_js_3.once)(() => (0, index_js_1.resolveConfigValue)(config.iss));
|
|
30
|
-
const
|
|
31
|
-
const getKeyStore = (0, index_js_3.once)(async () => {
|
|
32
|
-
const keystore = node_jose_1.JWK.createKeyStore();
|
|
33
|
-
await keystore.add(await getPrivateKey(), 'pem');
|
|
34
|
-
return keystore;
|
|
35
|
-
});
|
|
36
|
-
const jwks = async () => (await getKeyStore()).toJSON(false);
|
|
29
|
+
const getKey = (0, index_js_3.once)(() => services.keyStore.getPrivateKey());
|
|
37
30
|
const getExpiresInWithMax = async (maxExp) => {
|
|
38
31
|
const expiresIn = await getExpiresIn();
|
|
39
32
|
// The ms library used by jsonwebtoken can handle a value in seconds as well as a string like '1d'
|
|
@@ -46,13 +39,14 @@ const createLaunchSigner = ({ configSpace }) => (configProvider) => {
|
|
|
46
39
|
return Math.min(expiresInSeconds, maxExpSeconds);
|
|
47
40
|
};
|
|
48
41
|
const sign = async (data, subject, maxExp) => {
|
|
42
|
+
const { kid, pem } = await getKey();
|
|
49
43
|
const alg = await getAlg();
|
|
50
44
|
// expiresIn can be a number of seconds or a string like '1h' or '1d'
|
|
51
45
|
const expiresIn = await getExpiresInWithMax(maxExp);
|
|
52
46
|
const iss = await getIss();
|
|
53
|
-
const header = { alg, iss };
|
|
54
|
-
return jsonwebtoken_1.default.sign(data,
|
|
47
|
+
const header = { alg, iss, kid };
|
|
48
|
+
return jsonwebtoken_1.default.sign(data, pem, { algorithm: alg, expiresIn, header, issuer: iss, subject });
|
|
55
49
|
};
|
|
56
|
-
return {
|
|
50
|
+
return { sign };
|
|
57
51
|
};
|
|
58
52
|
exports.createLaunchSigner = createLaunchSigner;
|