@fgv/ts-extras 5.0.2 → 5.1.0-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/index.browser.js +6 -2
- package/dist/index.js +5 -1
- package/dist/packlets/ai-assist/apiClient.js +484 -0
- package/dist/packlets/ai-assist/converters.js +121 -0
- package/dist/packlets/ai-assist/index.js +10 -0
- package/dist/packlets/ai-assist/model.js +90 -0
- package/dist/packlets/ai-assist/registry.js +145 -0
- package/dist/packlets/ai-assist/toolFormats.js +160 -0
- package/dist/packlets/crypto-utils/constants.js +48 -0
- package/dist/packlets/crypto-utils/converters.js +155 -0
- package/dist/packlets/crypto-utils/directEncryptionProvider.js +86 -0
- package/dist/packlets/crypto-utils/encryptedFile.js +161 -0
- package/dist/packlets/crypto-utils/index.browser.js +41 -0
- package/dist/packlets/crypto-utils/index.js +41 -0
- package/dist/packlets/crypto-utils/keystore/converters.js +84 -0
- package/dist/packlets/crypto-utils/keystore/index.js +31 -0
- package/dist/packlets/crypto-utils/keystore/keyStore.js +758 -0
- package/dist/packlets/crypto-utils/keystore/model.js +64 -0
- package/dist/packlets/crypto-utils/model.js +39 -0
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js +159 -0
- package/dist/packlets/experimental/formatter.js +1 -1
- package/dist/packlets/mustache/index.js +23 -0
- package/dist/packlets/mustache/interfaces.js +25 -0
- package/dist/packlets/mustache/mustacheTemplate.js +242 -0
- package/dist/packlets/record-jar/recordJarHelpers.js +1 -1
- package/dist/packlets/yaml/converters.js +46 -0
- package/dist/packlets/yaml/index.js +23 -0
- package/dist/packlets/zip-file-tree/index.js +1 -0
- package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +43 -2
- package/dist/packlets/zip-file-tree/zipFileTreeWriter.js +40 -0
- package/dist/ts-extras.d.ts +1990 -112
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.browser.d.ts +3 -1
- package/lib/index.browser.js +6 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +9 -1
- package/lib/packlets/ai-assist/apiClient.d.ts +60 -0
- package/lib/packlets/ai-assist/apiClient.js +488 -0
- package/lib/packlets/ai-assist/converters.d.ts +55 -0
- package/lib/packlets/ai-assist/converters.js +124 -0
- package/lib/packlets/ai-assist/index.d.ts +10 -0
- package/lib/packlets/ai-assist/index.js +33 -0
- package/lib/packlets/ai-assist/model.d.ts +222 -0
- package/lib/packlets/ai-assist/model.js +95 -0
- package/lib/packlets/ai-assist/registry.d.ts +25 -0
- package/lib/packlets/ai-assist/registry.js +150 -0
- package/lib/packlets/ai-assist/toolFormats.d.ts +44 -0
- package/lib/packlets/ai-assist/toolFormats.js +166 -0
- package/lib/packlets/crypto-utils/constants.d.ts +26 -0
- package/lib/packlets/crypto-utils/constants.js +51 -0
- package/lib/packlets/crypto-utils/converters.d.ts +58 -0
- package/lib/packlets/crypto-utils/converters.js +192 -0
- package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts +69 -0
- package/lib/packlets/crypto-utils/directEncryptionProvider.js +90 -0
- package/lib/packlets/crypto-utils/encryptedFile.d.ts +88 -0
- package/lib/packlets/crypto-utils/encryptedFile.js +201 -0
- package/lib/packlets/crypto-utils/index.browser.d.ts +14 -0
- package/lib/packlets/crypto-utils/index.browser.js +91 -0
- package/lib/packlets/crypto-utils/index.d.ts +15 -0
- package/lib/packlets/crypto-utils/index.js +88 -0
- package/lib/packlets/crypto-utils/keystore/converters.d.ts +29 -0
- package/lib/packlets/crypto-utils/keystore/converters.js +87 -0
- package/lib/packlets/crypto-utils/keystore/index.d.ts +9 -0
- package/lib/packlets/crypto-utils/keystore/index.js +71 -0
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +239 -0
- package/lib/packlets/crypto-utils/keystore/keyStore.js +795 -0
- package/lib/packlets/crypto-utils/keystore/model.d.ts +245 -0
- package/lib/packlets/crypto-utils/keystore/model.js +68 -0
- package/lib/packlets/crypto-utils/model.d.ts +236 -0
- package/lib/packlets/crypto-utils/model.js +76 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +62 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js +196 -0
- package/lib/packlets/experimental/formatter.d.ts +1 -1
- package/lib/packlets/experimental/formatter.js +1 -1
- package/lib/packlets/mustache/index.d.ts +3 -0
- package/lib/packlets/mustache/index.js +27 -0
- package/lib/packlets/mustache/interfaces.d.ts +97 -0
- package/lib/packlets/mustache/interfaces.js +26 -0
- package/lib/packlets/mustache/mustacheTemplate.d.ts +76 -0
- package/lib/packlets/mustache/mustacheTemplate.js +249 -0
- package/lib/packlets/record-jar/recordJarHelpers.js +1 -1
- package/lib/packlets/yaml/converters.d.ts +9 -0
- package/lib/packlets/yaml/converters.js +82 -0
- package/lib/packlets/yaml/index.d.ts +2 -0
- package/lib/packlets/yaml/index.js +39 -0
- package/lib/packlets/zip-file-tree/index.d.ts +1 -0
- package/lib/packlets/zip-file-tree/index.js +15 -0
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +31 -2
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +42 -1
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts +27 -0
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.js +43 -0
- package/package.json +37 -18
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { EncryptionAlgorithm, ICryptoProvider, IKeyDerivationParams } from '../model';
|
|
2
|
+
/**
|
|
3
|
+
* Format version for key store files.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export type KeyStoreFormat = 'keystore-v1';
|
|
7
|
+
/**
|
|
8
|
+
* Current format version constant.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare const KEYSTORE_FORMAT: KeyStoreFormat;
|
|
12
|
+
/**
|
|
13
|
+
* Default PBKDF2 iterations for key store encryption.
|
|
14
|
+
* Higher than regular files since this protects the master key vault.
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_KEYSTORE_ITERATIONS: number;
|
|
18
|
+
/**
|
|
19
|
+
* Minimum salt length for key derivation.
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export declare const MIN_SALT_LENGTH: number;
|
|
23
|
+
/**
|
|
24
|
+
* Discriminator for secret types stored in the vault.
|
|
25
|
+
* - `'encryption-key'`: A 32-byte AES-256 encryption key.
|
|
26
|
+
* - `'api-key'`: An arbitrary-length API key string (UTF-8 encoded).
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export type KeyStoreSecretType = 'encryption-key' | 'api-key';
|
|
30
|
+
/**
|
|
31
|
+
* All valid key store secret types.
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export declare const allKeyStoreSecretTypes: ReadonlyArray<KeyStoreSecretType>;
|
|
35
|
+
/**
|
|
36
|
+
* A secret entry stored in the vault (in-memory representation).
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export interface IKeyStoreSecretEntry {
|
|
40
|
+
/**
|
|
41
|
+
* Unique name for this secret (used as lookup key).
|
|
42
|
+
*/
|
|
43
|
+
readonly name: string;
|
|
44
|
+
/**
|
|
45
|
+
* Secret type discriminator.
|
|
46
|
+
* Defaults to `'encryption-key'` for backwards compatibility.
|
|
47
|
+
*/
|
|
48
|
+
readonly type: KeyStoreSecretType;
|
|
49
|
+
/**
|
|
50
|
+
* The secret data.
|
|
51
|
+
* - For `'encryption-key'`: 32-byte AES-256 key.
|
|
52
|
+
* - For `'api-key'`: UTF-8 encoded API key string (arbitrary length).
|
|
53
|
+
*/
|
|
54
|
+
readonly key: Uint8Array;
|
|
55
|
+
/**
|
|
56
|
+
* Optional description for this secret.
|
|
57
|
+
*/
|
|
58
|
+
readonly description?: string;
|
|
59
|
+
/**
|
|
60
|
+
* When this secret was added (ISO 8601).
|
|
61
|
+
*/
|
|
62
|
+
readonly createdAt: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* JSON-serializable version of secret entry (for storage).
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export interface IKeyStoreSecretEntryJson {
|
|
69
|
+
/**
|
|
70
|
+
* Unique name for this secret.
|
|
71
|
+
*/
|
|
72
|
+
readonly name: string;
|
|
73
|
+
/**
|
|
74
|
+
* Secret type discriminator.
|
|
75
|
+
* Optional for backwards compatibility — missing means `'encryption-key'`.
|
|
76
|
+
*/
|
|
77
|
+
readonly type?: KeyStoreSecretType;
|
|
78
|
+
/**
|
|
79
|
+
* Base64-encoded secret data.
|
|
80
|
+
*/
|
|
81
|
+
readonly key: string;
|
|
82
|
+
/**
|
|
83
|
+
* Optional description.
|
|
84
|
+
*/
|
|
85
|
+
readonly description?: string;
|
|
86
|
+
/**
|
|
87
|
+
* When this secret was added (ISO 8601).
|
|
88
|
+
*/
|
|
89
|
+
readonly createdAt: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The decrypted vault contents - a versioned map of secrets.
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
export interface IKeyStoreVaultContents {
|
|
96
|
+
/**
|
|
97
|
+
* Format version for vault contents.
|
|
98
|
+
*/
|
|
99
|
+
readonly version: KeyStoreFormat;
|
|
100
|
+
/**
|
|
101
|
+
* Map of secret name to secret entry.
|
|
102
|
+
*/
|
|
103
|
+
readonly secrets: Record<string, IKeyStoreSecretEntryJson>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The encrypted key store file format.
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
export interface IKeyStoreFile {
|
|
110
|
+
/**
|
|
111
|
+
* Format identifier.
|
|
112
|
+
*/
|
|
113
|
+
readonly format: KeyStoreFormat;
|
|
114
|
+
/**
|
|
115
|
+
* Algorithm used for encryption.
|
|
116
|
+
*/
|
|
117
|
+
readonly algorithm: EncryptionAlgorithm;
|
|
118
|
+
/**
|
|
119
|
+
* Base64-encoded initialization vector.
|
|
120
|
+
*/
|
|
121
|
+
readonly iv: string;
|
|
122
|
+
/**
|
|
123
|
+
* Base64-encoded authentication tag.
|
|
124
|
+
*/
|
|
125
|
+
readonly authTag: string;
|
|
126
|
+
/**
|
|
127
|
+
* Base64-encoded encrypted vault contents.
|
|
128
|
+
*/
|
|
129
|
+
readonly encryptedData: string;
|
|
130
|
+
/**
|
|
131
|
+
* Key derivation parameters (required for key store - always password-derived).
|
|
132
|
+
*/
|
|
133
|
+
readonly keyDerivation: IKeyDerivationParams;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Key store lock state.
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
export type KeyStoreLockState = 'locked' | 'unlocked';
|
|
140
|
+
/**
|
|
141
|
+
* Parameters for creating a new key store.
|
|
142
|
+
* @public
|
|
143
|
+
*/
|
|
144
|
+
export interface IKeyStoreCreateParams {
|
|
145
|
+
/**
|
|
146
|
+
* Crypto provider to use.
|
|
147
|
+
*/
|
|
148
|
+
readonly cryptoProvider: ICryptoProvider;
|
|
149
|
+
/**
|
|
150
|
+
* PBKDF2 iterations (defaults to DEFAULT_KEYSTORE_ITERATIONS).
|
|
151
|
+
*/
|
|
152
|
+
readonly iterations?: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Parameters for opening an existing key store.
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
158
|
+
export interface IKeyStoreOpenParams {
|
|
159
|
+
/**
|
|
160
|
+
* Crypto provider to use.
|
|
161
|
+
*/
|
|
162
|
+
readonly cryptoProvider: ICryptoProvider;
|
|
163
|
+
/**
|
|
164
|
+
* The encrypted key store file content.
|
|
165
|
+
*/
|
|
166
|
+
readonly keystoreFile: IKeyStoreFile;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Result of adding a secret to the key store.
|
|
170
|
+
* @public
|
|
171
|
+
*/
|
|
172
|
+
export interface IAddSecretResult {
|
|
173
|
+
/**
|
|
174
|
+
* The secret entry that was added.
|
|
175
|
+
*/
|
|
176
|
+
readonly entry: IKeyStoreSecretEntry;
|
|
177
|
+
/**
|
|
178
|
+
* Whether this replaced an existing secret.
|
|
179
|
+
*/
|
|
180
|
+
readonly replaced: boolean;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Options for adding a secret.
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
186
|
+
export interface IAddSecretOptions {
|
|
187
|
+
/**
|
|
188
|
+
* Optional description for the secret.
|
|
189
|
+
*/
|
|
190
|
+
readonly description?: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Options for importing a secret.
|
|
194
|
+
* @public
|
|
195
|
+
*/
|
|
196
|
+
export interface IImportSecretOptions extends IAddSecretOptions {
|
|
197
|
+
/**
|
|
198
|
+
* Whether to replace an existing secret with the same name.
|
|
199
|
+
*/
|
|
200
|
+
readonly replace?: boolean;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Options for adding a secret derived from a password.
|
|
204
|
+
* @public
|
|
205
|
+
*/
|
|
206
|
+
export interface IAddSecretFromPasswordOptions extends IAddSecretOptions {
|
|
207
|
+
/**
|
|
208
|
+
* Whether to replace an existing secret with the same name.
|
|
209
|
+
*/
|
|
210
|
+
readonly replace?: boolean;
|
|
211
|
+
/**
|
|
212
|
+
* PBKDF2 iterations for key derivation.
|
|
213
|
+
* @defaultValue DEFAULT_SECRET_ITERATIONS (350000)
|
|
214
|
+
*/
|
|
215
|
+
readonly iterations?: number;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Default PBKDF2 iterations for secret-level key derivation.
|
|
219
|
+
* Lower than keystore encryption since these are used more frequently.
|
|
220
|
+
* @public
|
|
221
|
+
*/
|
|
222
|
+
export declare const DEFAULT_SECRET_ITERATIONS: number;
|
|
223
|
+
/**
|
|
224
|
+
* Result of adding a password-derived secret.
|
|
225
|
+
* Extends {@link IAddSecretResult} with key derivation parameters
|
|
226
|
+
* needed to store alongside encrypted files.
|
|
227
|
+
* @public
|
|
228
|
+
*/
|
|
229
|
+
export interface IAddSecretFromPasswordResult extends IAddSecretResult {
|
|
230
|
+
/**
|
|
231
|
+
* Key derivation parameters used to derive the secret key.
|
|
232
|
+
* Store these in encrypted file metadata so the password alone
|
|
233
|
+
* can re-derive the same key for decryption.
|
|
234
|
+
*/
|
|
235
|
+
readonly keyDerivation: IKeyDerivationParams;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Checks if a JSON object appears to be a key store file.
|
|
239
|
+
* Uses the format field as a discriminator.
|
|
240
|
+
* @param json - JSON object to check
|
|
241
|
+
* @returns true if the object has the key store format field
|
|
242
|
+
* @public
|
|
243
|
+
*/
|
|
244
|
+
export declare function isKeyStoreFile(json: unknown): boolean;
|
|
245
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
exports.DEFAULT_SECRET_ITERATIONS = exports.allKeyStoreSecretTypes = exports.MIN_SALT_LENGTH = exports.DEFAULT_KEYSTORE_ITERATIONS = exports.KEYSTORE_FORMAT = void 0;
|
|
23
|
+
exports.isKeyStoreFile = isKeyStoreFile;
|
|
24
|
+
/**
|
|
25
|
+
* Current format version constant.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
exports.KEYSTORE_FORMAT = 'keystore-v1';
|
|
29
|
+
/**
|
|
30
|
+
* Default PBKDF2 iterations for key store encryption.
|
|
31
|
+
* Higher than regular files since this protects the master key vault.
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
exports.DEFAULT_KEYSTORE_ITERATIONS = 600000;
|
|
35
|
+
/**
|
|
36
|
+
* Minimum salt length for key derivation.
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
exports.MIN_SALT_LENGTH = 16;
|
|
40
|
+
/**
|
|
41
|
+
* All valid key store secret types.
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
exports.allKeyStoreSecretTypes = ['encryption-key', 'api-key'];
|
|
45
|
+
/**
|
|
46
|
+
* Default PBKDF2 iterations for secret-level key derivation.
|
|
47
|
+
* Lower than keystore encryption since these are used more frequently.
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
exports.DEFAULT_SECRET_ITERATIONS = 350000;
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Detection Helper
|
|
53
|
+
// ============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Checks if a JSON object appears to be a key store file.
|
|
56
|
+
* Uses the format field as a discriminator.
|
|
57
|
+
* @param json - JSON object to check
|
|
58
|
+
* @returns true if the object has the key store format field
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
function isKeyStoreFile(json) {
|
|
62
|
+
if (typeof json !== 'object' || json === null) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const obj = json;
|
|
66
|
+
return obj.format === exports.KEYSTORE_FORMAT;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { JsonValue } from '@fgv/ts-json-base';
|
|
2
|
+
import { Result } from '@fgv/ts-utils';
|
|
3
|
+
import * as Constants from './constants';
|
|
4
|
+
export { Constants };
|
|
5
|
+
/**
|
|
6
|
+
* Supported encryption algorithms.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export type EncryptionAlgorithm = typeof Constants.DEFAULT_ALGORITHM;
|
|
10
|
+
/**
|
|
11
|
+
* Format version for encrypted files.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export type EncryptedFileFormat = typeof Constants.ENCRYPTED_FILE_FORMAT;
|
|
15
|
+
/**
|
|
16
|
+
* Named secret for encryption/decryption.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export interface INamedSecret {
|
|
20
|
+
/**
|
|
21
|
+
* Unique name for this secret (referenced in encrypted files).
|
|
22
|
+
*/
|
|
23
|
+
readonly name: string;
|
|
24
|
+
/**
|
|
25
|
+
* The actual secret key (32 bytes for AES-256).
|
|
26
|
+
*/
|
|
27
|
+
readonly key: Uint8Array;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of an encryption operation.
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export interface IEncryptionResult {
|
|
34
|
+
/**
|
|
35
|
+
* Initialization vector used for encryption (12 bytes for GCM).
|
|
36
|
+
*/
|
|
37
|
+
readonly iv: Uint8Array;
|
|
38
|
+
/**
|
|
39
|
+
* Authentication tag from GCM mode (16 bytes).
|
|
40
|
+
*/
|
|
41
|
+
readonly authTag: Uint8Array;
|
|
42
|
+
/**
|
|
43
|
+
* The encrypted data.
|
|
44
|
+
*/
|
|
45
|
+
readonly encryptedData: Uint8Array;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Supported key derivation functions.
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export type KeyDerivationFunction = 'pbkdf2';
|
|
52
|
+
/**
|
|
53
|
+
* Key derivation parameters stored in encrypted files.
|
|
54
|
+
* Allows decryption with password without needing to know the original salt/iterations.
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export interface IKeyDerivationParams {
|
|
58
|
+
/**
|
|
59
|
+
* Key derivation function used.
|
|
60
|
+
*/
|
|
61
|
+
readonly kdf: KeyDerivationFunction;
|
|
62
|
+
/**
|
|
63
|
+
* Base64-encoded salt used for key derivation.
|
|
64
|
+
*/
|
|
65
|
+
readonly salt: string;
|
|
66
|
+
/**
|
|
67
|
+
* Number of iterations used for key derivation.
|
|
68
|
+
*/
|
|
69
|
+
readonly iterations: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generic encrypted file format.
|
|
73
|
+
* This is the JSON structure stored in encrypted files.
|
|
74
|
+
* @typeParam TMetadata - Type of optional unencrypted metadata
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
export interface IEncryptedFile<TMetadata = JsonValue> {
|
|
78
|
+
/**
|
|
79
|
+
* Format identifier for versioning.
|
|
80
|
+
*/
|
|
81
|
+
readonly format: EncryptedFileFormat;
|
|
82
|
+
/**
|
|
83
|
+
* Name of the secret required to decrypt (references INamedSecret.name).
|
|
84
|
+
*/
|
|
85
|
+
readonly secretName: string;
|
|
86
|
+
/**
|
|
87
|
+
* Algorithm used for encryption.
|
|
88
|
+
*/
|
|
89
|
+
readonly algorithm: EncryptionAlgorithm;
|
|
90
|
+
/**
|
|
91
|
+
* Base64-encoded initialization vector.
|
|
92
|
+
*/
|
|
93
|
+
readonly iv: string;
|
|
94
|
+
/**
|
|
95
|
+
* Base64-encoded authentication tag (for GCM mode).
|
|
96
|
+
*/
|
|
97
|
+
readonly authTag: string;
|
|
98
|
+
/**
|
|
99
|
+
* Base64-encoded encrypted data (JSON string when decrypted).
|
|
100
|
+
*/
|
|
101
|
+
readonly encryptedData: string;
|
|
102
|
+
/**
|
|
103
|
+
* Optional unencrypted metadata for display/filtering.
|
|
104
|
+
*/
|
|
105
|
+
readonly metadata?: TMetadata;
|
|
106
|
+
/**
|
|
107
|
+
* Optional key derivation parameters.
|
|
108
|
+
* If present, allows decryption using a password with these parameters.
|
|
109
|
+
* If absent, a pre-derived key must be provided.
|
|
110
|
+
*/
|
|
111
|
+
readonly keyDerivation?: IKeyDerivationParams;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Crypto provider interface for cross-platform encryption.
|
|
115
|
+
* Implementations provided for Node.js (crypto module) and browser (Web Crypto API).
|
|
116
|
+
* @public
|
|
117
|
+
*/
|
|
118
|
+
export interface ICryptoProvider {
|
|
119
|
+
/**
|
|
120
|
+
* Encrypts plaintext using AES-256-GCM.
|
|
121
|
+
* @param plaintext - UTF-8 string to encrypt
|
|
122
|
+
* @param key - 32-byte encryption key
|
|
123
|
+
* @returns Success with encryption result, or Failure with error
|
|
124
|
+
*/
|
|
125
|
+
encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;
|
|
126
|
+
/**
|
|
127
|
+
* Decrypts ciphertext using AES-256-GCM.
|
|
128
|
+
* @param encryptedData - Encrypted bytes
|
|
129
|
+
* @param key - 32-byte decryption key
|
|
130
|
+
* @param iv - Initialization vector (12 bytes)
|
|
131
|
+
* @param authTag - GCM authentication tag (16 bytes)
|
|
132
|
+
* @returns Success with decrypted UTF-8 string, or Failure with error
|
|
133
|
+
*/
|
|
134
|
+
decrypt(encryptedData: Uint8Array, key: Uint8Array, iv: Uint8Array, authTag: Uint8Array): Promise<Result<string>>;
|
|
135
|
+
/**
|
|
136
|
+
* Generates a random 32-byte key suitable for AES-256.
|
|
137
|
+
* @returns Success with generated key, or Failure with error
|
|
138
|
+
*/
|
|
139
|
+
generateKey(): Promise<Result<Uint8Array>>;
|
|
140
|
+
/**
|
|
141
|
+
* Derives a key from a password using PBKDF2.
|
|
142
|
+
* @param password - Password string
|
|
143
|
+
* @param salt - Salt bytes (should be at least 16 bytes)
|
|
144
|
+
* @param iterations - Number of iterations (recommend 100000+)
|
|
145
|
+
* @returns Success with derived 32-byte key, or Failure with error
|
|
146
|
+
*/
|
|
147
|
+
deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
|
|
148
|
+
/**
|
|
149
|
+
* Generates cryptographically secure random bytes.
|
|
150
|
+
* @param length - Number of bytes to generate
|
|
151
|
+
* @returns Success with random bytes, or Failure with error
|
|
152
|
+
*/
|
|
153
|
+
generateRandomBytes(length: number): Result<Uint8Array>;
|
|
154
|
+
/**
|
|
155
|
+
* Encodes binary data to base64 string.
|
|
156
|
+
* @param data - Binary data to encode
|
|
157
|
+
* @returns Base64-encoded string
|
|
158
|
+
*/
|
|
159
|
+
toBase64(data: Uint8Array): string;
|
|
160
|
+
/**
|
|
161
|
+
* Decodes base64 string to binary data.
|
|
162
|
+
* @param base64 - Base64-encoded string
|
|
163
|
+
* @returns Success with decoded bytes, or Failure if invalid base64
|
|
164
|
+
*/
|
|
165
|
+
fromBase64(base64: string): Result<Uint8Array>;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* High-level interface for encrypting JSON content by secret name.
|
|
169
|
+
*
|
|
170
|
+
* This abstraction unifies two common encryption workflows:
|
|
171
|
+
* - **KeyStore**: looks up the named secret and crypto provider from the vault
|
|
172
|
+
* - **DirectEncryptionProvider**: uses a pre-supplied key and crypto provider,
|
|
173
|
+
* optionally bound to a specific secret name for safety
|
|
174
|
+
*
|
|
175
|
+
* Callers that need to encrypt (e.g. `EditableCollection.save()`) depend on
|
|
176
|
+
* this interface rather than on `KeyStore` directly, allowing mix-and-match.
|
|
177
|
+
*
|
|
178
|
+
* @public
|
|
179
|
+
*/
|
|
180
|
+
export interface IEncryptionProvider {
|
|
181
|
+
/**
|
|
182
|
+
* Encrypts JSON content under a named secret.
|
|
183
|
+
*
|
|
184
|
+
* @param secretName - Name of the secret to encrypt with
|
|
185
|
+
* @param content - JSON-safe content to encrypt
|
|
186
|
+
* @param metadata - Optional unencrypted metadata to include in the encrypted file
|
|
187
|
+
* @returns Success with encrypted file structure, or Failure with error context
|
|
188
|
+
*/
|
|
189
|
+
encryptByName<TMetadata = JsonValue>(secretName: string, content: JsonValue, metadata?: TMetadata): Promise<Result<IEncryptedFile<TMetadata>>>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Behavior when an encrypted file cannot be decrypted.
|
|
193
|
+
* @public
|
|
194
|
+
*/
|
|
195
|
+
export type EncryptedFileErrorMode = 'fail' | 'skip' | 'warn';
|
|
196
|
+
/**
|
|
197
|
+
* Function type for dynamic secret retrieval.
|
|
198
|
+
* @public
|
|
199
|
+
*/
|
|
200
|
+
export type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;
|
|
201
|
+
/**
|
|
202
|
+
* Configuration for encrypted file handling during loading.
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
export interface IEncryptionConfig {
|
|
206
|
+
/**
|
|
207
|
+
* Named secrets available for decryption.
|
|
208
|
+
*/
|
|
209
|
+
readonly secrets?: ReadonlyArray<INamedSecret>;
|
|
210
|
+
/**
|
|
211
|
+
* Alternative: dynamic secret provider function.
|
|
212
|
+
* Called when a secret is not found in the secrets array.
|
|
213
|
+
*/
|
|
214
|
+
readonly secretProvider?: SecretProvider;
|
|
215
|
+
/**
|
|
216
|
+
* Crypto provider implementation (Node.js or browser).
|
|
217
|
+
*/
|
|
218
|
+
readonly cryptoProvider: ICryptoProvider;
|
|
219
|
+
/**
|
|
220
|
+
* Behavior when decryption key is missing (default: 'fail').
|
|
221
|
+
*/
|
|
222
|
+
readonly onMissingKey?: EncryptedFileErrorMode;
|
|
223
|
+
/**
|
|
224
|
+
* Behavior when decryption fails (default: 'fail').
|
|
225
|
+
*/
|
|
226
|
+
readonly onDecryptionError?: EncryptedFileErrorMode;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Checks if a JSON object appears to be an encrypted file.
|
|
230
|
+
* Uses the format field as a discriminator.
|
|
231
|
+
* @param json - JSON object to check
|
|
232
|
+
* @returns true if the object has the encrypted file format field
|
|
233
|
+
* @public
|
|
234
|
+
*/
|
|
235
|
+
export declare function isEncryptedFile(json: unknown): boolean;
|
|
236
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2024 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
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.Constants = void 0;
|
|
56
|
+
exports.isEncryptedFile = isEncryptedFile;
|
|
57
|
+
const Constants = __importStar(require("./constants"));
|
|
58
|
+
exports.Constants = Constants;
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Detection Helper
|
|
61
|
+
// ============================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Checks if a JSON object appears to be an encrypted file.
|
|
64
|
+
* Uses the format field as a discriminator.
|
|
65
|
+
* @param json - JSON object to check
|
|
66
|
+
* @returns true if the object has the encrypted file format field
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
function isEncryptedFile(json) {
|
|
70
|
+
if (typeof json !== 'object' || json === null) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const obj = json;
|
|
74
|
+
return obj.format === Constants.ENCRYPTED_FILE_FORMAT;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Result } from '@fgv/ts-utils';
|
|
2
|
+
import { ICryptoProvider, IEncryptionResult } from './model';
|
|
3
|
+
/**
|
|
4
|
+
* Node.js implementation of {@link CryptoUtils.ICryptoProvider} using the built-in crypto module.
|
|
5
|
+
* Uses AES-256-GCM for authenticated encryption.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare class NodeCryptoProvider implements ICryptoProvider {
|
|
9
|
+
/**
|
|
10
|
+
* Encrypts plaintext using AES-256-GCM.
|
|
11
|
+
* @param plaintext - UTF-8 string to encrypt
|
|
12
|
+
* @param key - 32-byte encryption key
|
|
13
|
+
* @returns `Success` with encryption result, or `Failure` with an error.
|
|
14
|
+
*/
|
|
15
|
+
encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;
|
|
16
|
+
/**
|
|
17
|
+
* Decrypts ciphertext using AES-256-GCM.
|
|
18
|
+
* @param encryptedData - Encrypted bytes
|
|
19
|
+
* @param key - 32-byte decryption key
|
|
20
|
+
* @param iv - Initialization vector (12 bytes)
|
|
21
|
+
* @param authTag - GCM authentication tag (16 bytes)
|
|
22
|
+
* @returns `Success` with decrypted UTF-8 string, or `Failure` with an error.
|
|
23
|
+
*/
|
|
24
|
+
decrypt(encryptedData: Uint8Array, key: Uint8Array, iv: Uint8Array, authTag: Uint8Array): Promise<Result<string>>;
|
|
25
|
+
/**
|
|
26
|
+
* Generates a random 32-byte key suitable for AES-256.
|
|
27
|
+
* @returns `Success` with generated key, or `Failure` with an error.
|
|
28
|
+
*/
|
|
29
|
+
generateKey(): Promise<Result<Uint8Array>>;
|
|
30
|
+
/**
|
|
31
|
+
* Derives a key from a password using PBKDF2.
|
|
32
|
+
* @param password - Password string
|
|
33
|
+
* @param salt - Salt bytes (should be at least 16 bytes)
|
|
34
|
+
* @param iterations - Number of iterations (recommend 100000+)
|
|
35
|
+
* @returns `Success` with derived 32-byte key, or `Failure` with an error.
|
|
36
|
+
*/
|
|
37
|
+
deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
|
|
38
|
+
/**
|
|
39
|
+
* Generates cryptographically secure random bytes.
|
|
40
|
+
* @param length - Number of bytes to generate
|
|
41
|
+
* @returns Success with random bytes, or Failure with error
|
|
42
|
+
*/
|
|
43
|
+
generateRandomBytes(length: number): Result<Uint8Array>;
|
|
44
|
+
/**
|
|
45
|
+
* Encodes binary data to base64 string.
|
|
46
|
+
* @param data - Binary data to encode
|
|
47
|
+
* @returns Base64-encoded string
|
|
48
|
+
*/
|
|
49
|
+
toBase64(data: Uint8Array): string;
|
|
50
|
+
/**
|
|
51
|
+
* Decodes base64 string to binary data.
|
|
52
|
+
* @param base64 - Base64-encoded string
|
|
53
|
+
* @returns Success with decoded bytes, or Failure if invalid base64
|
|
54
|
+
*/
|
|
55
|
+
fromBase64(base64: string): Result<Uint8Array>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Singleton instance of {@link CryptoUtils.NodeCryptoProvider}.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare const nodeCryptoProvider: NodeCryptoProvider;
|
|
62
|
+
//# sourceMappingURL=nodeCryptoProvider.d.ts.map
|