@fgv/ts-extras 5.1.0-16 → 5.1.0-18
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/index.browser.js +2 -1
- package/dist/packlets/ai-assist/apiClient.js +570 -58
- package/dist/packlets/ai-assist/chatRequestBuilders.js +180 -0
- package/dist/packlets/ai-assist/index.js +4 -3
- package/dist/packlets/ai-assist/model.js +20 -3
- package/dist/packlets/ai-assist/registry.js +66 -10
- package/dist/packlets/ai-assist/sseParser.js +122 -0
- package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +192 -0
- package/dist/packlets/ai-assist/streamingAdapters/common.js +77 -0
- package/dist/packlets/ai-assist/streamingAdapters/gemini.js +160 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +149 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +163 -0
- package/dist/packlets/ai-assist/streamingAdapters/proxy.js +157 -0
- package/dist/packlets/ai-assist/streamingClient.js +88 -0
- package/dist/packlets/conversion/converters.js +1 -1
- 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 +44 -1
- package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
- package/dist/test/unit/crypto/keystore/inMemoryPrivateKeyStorage.js +78 -0
- package/dist/ts-extras.d.ts +1089 -37
- package/lib/index.browser.d.ts +2 -1
- package/lib/index.browser.js +3 -1
- package/lib/packlets/ai-assist/apiClient.d.ts +103 -1
- package/lib/packlets/ai-assist/apiClient.js +574 -58
- package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +89 -0
- package/lib/packlets/ai-assist/chatRequestBuilders.js +189 -0
- package/lib/packlets/ai-assist/index.d.ts +4 -3
- package/lib/packlets/ai-assist/index.js +10 -1
- package/lib/packlets/ai-assist/model.d.ts +271 -2
- package/lib/packlets/ai-assist/model.js +21 -3
- package/lib/packlets/ai-assist/registry.d.ts +10 -1
- package/lib/packlets/ai-assist/registry.js +67 -11
- package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
- package/lib/packlets/ai-assist/sseParser.js +127 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +18 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +195 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +71 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.js +81 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +19 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.js +163 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +18 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +152 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +19 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +166 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.js +160 -0
- package/lib/packlets/ai-assist/streamingClient.d.ts +33 -0
- package/lib/packlets/ai-assist/streamingClient.js +93 -0
- package/lib/packlets/conversion/converters.d.ts +1 -1
- package/lib/packlets/conversion/converters.js +1 -1
- 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 +38 -0
- package/lib/packlets/crypto-utils/model.js +6 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +26 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js +43 -0
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +2 -2
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
- package/package.json +7 -7
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { EncryptionAlgorithm, ICryptoProvider, IKeyDerivationParams } from '../model';
|
|
1
|
+
import { EncryptionAlgorithm, ICryptoProvider, IKeyDerivationParams, KeyPairAlgorithm } from '../model';
|
|
2
|
+
import { IPrivateKeyStorage } from './privateKeyStorage';
|
|
3
|
+
export { allKeyPairAlgorithms, KeyPairAlgorithm } from '../model';
|
|
2
4
|
/**
|
|
3
5
|
* Format version for key store files.
|
|
4
6
|
* @public
|
|
@@ -21,31 +23,55 @@ export declare const DEFAULT_KEYSTORE_ITERATIONS: number;
|
|
|
21
23
|
*/
|
|
22
24
|
export declare const MIN_SALT_LENGTH: number;
|
|
23
25
|
/**
|
|
24
|
-
* Discriminator for secret types stored in the vault.
|
|
26
|
+
* Discriminator for symmetric secret types stored in the vault.
|
|
25
27
|
* - `'encryption-key'`: A 32-byte AES-256 encryption key.
|
|
26
28
|
* - `'api-key'`: An arbitrary-length API key string (UTF-8 encoded).
|
|
27
29
|
* @public
|
|
28
30
|
*/
|
|
29
|
-
export type
|
|
31
|
+
export type KeyStoreSymmetricSecretType = 'encryption-key' | 'api-key';
|
|
32
|
+
/**
|
|
33
|
+
* All valid symmetric secret types.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export declare const allKeyStoreSymmetricSecretTypes: ReadonlyArray<KeyStoreSymmetricSecretType>;
|
|
37
|
+
/**
|
|
38
|
+
* Discriminator for asymmetric secret types stored in the vault.
|
|
39
|
+
* - `'asymmetric-keypair'`: A public/private key pair. The public key is held in
|
|
40
|
+
* the vault as a JWK; the private key lives in the supplied
|
|
41
|
+
* {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider.
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export type KeyStoreAsymmetricSecretType = 'asymmetric-keypair';
|
|
45
|
+
/**
|
|
46
|
+
* All valid asymmetric secret types.
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export declare const allKeyStoreAsymmetricSecretTypes: ReadonlyArray<KeyStoreAsymmetricSecretType>;
|
|
50
|
+
/**
|
|
51
|
+
* Discriminator for any secret type stored in the vault.
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
export type KeyStoreSecretType = KeyStoreSymmetricSecretType | KeyStoreAsymmetricSecretType;
|
|
30
55
|
/**
|
|
31
56
|
* All valid key store secret types.
|
|
32
57
|
* @public
|
|
33
58
|
*/
|
|
34
59
|
export declare const allKeyStoreSecretTypes: ReadonlyArray<KeyStoreSecretType>;
|
|
35
60
|
/**
|
|
36
|
-
* A secret entry stored in the vault (in-memory representation).
|
|
61
|
+
* A symmetric secret entry stored in the vault (in-memory representation).
|
|
62
|
+
* Holds the raw key material directly — for `'encryption-key'` it is a 32-byte
|
|
63
|
+
* AES-256 key; for `'api-key'` it is the UTF-8 encoded API key string.
|
|
37
64
|
* @public
|
|
38
65
|
*/
|
|
39
|
-
export interface
|
|
66
|
+
export interface IKeyStoreSymmetricEntry {
|
|
40
67
|
/**
|
|
41
68
|
* Unique name for this secret (used as lookup key).
|
|
42
69
|
*/
|
|
43
70
|
readonly name: string;
|
|
44
71
|
/**
|
|
45
|
-
*
|
|
46
|
-
* Defaults to `'encryption-key'` for backwards compatibility.
|
|
72
|
+
* Symmetric secret type discriminator.
|
|
47
73
|
*/
|
|
48
|
-
readonly type:
|
|
74
|
+
readonly type: KeyStoreSymmetricSecretType;
|
|
49
75
|
/**
|
|
50
76
|
* The secret data.
|
|
51
77
|
* - For `'encryption-key'`: 32-byte AES-256 key.
|
|
@@ -62,19 +88,83 @@ export interface IKeyStoreSecretEntry {
|
|
|
62
88
|
readonly createdAt: string;
|
|
63
89
|
}
|
|
64
90
|
/**
|
|
65
|
-
*
|
|
91
|
+
* An asymmetric keypair entry stored in the vault (in-memory representation).
|
|
92
|
+
* Holds only the public key (as a JWK) and a stable handle (`id`) the
|
|
93
|
+
* {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider uses to fetch the private key.
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
export interface IKeyStoreAsymmetricEntry {
|
|
97
|
+
/**
|
|
98
|
+
* Unique name for this entry (used as vault lookup key, renameable).
|
|
99
|
+
*/
|
|
100
|
+
readonly name: string;
|
|
101
|
+
/**
|
|
102
|
+
* Asymmetric secret type discriminator.
|
|
103
|
+
*/
|
|
104
|
+
readonly type: KeyStoreAsymmetricSecretType;
|
|
105
|
+
/**
|
|
106
|
+
* Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
|
|
107
|
+
* private key. Independent of `name`; survives renames.
|
|
108
|
+
*/
|
|
109
|
+
readonly id: string;
|
|
110
|
+
/**
|
|
111
|
+
* Algorithm used to generate this keypair.
|
|
112
|
+
*/
|
|
113
|
+
readonly algorithm: KeyPairAlgorithm;
|
|
114
|
+
/**
|
|
115
|
+
* The public key as a JSON Web Key.
|
|
116
|
+
*/
|
|
117
|
+
readonly publicKeyJwk: JsonWebKey;
|
|
118
|
+
/**
|
|
119
|
+
* Optional description for this entry.
|
|
120
|
+
*/
|
|
121
|
+
readonly description?: string;
|
|
122
|
+
/**
|
|
123
|
+
* When this entry was added (ISO 8601).
|
|
124
|
+
*/
|
|
125
|
+
readonly createdAt: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Any vault entry, discriminated by `type`.
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export type IKeyStoreEntry = IKeyStoreSymmetricEntry | IKeyStoreAsymmetricEntry;
|
|
132
|
+
/**
|
|
133
|
+
* Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry}.
|
|
134
|
+
* @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry} for symmetric
|
|
135
|
+
* entries or {@link CryptoUtils.KeyStore.IKeyStoreEntry} for the discriminated union.
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
export type IKeyStoreSecretEntry = IKeyStoreSymmetricEntry;
|
|
139
|
+
/**
|
|
140
|
+
* JSON-serializable representation of a symmetric secret entry.
|
|
141
|
+
*
|
|
142
|
+
* @remarks
|
|
143
|
+
* Describes the *normalized* shape after parsing. `type` is required here
|
|
144
|
+
* because the converter (see
|
|
145
|
+
* {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson})
|
|
146
|
+
* injects the default `'encryption-key'` when reading vaults written before
|
|
147
|
+
* asymmetric-keypair support added the discriminator. Raw on-wire bytes from
|
|
148
|
+
* a legacy vault may therefore omit `type`; downstream code only ever sees
|
|
149
|
+
* the post-conversion shape declared here.
|
|
150
|
+
*
|
|
66
151
|
* @public
|
|
67
152
|
*/
|
|
68
|
-
export interface
|
|
153
|
+
export interface IKeyStoreSymmetricEntryJson {
|
|
69
154
|
/**
|
|
70
155
|
* Unique name for this secret.
|
|
71
156
|
*/
|
|
72
157
|
readonly name: string;
|
|
73
158
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
159
|
+
* Symmetric secret type discriminator.
|
|
160
|
+
*
|
|
161
|
+
* Required on this normalized model type. Vaults written prior to the
|
|
162
|
+
* asymmetric-keypair support may omit this field on the wire; the
|
|
163
|
+
* converter injects `'encryption-key'` when missing for backwards
|
|
164
|
+
* compatibility, so by the time a value of this type is observed the
|
|
165
|
+
* discriminator is always present.
|
|
76
166
|
*/
|
|
77
|
-
readonly type
|
|
167
|
+
readonly type: KeyStoreSymmetricSecretType;
|
|
78
168
|
/**
|
|
79
169
|
* Base64-encoded secret data.
|
|
80
170
|
*/
|
|
@@ -89,7 +179,57 @@ export interface IKeyStoreSecretEntryJson {
|
|
|
89
179
|
readonly createdAt: string;
|
|
90
180
|
}
|
|
91
181
|
/**
|
|
92
|
-
*
|
|
182
|
+
* JSON-serializable representation of an asymmetric keypair entry.
|
|
183
|
+
* The private key is not present here — it lives in the
|
|
184
|
+
* {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider, addressed by `id`.
|
|
185
|
+
* @public
|
|
186
|
+
*/
|
|
187
|
+
export interface IKeyStoreAsymmetricEntryJson {
|
|
188
|
+
/**
|
|
189
|
+
* Unique name for this entry.
|
|
190
|
+
*/
|
|
191
|
+
readonly name: string;
|
|
192
|
+
/**
|
|
193
|
+
* Asymmetric secret type discriminator.
|
|
194
|
+
*/
|
|
195
|
+
readonly type: KeyStoreAsymmetricSecretType;
|
|
196
|
+
/**
|
|
197
|
+
* Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
|
|
198
|
+
* private key.
|
|
199
|
+
*/
|
|
200
|
+
readonly id: string;
|
|
201
|
+
/**
|
|
202
|
+
* Algorithm used to generate this keypair.
|
|
203
|
+
*/
|
|
204
|
+
readonly algorithm: KeyPairAlgorithm;
|
|
205
|
+
/**
|
|
206
|
+
* The public key as a JSON Web Key.
|
|
207
|
+
*/
|
|
208
|
+
readonly publicKeyJwk: JsonWebKey;
|
|
209
|
+
/**
|
|
210
|
+
* Optional description.
|
|
211
|
+
*/
|
|
212
|
+
readonly description?: string;
|
|
213
|
+
/**
|
|
214
|
+
* When this entry was added (ISO 8601).
|
|
215
|
+
*/
|
|
216
|
+
readonly createdAt: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Any JSON vault entry, discriminated by `type`.
|
|
220
|
+
* @public
|
|
221
|
+
*/
|
|
222
|
+
export type IKeyStoreEntryJson = IKeyStoreSymmetricEntryJson | IKeyStoreAsymmetricEntryJson;
|
|
223
|
+
/**
|
|
224
|
+
* Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}.
|
|
225
|
+
* @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson} for
|
|
226
|
+
* symmetric entries or {@link CryptoUtils.KeyStore.IKeyStoreEntryJson} for the
|
|
227
|
+
* discriminated union.
|
|
228
|
+
* @public
|
|
229
|
+
*/
|
|
230
|
+
export type IKeyStoreSecretEntryJson = IKeyStoreSymmetricEntryJson;
|
|
231
|
+
/**
|
|
232
|
+
* The decrypted vault contents - a versioned map of entries.
|
|
93
233
|
* @public
|
|
94
234
|
*/
|
|
95
235
|
export interface IKeyStoreVaultContents {
|
|
@@ -98,9 +238,9 @@ export interface IKeyStoreVaultContents {
|
|
|
98
238
|
*/
|
|
99
239
|
readonly version: KeyStoreFormat;
|
|
100
240
|
/**
|
|
101
|
-
* Map of
|
|
241
|
+
* Map of entry name to entry (symmetric or asymmetric).
|
|
102
242
|
*/
|
|
103
|
-
readonly secrets: Record<string,
|
|
243
|
+
readonly secrets: Record<string, IKeyStoreEntryJson>;
|
|
104
244
|
}
|
|
105
245
|
/**
|
|
106
246
|
* The encrypted key store file format.
|
|
@@ -150,6 +290,12 @@ export interface IKeyStoreCreateParams {
|
|
|
150
290
|
* PBKDF2 iterations (defaults to DEFAULT_KEYSTORE_ITERATIONS).
|
|
151
291
|
*/
|
|
152
292
|
readonly iterations?: number;
|
|
293
|
+
/**
|
|
294
|
+
* Optional private-key storage backend. Required to use `addKeyPair` /
|
|
295
|
+
* `getKeyPair`; absent backends still permit opening, listing, and reading
|
|
296
|
+
* public-key metadata for asymmetric entries.
|
|
297
|
+
*/
|
|
298
|
+
readonly privateKeyStorage?: IPrivateKeyStorage;
|
|
153
299
|
}
|
|
154
300
|
/**
|
|
155
301
|
* Parameters for opening an existing key store.
|
|
@@ -164,6 +310,12 @@ export interface IKeyStoreOpenParams {
|
|
|
164
310
|
* The encrypted key store file content.
|
|
165
311
|
*/
|
|
166
312
|
readonly keystoreFile: IKeyStoreFile;
|
|
313
|
+
/**
|
|
314
|
+
* Optional private-key storage backend. Required to use `addKeyPair` /
|
|
315
|
+
* `getKeyPair`; absent backends still permit opening, listing, and reading
|
|
316
|
+
* public-key metadata for asymmetric entries.
|
|
317
|
+
*/
|
|
318
|
+
readonly privateKeyStorage?: IPrivateKeyStorage;
|
|
167
319
|
}
|
|
168
320
|
/**
|
|
169
321
|
* Result of adding a secret to the key store.
|
|
@@ -173,11 +325,19 @@ export interface IAddSecretResult {
|
|
|
173
325
|
/**
|
|
174
326
|
* The secret entry that was added.
|
|
175
327
|
*/
|
|
176
|
-
readonly entry:
|
|
328
|
+
readonly entry: IKeyStoreSymmetricEntry;
|
|
177
329
|
/**
|
|
178
330
|
* Whether this replaced an existing secret.
|
|
179
331
|
*/
|
|
180
332
|
readonly replaced: boolean;
|
|
333
|
+
/**
|
|
334
|
+
* Best-effort warning from displaced-resource cleanup. Set when this call
|
|
335
|
+
* replaced an asymmetric-keypair entry but the corresponding
|
|
336
|
+
* {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
|
|
337
|
+
* entry is still committed and the orphaned blob is left for consumer-side
|
|
338
|
+
* GC to reconcile.
|
|
339
|
+
*/
|
|
340
|
+
readonly warning?: string;
|
|
181
341
|
}
|
|
182
342
|
/**
|
|
183
343
|
* Options for adding a secret.
|
|
@@ -206,10 +366,10 @@ export interface IImportSecretOptions extends IAddSecretOptions {
|
|
|
206
366
|
*/
|
|
207
367
|
export interface IImportKeyOptions extends IImportSecretOptions {
|
|
208
368
|
/**
|
|
209
|
-
*
|
|
369
|
+
* Symmetric secret type classification for the imported key material.
|
|
210
370
|
* @defaultValue 'encryption-key'
|
|
211
371
|
*/
|
|
212
|
-
readonly type?:
|
|
372
|
+
readonly type?: KeyStoreSymmetricSecretType;
|
|
213
373
|
}
|
|
214
374
|
/**
|
|
215
375
|
* Options for adding a secret derived from a password.
|
|
@@ -246,6 +406,65 @@ export interface IAddSecretFromPasswordResult extends IAddSecretResult {
|
|
|
246
406
|
*/
|
|
247
407
|
readonly keyDerivation: IKeyDerivationParams;
|
|
248
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Options for adding an asymmetric keypair to the key store.
|
|
411
|
+
* @public
|
|
412
|
+
*/
|
|
413
|
+
export interface IAddKeyPairOptions {
|
|
414
|
+
/**
|
|
415
|
+
* Algorithm to use for the new keypair.
|
|
416
|
+
*/
|
|
417
|
+
readonly algorithm: KeyPairAlgorithm;
|
|
418
|
+
/**
|
|
419
|
+
* Optional description for the entry.
|
|
420
|
+
*/
|
|
421
|
+
readonly description?: string;
|
|
422
|
+
/**
|
|
423
|
+
* Whether to replace an existing entry with the same name.
|
|
424
|
+
* Replacement mints a fresh storage `id` and best-effort deletes the
|
|
425
|
+
* displaced storage blob; see the keystore design doc for details.
|
|
426
|
+
*/
|
|
427
|
+
readonly replace?: boolean;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Result of adding an asymmetric keypair to the key store.
|
|
431
|
+
* @public
|
|
432
|
+
*/
|
|
433
|
+
export interface IAddKeyPairResult {
|
|
434
|
+
/**
|
|
435
|
+
* The asymmetric entry that was added.
|
|
436
|
+
*/
|
|
437
|
+
readonly entry: IKeyStoreAsymmetricEntry;
|
|
438
|
+
/**
|
|
439
|
+
* Whether this replaced an existing entry.
|
|
440
|
+
*/
|
|
441
|
+
readonly replaced: boolean;
|
|
442
|
+
/**
|
|
443
|
+
* Best-effort warning from displaced-resource cleanup. Set when this call
|
|
444
|
+
* replaced a prior entry but the corresponding
|
|
445
|
+
* {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
|
|
446
|
+
* keypair is still committed and the orphaned blob is left for consumer-side
|
|
447
|
+
* GC to reconcile.
|
|
448
|
+
*/
|
|
449
|
+
readonly warning?: string;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Result of removing a secret from the key store.
|
|
453
|
+
* @public
|
|
454
|
+
*/
|
|
455
|
+
export interface IRemoveSecretResult {
|
|
456
|
+
/**
|
|
457
|
+
* The secret entry that was removed from the vault.
|
|
458
|
+
*/
|
|
459
|
+
readonly entry: IKeyStoreEntry;
|
|
460
|
+
/**
|
|
461
|
+
* Best-effort warning from {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete
|
|
462
|
+
* for asymmetric entries when the storage call failed. The vault entry is
|
|
463
|
+
* still considered removed and the orphaned blob is left for consumer-side
|
|
464
|
+
* GC to reconcile.
|
|
465
|
+
*/
|
|
466
|
+
readonly warning?: string;
|
|
467
|
+
}
|
|
249
468
|
/**
|
|
250
469
|
* Checks if a JSON object appears to be a key store file.
|
|
251
470
|
* Uses the format field as a discriminator.
|
|
@@ -19,8 +19,12 @@
|
|
|
19
19
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
20
|
// SOFTWARE.
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.DEFAULT_SECRET_ITERATIONS = exports.allKeyStoreSecretTypes = exports.MIN_SALT_LENGTH = exports.DEFAULT_KEYSTORE_ITERATIONS = exports.KEYSTORE_FORMAT = void 0;
|
|
22
|
+
exports.DEFAULT_SECRET_ITERATIONS = exports.allKeyStoreSecretTypes = exports.allKeyStoreAsymmetricSecretTypes = exports.allKeyStoreSymmetricSecretTypes = exports.MIN_SALT_LENGTH = exports.DEFAULT_KEYSTORE_ITERATIONS = exports.KEYSTORE_FORMAT = exports.allKeyPairAlgorithms = void 0;
|
|
23
23
|
exports.isKeyStoreFile = isKeyStoreFile;
|
|
24
|
+
// Re-export so consumers can continue to access the algorithm enum via the
|
|
25
|
+
// CryptoUtils.KeyStore namespace alongside the rest of the keystore types.
|
|
26
|
+
var model_1 = require("../model");
|
|
27
|
+
Object.defineProperty(exports, "allKeyPairAlgorithms", { enumerable: true, get: function () { return model_1.allKeyPairAlgorithms; } });
|
|
24
28
|
/**
|
|
25
29
|
* Current format version constant.
|
|
26
30
|
* @public
|
|
@@ -37,11 +41,29 @@ exports.DEFAULT_KEYSTORE_ITERATIONS = 600000;
|
|
|
37
41
|
* @public
|
|
38
42
|
*/
|
|
39
43
|
exports.MIN_SALT_LENGTH = 16;
|
|
44
|
+
/**
|
|
45
|
+
* All valid symmetric secret types.
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
exports.allKeyStoreSymmetricSecretTypes = [
|
|
49
|
+
'encryption-key',
|
|
50
|
+
'api-key'
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* All valid asymmetric secret types.
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
exports.allKeyStoreAsymmetricSecretTypes = [
|
|
57
|
+
'asymmetric-keypair'
|
|
58
|
+
];
|
|
40
59
|
/**
|
|
41
60
|
* All valid key store secret types.
|
|
42
61
|
* @public
|
|
43
62
|
*/
|
|
44
|
-
exports.allKeyStoreSecretTypes = [
|
|
63
|
+
exports.allKeyStoreSecretTypes = [
|
|
64
|
+
...exports.allKeyStoreAsymmetricSecretTypes,
|
|
65
|
+
...exports.allKeyStoreSymmetricSecretTypes
|
|
66
|
+
];
|
|
45
67
|
/**
|
|
46
68
|
* Default PBKDF2 iterations for secret-level key derivation.
|
|
47
69
|
* Lower than keystore encryption since these are used more frequently.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Result } from '@fgv/ts-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Pluggable backend that persists raw asymmetric private keys outside of the
|
|
4
|
+
* encrypted keystore vault. Concrete implementations live in platform-specific
|
|
5
|
+
* packages (e.g. an IndexedDB-backed implementation in `@fgv/ts-web-extras` or
|
|
6
|
+
* an encrypted-file implementation in `@fgv/ts-chocolate`).
|
|
7
|
+
*
|
|
8
|
+
* The keystore writes storage-first: a private key is always stored here
|
|
9
|
+
* before the corresponding public-key vault entry is committed. Conversely,
|
|
10
|
+
* deletes hit the vault first and then this storage best-effort. As a result,
|
|
11
|
+
* crashes or skipped saves can leave orphaned blobs here; callers are expected
|
|
12
|
+
* to reconcile via {@link CryptoUtils.KeyStore.IPrivateKeyStorage.list} cross-referenced
|
|
13
|
+
* against the keystore's asymmetric entries.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export interface IPrivateKeyStorage {
|
|
18
|
+
/**
|
|
19
|
+
* Whether keys generated for this backend may be marked
|
|
20
|
+
* `extractable: false`. `true` on backends that store `CryptoKey`
|
|
21
|
+
* objects directly (e.g. IndexedDB). `false` on backends that must
|
|
22
|
+
* round-trip via JWK (e.g. encrypted-file backends).
|
|
23
|
+
*/
|
|
24
|
+
readonly supportsNonExtractable: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Stores `key` under `id`. Returns the stored `id` on success so the
|
|
27
|
+
* call can compose into a Result chain.
|
|
28
|
+
* @param id - Storage handle to write under.
|
|
29
|
+
* @param key - The private `CryptoKey` to persist.
|
|
30
|
+
*/
|
|
31
|
+
store(id: string, key: CryptoKey): Promise<Result<string>>;
|
|
32
|
+
/**
|
|
33
|
+
* Loads the private key previously stored under `id`.
|
|
34
|
+
* @param id - Storage handle to look up.
|
|
35
|
+
*/
|
|
36
|
+
load(id: string): Promise<Result<CryptoKey>>;
|
|
37
|
+
/**
|
|
38
|
+
* Deletes the entry stored under `id`. Returns the deleted `id` on
|
|
39
|
+
* success so the call can compose into a Result chain.
|
|
40
|
+
* @param id - Storage handle to remove.
|
|
41
|
+
*/
|
|
42
|
+
delete(id: string): Promise<Result<string>>;
|
|
43
|
+
/**
|
|
44
|
+
* Lists every `id` currently held by the backend. Used by consumers to
|
|
45
|
+
* garbage-collect orphans left by crashes or aborted sessions; the
|
|
46
|
+
* keystore itself does not invoke this automatically.
|
|
47
|
+
*/
|
|
48
|
+
list(): Promise<Result<readonly string[]>>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=privateKeyStorage.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026 Erik Fortune
|
|
3
|
+
//
|
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
// in the Software without restriction, including without limitation the rights
|
|
7
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
// furnished to do so, subject to the following conditions:
|
|
10
|
+
//
|
|
11
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
// copies or substantial portions of the Software.
|
|
13
|
+
//
|
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
// SOFTWARE.
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
//# sourceMappingURL=privateKeyStorage.js.map
|
|
@@ -44,6 +44,18 @@ export interface IEncryptionResult {
|
|
|
44
44
|
*/
|
|
45
45
|
readonly encryptedData: Uint8Array;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Asymmetric keypair algorithms supported by the crypto provider.
|
|
49
|
+
* - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.
|
|
50
|
+
* - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048';
|
|
54
|
+
/**
|
|
55
|
+
* All valid key pair algorithms.
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export declare const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm>;
|
|
47
59
|
/**
|
|
48
60
|
* Supported key derivation functions.
|
|
49
61
|
* @public
|
|
@@ -169,6 +181,32 @@ export interface ICryptoProvider {
|
|
|
169
181
|
* @returns Success with decoded bytes, or Failure if invalid base64
|
|
170
182
|
*/
|
|
171
183
|
fromBase64(base64: string): Result<Uint8Array>;
|
|
184
|
+
/**
|
|
185
|
+
* Generates a new asymmetric keypair for the requested algorithm.
|
|
186
|
+
* @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
|
|
187
|
+
* @param extractable - Whether the resulting `CryptoKey` objects may be exported.
|
|
188
|
+
* Set `false` on backends that store `CryptoKey` references directly (e.g.
|
|
189
|
+
* IndexedDB). Set `true` when the private key must round-trip through JWK or
|
|
190
|
+
* PKCS#8 (e.g. encrypted-file backends).
|
|
191
|
+
* @returns Success with the generated `CryptoKeyPair`, or Failure with error context.
|
|
192
|
+
*/
|
|
193
|
+
generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
|
|
194
|
+
/**
|
|
195
|
+
* Exports the public half of a keypair as a JSON Web Key.
|
|
196
|
+
* @param publicKey - The public `CryptoKey` to export. Must be an `extractable`
|
|
197
|
+
* key generated for an asymmetric algorithm.
|
|
198
|
+
* @returns Success with the JWK, or Failure with error context.
|
|
199
|
+
*/
|
|
200
|
+
exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
|
|
201
|
+
/**
|
|
202
|
+
* Re-imports a public-key JWK as a `CryptoKey` usable for verification or
|
|
203
|
+
* encryption (depending on algorithm).
|
|
204
|
+
* @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.
|
|
205
|
+
* @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the
|
|
206
|
+
* key was generated for. Determines the import parameters and key usages.
|
|
207
|
+
* @returns Success with the imported public `CryptoKey`, or Failure with error context.
|
|
208
|
+
*/
|
|
209
|
+
importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
|
|
172
210
|
}
|
|
173
211
|
/**
|
|
174
212
|
* High-level interface for encrypting JSON content by secret name.
|
|
@@ -52,10 +52,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
52
52
|
};
|
|
53
53
|
})();
|
|
54
54
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
-
exports.Constants = void 0;
|
|
55
|
+
exports.allKeyPairAlgorithms = exports.Constants = void 0;
|
|
56
56
|
exports.isEncryptedFile = isEncryptedFile;
|
|
57
57
|
const Constants = __importStar(require("./constants"));
|
|
58
58
|
exports.Constants = Constants;
|
|
59
|
+
/**
|
|
60
|
+
* All valid key pair algorithms.
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
exports.allKeyPairAlgorithms = ['ecdsa-p256', 'rsa-oaep-2048'];
|
|
59
64
|
// ============================================================================
|
|
60
65
|
// Detection Helper
|
|
61
66
|
// ============================================================================
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Result } from '@fgv/ts-utils';
|
|
2
|
-
import { ICryptoProvider, IEncryptionResult } from './model';
|
|
2
|
+
import { ICryptoProvider, IEncryptionResult, KeyPairAlgorithm } from './model';
|
|
3
3
|
/**
|
|
4
4
|
* Node.js implementation of {@link CryptoUtils.ICryptoProvider} using the built-in crypto module.
|
|
5
5
|
* Uses AES-256-GCM for authenticated encryption.
|
|
@@ -59,6 +59,31 @@ export declare class NodeCryptoProvider implements ICryptoProvider {
|
|
|
59
59
|
* @returns Success with decoded bytes, or Failure if invalid base64
|
|
60
60
|
*/
|
|
61
61
|
fromBase64(base64: string): Result<Uint8Array>;
|
|
62
|
+
/**
|
|
63
|
+
* Generates a new asymmetric keypair using Node's WebCrypto.
|
|
64
|
+
* @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
|
|
65
|
+
* @param extractable - Whether the resulting keys may be exported.
|
|
66
|
+
* @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
|
|
67
|
+
*/
|
|
68
|
+
generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
|
|
69
|
+
/**
|
|
70
|
+
* Exports a public `CryptoKey` as a JSON Web Key.
|
|
71
|
+
* @remarks
|
|
72
|
+
* Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
|
|
73
|
+
* does not enforce public-vs-private; without this guard a caller that
|
|
74
|
+
* passed an extractable private key would receive its private fields
|
|
75
|
+
* (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
|
|
76
|
+
* @param publicKey - Extractable public key to export.
|
|
77
|
+
* @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
|
|
78
|
+
*/
|
|
79
|
+
exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
|
|
80
|
+
/**
|
|
81
|
+
* Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
|
|
82
|
+
* @param jwk - The JSON Web Key produced by a prior export.
|
|
83
|
+
* @param algorithm - The algorithm the key was generated for.
|
|
84
|
+
* @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
|
|
85
|
+
*/
|
|
86
|
+
importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
|
|
62
87
|
}
|
|
63
88
|
/**
|
|
64
89
|
* Singleton instance of {@link CryptoUtils.NodeCryptoProvider}.
|
|
@@ -56,6 +56,7 @@ exports.nodeCryptoProvider = exports.NodeCryptoProvider = void 0;
|
|
|
56
56
|
const crypto = __importStar(require("crypto"));
|
|
57
57
|
const ts_utils_1 = require("@fgv/ts-utils");
|
|
58
58
|
const Constants = __importStar(require("./constants"));
|
|
59
|
+
const keyPairAlgorithmParams_1 = require("./keyPairAlgorithmParams");
|
|
59
60
|
/**
|
|
60
61
|
* Node.js implementation of {@link CryptoUtils.ICryptoProvider} using the built-in crypto module.
|
|
61
62
|
* Uses AES-256-GCM for authenticated encryption.
|
|
@@ -198,6 +199,48 @@ class NodeCryptoProvider {
|
|
|
198
199
|
}
|
|
199
200
|
return ts_utils_1.Success.with(new Uint8Array(Buffer.from(base64, 'base64')));
|
|
200
201
|
}
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Asymmetric Key Operations
|
|
204
|
+
// ============================================================================
|
|
205
|
+
/**
|
|
206
|
+
* Generates a new asymmetric keypair using Node's WebCrypto.
|
|
207
|
+
* @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
|
|
208
|
+
* @param extractable - Whether the resulting keys may be exported.
|
|
209
|
+
* @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
|
|
210
|
+
*/
|
|
211
|
+
async generateKeyPair(algorithm, extractable) {
|
|
212
|
+
const params = keyPairAlgorithmParams_1.keyPairAlgorithmParams[algorithm];
|
|
213
|
+
const result = await (0, ts_utils_1.captureAsyncResult)(() => crypto.webcrypto.subtle.generateKey(params.generateKey, extractable, params.keyPairUsages));
|
|
214
|
+
return result.withErrorFormat((e) => `Failed to generate ${algorithm} keypair: ${e}`);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Exports a public `CryptoKey` as a JSON Web Key.
|
|
218
|
+
* @remarks
|
|
219
|
+
* Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
|
|
220
|
+
* does not enforce public-vs-private; without this guard a caller that
|
|
221
|
+
* passed an extractable private key would receive its private fields
|
|
222
|
+
* (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
|
|
223
|
+
* @param publicKey - Extractable public key to export.
|
|
224
|
+
* @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
|
|
225
|
+
*/
|
|
226
|
+
async exportPublicKeyJwk(publicKey) {
|
|
227
|
+
if (publicKey.type !== 'public') {
|
|
228
|
+
return (0, ts_utils_1.fail)(`exportPublicKeyJwk requires a public CryptoKey, got '${publicKey.type}'`);
|
|
229
|
+
}
|
|
230
|
+
const result = await (0, ts_utils_1.captureAsyncResult)(() => crypto.webcrypto.subtle.exportKey('jwk', publicKey));
|
|
231
|
+
return result.withErrorFormat((e) => `Failed to export public key as JWK: ${e}`);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
|
|
235
|
+
* @param jwk - The JSON Web Key produced by a prior export.
|
|
236
|
+
* @param algorithm - The algorithm the key was generated for.
|
|
237
|
+
* @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
|
|
238
|
+
*/
|
|
239
|
+
async importPublicKeyJwk(jwk, algorithm) {
|
|
240
|
+
const params = keyPairAlgorithmParams_1.keyPairAlgorithmParams[algorithm];
|
|
241
|
+
const result = await (0, ts_utils_1.captureAsyncResult)(() => crypto.webcrypto.subtle.importKey('jwk', jwk, params.importPublicKey, true, params.publicKeyUsages));
|
|
242
|
+
return result.withErrorFormat((e) => `Failed to import ${algorithm} public key from JWK: ${e}`);
|
|
243
|
+
}
|
|
201
244
|
}
|
|
202
245
|
exports.NodeCryptoProvider = NodeCryptoProvider;
|
|
203
246
|
/**
|
|
@@ -132,8 +132,8 @@ export declare class ZipFileTreeAccessors<TCT extends string = string> implement
|
|
|
132
132
|
private constructor();
|
|
133
133
|
/**
|
|
134
134
|
* Default function to infer the content type of a file.
|
|
135
|
-
* @param
|
|
136
|
-
* @param
|
|
135
|
+
* @param __filePath - The path of the file.
|
|
136
|
+
* @param __provided - Optional supplied content type.
|
|
137
137
|
* @returns `Success` with the content type of the file if successful, or
|
|
138
138
|
* `Failure` with an error message otherwise.
|
|
139
139
|
* @remarks This default implementation always returns `Success` with `undefined`.
|
|
@@ -149,8 +149,8 @@ class ZipFileTreeAccessors {
|
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
151
151
|
* Default function to infer the content type of a file.
|
|
152
|
-
* @param
|
|
153
|
-
* @param
|
|
152
|
+
* @param __filePath - The path of the file.
|
|
153
|
+
* @param __provided - Optional supplied content type.
|
|
154
154
|
* @returns `Success` with the content type of the file if successful, or
|
|
155
155
|
* `Failure` with an error message otherwise.
|
|
156
156
|
* @remarks This default implementation always returns `Success` with `undefined`.
|