@fgv/ts-extras 5.1.0-17 → 5.1.0-19
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/packlets/ai-assist/apiClient.js +247 -24
- package/dist/packlets/ai-assist/index.js +1 -1
- package/dist/packlets/ai-assist/registry.js +49 -4
- package/dist/packlets/crypto-utils/index.browser.js +2 -0
- package/dist/packlets/crypto-utils/index.js +2 -0
- package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +47 -0
- package/dist/packlets/crypto-utils/keystore/converters.js +101 -9
- package/dist/packlets/crypto-utils/keystore/index.js +1 -0
- package/dist/packlets/crypto-utils/keystore/keyStore.js +271 -46
- package/dist/packlets/crypto-utils/keystore/model.js +22 -1
- package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
- package/dist/packlets/crypto-utils/model.js +5 -0
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js +140 -1
- package/dist/test/unit/crypto/keystore/inMemoryPrivateKeyStorage.js +78 -0
- package/dist/ts-extras.d.ts +799 -40
- package/lib/packlets/ai-assist/apiClient.d.ts +11 -3
- package/lib/packlets/ai-assist/apiClient.js +245 -22
- package/lib/packlets/ai-assist/index.d.ts +2 -2
- package/lib/packlets/ai-assist/index.js +3 -1
- package/lib/packlets/ai-assist/model.d.ts +66 -5
- package/lib/packlets/ai-assist/registry.d.ts +25 -1
- package/lib/packlets/ai-assist/registry.js +51 -4
- package/lib/packlets/crypto-utils/index.browser.d.ts +1 -0
- package/lib/packlets/crypto-utils/index.browser.js +4 -1
- package/lib/packlets/crypto-utils/index.d.ts +1 -0
- package/lib/packlets/crypto-utils/index.js +4 -1
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +39 -0
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +50 -0
- package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
- package/lib/packlets/crypto-utils/keystore/converters.js +100 -8
- package/lib/packlets/crypto-utils/keystore/index.d.ts +1 -0
- package/lib/packlets/crypto-utils/keystore/index.js +1 -0
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +77 -9
- package/lib/packlets/crypto-utils/keystore/keyStore.js +271 -46
- package/lib/packlets/crypto-utils/keystore/model.d.ts +238 -19
- package/lib/packlets/crypto-utils/keystore/model.js +24 -2
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +50 -0
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
- package/lib/packlets/crypto-utils/model.d.ts +130 -0
- package/lib/packlets/crypto-utils/model.js +6 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +45 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js +139 -0
- package/package.json +7 -7
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
18
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
19
|
// SOFTWARE.
|
|
20
|
+
// Re-export so consumers can continue to access the algorithm enum via the
|
|
21
|
+
// CryptoUtils.KeyStore namespace alongside the rest of the keystore types.
|
|
22
|
+
export { allKeyPairAlgorithms } from '../model';
|
|
20
23
|
/**
|
|
21
24
|
* Current format version constant.
|
|
22
25
|
* @public
|
|
@@ -33,11 +36,29 @@ export const DEFAULT_KEYSTORE_ITERATIONS = 600000;
|
|
|
33
36
|
* @public
|
|
34
37
|
*/
|
|
35
38
|
export const MIN_SALT_LENGTH = 16;
|
|
39
|
+
/**
|
|
40
|
+
* All valid symmetric secret types.
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export const allKeyStoreSymmetricSecretTypes = [
|
|
44
|
+
'encryption-key',
|
|
45
|
+
'api-key'
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* All valid asymmetric secret types.
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export const allKeyStoreAsymmetricSecretTypes = [
|
|
52
|
+
'asymmetric-keypair'
|
|
53
|
+
];
|
|
36
54
|
/**
|
|
37
55
|
* All valid key store secret types.
|
|
38
56
|
* @public
|
|
39
57
|
*/
|
|
40
|
-
export const allKeyStoreSecretTypes = [
|
|
58
|
+
export const allKeyStoreSecretTypes = [
|
|
59
|
+
...allKeyStoreAsymmetricSecretTypes,
|
|
60
|
+
...allKeyStoreSymmetricSecretTypes
|
|
61
|
+
];
|
|
41
62
|
/**
|
|
42
63
|
* Default PBKDF2 iterations for secret-level key derivation.
|
|
43
64
|
* Lower than keystore encryption since these are used more frequently.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright (c) 2026 Erik Fortune
|
|
2
|
+
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
// furnished to do so, subject to the following conditions:
|
|
9
|
+
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
// SOFTWARE.
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=privateKeyStorage.js.map
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
// SOFTWARE.
|
|
20
20
|
import * as Constants from './constants';
|
|
21
21
|
export { Constants };
|
|
22
|
+
/**
|
|
23
|
+
* All valid key pair algorithms.
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export const allKeyPairAlgorithms = ['ecdsa-p256', 'rsa-oaep-2048'];
|
|
22
27
|
// ============================================================================
|
|
23
28
|
// Detection Helper
|
|
24
29
|
// ============================================================================
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
19
|
// SOFTWARE.
|
|
20
20
|
import * as crypto from 'crypto';
|
|
21
|
-
import { captureResult, fail, Failure, succeed, Success } from '@fgv/ts-utils';
|
|
21
|
+
import { captureAsyncResult, captureResult, fail, Failure, succeed, Success } from '@fgv/ts-utils';
|
|
22
22
|
import * as Constants from './constants';
|
|
23
|
+
import { keyPairAlgorithmParams } from './keyPairAlgorithmParams';
|
|
23
24
|
/**
|
|
24
25
|
* Node.js implementation of {@link CryptoUtils.ICryptoProvider} using the built-in crypto module.
|
|
25
26
|
* Uses AES-256-GCM for authenticated encryption.
|
|
@@ -162,6 +163,144 @@ export class NodeCryptoProvider {
|
|
|
162
163
|
}
|
|
163
164
|
return Success.with(new Uint8Array(Buffer.from(base64, 'base64')));
|
|
164
165
|
}
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// Asymmetric Key Operations
|
|
168
|
+
// ============================================================================
|
|
169
|
+
/**
|
|
170
|
+
* Generates a new asymmetric keypair using Node's WebCrypto.
|
|
171
|
+
* @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
|
|
172
|
+
* @param extractable - Whether the resulting keys may be exported.
|
|
173
|
+
* @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
|
|
174
|
+
*/
|
|
175
|
+
async generateKeyPair(algorithm, extractable) {
|
|
176
|
+
const params = keyPairAlgorithmParams[algorithm];
|
|
177
|
+
const result = await captureAsyncResult(() => crypto.webcrypto.subtle.generateKey(params.generateKey, extractable, params.keyPairUsages));
|
|
178
|
+
return result.withErrorFormat((e) => `Failed to generate ${algorithm} keypair: ${e}`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Exports a public `CryptoKey` as a JSON Web Key.
|
|
182
|
+
* @remarks
|
|
183
|
+
* Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
|
|
184
|
+
* does not enforce public-vs-private; without this guard a caller that
|
|
185
|
+
* passed an extractable private key would receive its private fields
|
|
186
|
+
* (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
|
|
187
|
+
* @param publicKey - Extractable public key to export.
|
|
188
|
+
* @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
|
|
189
|
+
*/
|
|
190
|
+
async exportPublicKeyJwk(publicKey) {
|
|
191
|
+
if (publicKey.type !== 'public') {
|
|
192
|
+
return fail(`exportPublicKeyJwk requires a public CryptoKey, got '${publicKey.type}'`);
|
|
193
|
+
}
|
|
194
|
+
const result = await captureAsyncResult(() => crypto.webcrypto.subtle.exportKey('jwk', publicKey));
|
|
195
|
+
return result.withErrorFormat((e) => `Failed to export public key as JWK: ${e}`);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
|
|
199
|
+
* @param jwk - The JSON Web Key produced by a prior export.
|
|
200
|
+
* @param algorithm - The algorithm the key was generated for.
|
|
201
|
+
* @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
|
|
202
|
+
*/
|
|
203
|
+
async importPublicKeyJwk(jwk, algorithm) {
|
|
204
|
+
const params = keyPairAlgorithmParams[algorithm];
|
|
205
|
+
const result = await captureAsyncResult(() => crypto.webcrypto.subtle.importKey('jwk', jwk, params.importPublicKey, true, params.publicKeyUsages));
|
|
206
|
+
return result.withErrorFormat((e) => `Failed to import ${algorithm} public key from JWK: ${e}`);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Wraps `plaintext` for the holder of `recipientPublicKey` using
|
|
210
|
+
* ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
|
|
211
|
+
* {@link CryptoUtils.ICryptoProvider.wrapBytes | ICryptoProvider.wrapBytes}.
|
|
212
|
+
* @param plaintext - The bytes to wrap.
|
|
213
|
+
* @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.
|
|
214
|
+
* @param options - HKDF salt and info; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.
|
|
215
|
+
* @returns `Success` with the wrapped payload, or `Failure` with an error.
|
|
216
|
+
*/
|
|
217
|
+
async wrapBytes(plaintext, recipientPublicKey, options) {
|
|
218
|
+
const recipientCheck = checkEcdhP256(recipientPublicKey, 'public', 'recipient public key');
|
|
219
|
+
if (recipientCheck.isFailure()) {
|
|
220
|
+
return fail(`wrapBytes failed: ${recipientCheck.message}`);
|
|
221
|
+
}
|
|
222
|
+
const subtle = crypto.webcrypto.subtle;
|
|
223
|
+
const result = await captureAsyncResult(async () => {
|
|
224
|
+
const ephemeral = (await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, [
|
|
225
|
+
'deriveKey'
|
|
226
|
+
]));
|
|
227
|
+
const hkdfBase = await subtle.deriveKey({ name: 'ECDH', public: recipientPublicKey }, ephemeral.privateKey, { name: 'HKDF' }, false, ['deriveKey']);
|
|
228
|
+
const wrapKey = await subtle.deriveKey({ name: 'HKDF', salt: options.salt, info: options.info, hash: 'SHA-256' }, hkdfBase, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
|
|
229
|
+
const nonce = crypto.randomBytes(Constants.GCM_IV_SIZE);
|
|
230
|
+
const ctBuf = await subtle.encrypt({ name: 'AES-GCM', iv: nonce }, wrapKey, plaintext);
|
|
231
|
+
const ephemeralPublicKey = await subtle.exportKey('jwk', ephemeral.publicKey);
|
|
232
|
+
return {
|
|
233
|
+
ephemeralPublicKey,
|
|
234
|
+
nonce: this.toBase64(nonce),
|
|
235
|
+
ciphertext: this.toBase64(new Uint8Array(ctBuf))
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
return result.withErrorFormat((e) => `wrapBytes failed: ${e}`);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Unwraps a payload produced by `wrapBytes` using the recipient's private
|
|
242
|
+
* key. See {@link CryptoUtils.ICryptoProvider.unwrapBytes | ICryptoProvider.unwrapBytes}.
|
|
243
|
+
* @param wrapped - The wrapped payload.
|
|
244
|
+
* @param recipientPrivateKey - The recipient's ECDH P-256 private `CryptoKey`.
|
|
245
|
+
* @param options - HKDF salt and info matching the wrap call.
|
|
246
|
+
* @returns `Success` with the original `plaintext`, or `Failure` with an error.
|
|
247
|
+
*/
|
|
248
|
+
async unwrapBytes(wrapped, recipientPrivateKey, options) {
|
|
249
|
+
const recipientCheck = checkEcdhP256(recipientPrivateKey, 'private', 'recipient private key');
|
|
250
|
+
if (recipientCheck.isFailure()) {
|
|
251
|
+
return fail(`unwrapBytes failed: ${recipientCheck.message}`);
|
|
252
|
+
}
|
|
253
|
+
const nonceResult = this.fromBase64(wrapped.nonce);
|
|
254
|
+
if (nonceResult.isFailure()) {
|
|
255
|
+
return fail(`unwrapBytes failed: nonce: ${nonceResult.message}`);
|
|
256
|
+
}
|
|
257
|
+
if (nonceResult.value.length !== Constants.GCM_IV_SIZE) {
|
|
258
|
+
return fail(`unwrapBytes failed: nonce must be ${Constants.GCM_IV_SIZE} bytes (got ${nonceResult.value.length})`);
|
|
259
|
+
}
|
|
260
|
+
const ciphertextResult = this.fromBase64(wrapped.ciphertext);
|
|
261
|
+
if (ciphertextResult.isFailure()) {
|
|
262
|
+
return fail(`unwrapBytes failed: ciphertext: ${ciphertextResult.message}`);
|
|
263
|
+
}
|
|
264
|
+
if (ciphertextResult.value.length < Constants.GCM_AUTH_TAG_SIZE) {
|
|
265
|
+
return fail(`unwrapBytes failed: ciphertext must be at least ${Constants.GCM_AUTH_TAG_SIZE} bytes (got ${ciphertextResult.value.length})`);
|
|
266
|
+
}
|
|
267
|
+
const subtle = crypto.webcrypto.subtle;
|
|
268
|
+
const result = await captureAsyncResult(async () => {
|
|
269
|
+
const ephemeralPub = await subtle.importKey('jwk', wrapped.ephemeralPublicKey, { name: 'ECDH', namedCurve: 'P-256' }, false, []);
|
|
270
|
+
const hkdfBase = await subtle.deriveKey({ name: 'ECDH', public: ephemeralPub }, recipientPrivateKey, { name: 'HKDF' }, false, ['deriveKey']);
|
|
271
|
+
const wrapKey = await subtle.deriveKey({ name: 'HKDF', salt: options.salt, info: options.info, hash: 'SHA-256' }, hkdfBase, { name: 'AES-GCM', length: 256 }, false, ['decrypt']);
|
|
272
|
+
const ptBuf = await subtle.decrypt({ name: 'AES-GCM', iv: nonceResult.value }, wrapKey, ciphertextResult.value);
|
|
273
|
+
return new Uint8Array(ptBuf);
|
|
274
|
+
});
|
|
275
|
+
return result.withErrorFormat((e) => `unwrapBytes failed: ${e}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Verifies that `key` is an ECDH P-256 `CryptoKey` of the expected `keyType`
|
|
280
|
+
* (public or private). Used by the wrap/unwrap methods to surface a clean
|
|
281
|
+
* `Failure` instead of letting the WebCrypto deriveKey call throw a less
|
|
282
|
+
* informative error later in the pipeline. Key usages are intentionally not
|
|
283
|
+
* checked here: WebCrypto already produces a specific error if `deriveKey` is
|
|
284
|
+
* not in `usages`, and `deriveBits` is an equally valid alternative usage that
|
|
285
|
+
* an explicit check would have to track.
|
|
286
|
+
* @param key - The CryptoKey to validate.
|
|
287
|
+
* @param keyType - The required `key.type` ('public' for wrap, 'private' for unwrap).
|
|
288
|
+
* @param label - Human-readable role label included in the failure message.
|
|
289
|
+
* @returns `Success` with the key (unchanged) when the algorithm, curve, and
|
|
290
|
+
* type all match; otherwise `Failure` with `<label> must be ECDH P-256 (...)`.
|
|
291
|
+
*/
|
|
292
|
+
function checkEcdhP256(key, keyType, label) {
|
|
293
|
+
if (key.algorithm.name !== 'ECDH') {
|
|
294
|
+
return fail(`${label} must be ECDH P-256 (got algorithm '${key.algorithm.name}')`);
|
|
295
|
+
}
|
|
296
|
+
const namedCurve = key.algorithm.namedCurve;
|
|
297
|
+
if (namedCurve !== 'P-256') {
|
|
298
|
+
return fail(`${label} must be ECDH P-256 (got curve '${namedCurve}')`);
|
|
299
|
+
}
|
|
300
|
+
if (key.type !== keyType) {
|
|
301
|
+
return fail(`${label} must be a ${keyType} CryptoKey (got '${key.type}')`);
|
|
302
|
+
}
|
|
303
|
+
return succeed(key);
|
|
165
304
|
}
|
|
166
305
|
/**
|
|
167
306
|
* Singleton instance of {@link CryptoUtils.NodeCryptoProvider}.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Copyright (c) 2026 Erik Fortune
|
|
2
|
+
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
// furnished to do so, subject to the following conditions:
|
|
9
|
+
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
// SOFTWARE.
|
|
20
|
+
import { fail, succeed } from '@fgv/ts-utils';
|
|
21
|
+
/**
|
|
22
|
+
* In-memory implementation of `IPrivateKeyStorage` for keystore tests.
|
|
23
|
+
*
|
|
24
|
+
* Not exported from `@fgv/ts-extras`. Lives in the test tree as a reference
|
|
25
|
+
* implementation downstream packages may copy if useful, but the public API
|
|
26
|
+
* delegates concrete backends to platform-specific packages
|
|
27
|
+
* (browser/IDB in `@fgv/ts-web-extras`, encrypted-file in `@fgv/ts-chocolate`).
|
|
28
|
+
*
|
|
29
|
+
* Holds `CryptoKey` objects directly in a `Map`, so it advertises
|
|
30
|
+
* `supportsNonExtractable: true` by default. The constructor accepts overrides
|
|
31
|
+
* useful for negative tests:
|
|
32
|
+
* - `supportsNonExtractable: false` exercises the extractable=true codepath.
|
|
33
|
+
* - `failOn: { store?, load?, delete?, list? }` makes the named operations
|
|
34
|
+
* return Failure with a stable message so tests can assert downstream
|
|
35
|
+
* warning/error propagation without resorting to mocks.
|
|
36
|
+
*/
|
|
37
|
+
export class InMemoryPrivateKeyStorage {
|
|
38
|
+
constructor(options) {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
this.supportsNonExtractable = (_a = options === null || options === void 0 ? void 0 : options.supportsNonExtractable) !== null && _a !== void 0 ? _a : true;
|
|
41
|
+
this.entries = new Map();
|
|
42
|
+
this._failOn = (_b = options === null || options === void 0 ? void 0 : options.failOn) !== null && _b !== void 0 ? _b : {};
|
|
43
|
+
}
|
|
44
|
+
async store(id, key) {
|
|
45
|
+
if (this._failOn.store) {
|
|
46
|
+
return fail(this._failOn.store);
|
|
47
|
+
}
|
|
48
|
+
this.entries.set(id, key);
|
|
49
|
+
return succeed(id);
|
|
50
|
+
}
|
|
51
|
+
async load(id) {
|
|
52
|
+
if (this._failOn.load) {
|
|
53
|
+
return fail(this._failOn.load);
|
|
54
|
+
}
|
|
55
|
+
const key = this.entries.get(id);
|
|
56
|
+
if (!key) {
|
|
57
|
+
return fail(`No private key for id '${id}'`);
|
|
58
|
+
}
|
|
59
|
+
return succeed(key);
|
|
60
|
+
}
|
|
61
|
+
async delete(id) {
|
|
62
|
+
if (this._failOn.delete) {
|
|
63
|
+
return fail(this._failOn.delete);
|
|
64
|
+
}
|
|
65
|
+
if (!this.entries.has(id)) {
|
|
66
|
+
return fail(`No private key for id '${id}'`);
|
|
67
|
+
}
|
|
68
|
+
this.entries.delete(id);
|
|
69
|
+
return succeed(id);
|
|
70
|
+
}
|
|
71
|
+
async list() {
|
|
72
|
+
if (this._failOn.list) {
|
|
73
|
+
return fail(this._failOn.list);
|
|
74
|
+
}
|
|
75
|
+
return succeed(Array.from(this.entries.keys()));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=inMemoryPrivateKeyStorage.js.map
|