@marktoflow/core 2.0.0-alpha.3
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/bundle.d.ts +43 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +202 -0
- package/dist/bundle.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -0
- package/dist/costs.d.ts +182 -0
- package/dist/costs.d.ts.map +1 -0
- package/dist/costs.js +464 -0
- package/dist/costs.js.map +1 -0
- package/dist/credentials.d.ts +162 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +646 -0
- package/dist/credentials.js.map +1 -0
- package/dist/engine.d.ts +137 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +514 -0
- package/dist/engine.js.map +1 -0
- package/dist/env.d.ts +59 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +256 -0
- package/dist/env.js.map +1 -0
- package/dist/failover.d.ts +43 -0
- package/dist/failover.d.ts.map +1 -0
- package/dist/failover.js +53 -0
- package/dist/failover.js.map +1 -0
- package/dist/filewatcher.d.ts +32 -0
- package/dist/filewatcher.d.ts.map +1 -0
- package/dist/filewatcher.js +92 -0
- package/dist/filewatcher.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +62 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +211 -0
- package/dist/logging.js.map +1 -0
- package/dist/mcp-loader.d.ts +29 -0
- package/dist/mcp-loader.d.ts.map +1 -0
- package/dist/mcp-loader.js +60 -0
- package/dist/mcp-loader.js.map +1 -0
- package/dist/metrics.d.ts +19 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +65 -0
- package/dist/metrics.js.map +1 -0
- package/dist/models.d.ts +419 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +111 -0
- package/dist/models.js.map +1 -0
- package/dist/parser.d.ts +40 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +287 -0
- package/dist/parser.js.map +1 -0
- package/dist/plugins.d.ts +105 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +182 -0
- package/dist/plugins.js.map +1 -0
- package/dist/queue.d.ts +114 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +385 -0
- package/dist/queue.js.map +1 -0
- package/dist/rollback.d.ts +117 -0
- package/dist/rollback.d.ts.map +1 -0
- package/dist/rollback.js +374 -0
- package/dist/rollback.js.map +1 -0
- package/dist/routing.d.ts +144 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +457 -0
- package/dist/routing.js.map +1 -0
- package/dist/scheduler.d.ts +91 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +259 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/script-tool.d.ts +22 -0
- package/dist/script-tool.d.ts.map +1 -0
- package/dist/script-tool.js +90 -0
- package/dist/script-tool.js.map +1 -0
- package/dist/sdk-registry.d.ts +81 -0
- package/dist/sdk-registry.d.ts.map +1 -0
- package/dist/sdk-registry.js +264 -0
- package/dist/sdk-registry.js.map +1 -0
- package/dist/security.d.ts +155 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +362 -0
- package/dist/security.js.map +1 -0
- package/dist/state.d.ts +67 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +276 -0
- package/dist/state.js.map +1 -0
- package/dist/templates.d.ts +70 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +244 -0
- package/dist/templates.js.map +1 -0
- package/dist/tool-base.d.ts +54 -0
- package/dist/tool-base.d.ts.map +1 -0
- package/dist/tool-base.js +43 -0
- package/dist/tool-base.js.map +1 -0
- package/dist/tool-registry.d.ts +24 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +164 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/custom-tool.d.ts +16 -0
- package/dist/tools/custom-tool.d.ts.map +1 -0
- package/dist/tools/custom-tool.js +85 -0
- package/dist/tools/custom-tool.js.map +1 -0
- package/dist/tools/mcp-tool.d.ts +16 -0
- package/dist/tools/mcp-tool.d.ts.map +1 -0
- package/dist/tools/mcp-tool.js +98 -0
- package/dist/tools/mcp-tool.js.map +1 -0
- package/dist/tools/openapi-tool.d.ts +17 -0
- package/dist/tools/openapi-tool.d.ts.map +1 -0
- package/dist/tools/openapi-tool.js +165 -0
- package/dist/tools/openapi-tool.js.map +1 -0
- package/dist/trigger-manager.d.ts +26 -0
- package/dist/trigger-manager.d.ts.map +1 -0
- package/dist/trigger-manager.js +107 -0
- package/dist/trigger-manager.js.map +1 -0
- package/dist/webhook.d.ts +95 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +261 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential encryption and management.
|
|
3
|
+
*
|
|
4
|
+
* Provides secure credential storage with encryption support for:
|
|
5
|
+
* - Age encryption (external binary)
|
|
6
|
+
* - GPG encryption (external binary)
|
|
7
|
+
* - Fernet encryption (built-in via Node crypto)
|
|
8
|
+
*/
|
|
9
|
+
import { randomBytes, createCipheriv, createDecipheriv, createHmac } from 'node:crypto';
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, unlinkSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
export var EncryptionBackend;
|
|
15
|
+
(function (EncryptionBackend) {
|
|
16
|
+
EncryptionBackend["AGE"] = "age";
|
|
17
|
+
EncryptionBackend["GPG"] = "gpg";
|
|
18
|
+
EncryptionBackend["FERNET"] = "fernet";
|
|
19
|
+
})(EncryptionBackend || (EncryptionBackend = {}));
|
|
20
|
+
export var CredentialType;
|
|
21
|
+
(function (CredentialType) {
|
|
22
|
+
CredentialType["API_KEY"] = "api_key";
|
|
23
|
+
CredentialType["TOKEN"] = "token";
|
|
24
|
+
CredentialType["PASSWORD"] = "password";
|
|
25
|
+
CredentialType["CERTIFICATE"] = "certificate";
|
|
26
|
+
CredentialType["SSH_KEY"] = "ssh_key";
|
|
27
|
+
CredentialType["SECRET"] = "secret";
|
|
28
|
+
CredentialType["OAUTH_TOKEN"] = "oauth_token";
|
|
29
|
+
CredentialType["CUSTOM"] = "custom";
|
|
30
|
+
})(CredentialType || (CredentialType = {}));
|
|
31
|
+
export class EncryptionError extends Error {
|
|
32
|
+
}
|
|
33
|
+
export class KeyNotFoundError extends Error {
|
|
34
|
+
}
|
|
35
|
+
export class CredentialNotFoundError extends Error {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Fernet-compatible encryption using Node's built-in crypto.
|
|
39
|
+
*
|
|
40
|
+
* Fernet format:
|
|
41
|
+
* - Version (1 byte): 0x80
|
|
42
|
+
* - Timestamp (8 bytes): big-endian seconds since epoch
|
|
43
|
+
* - IV (16 bytes): random initialization vector
|
|
44
|
+
* - Ciphertext: AES-128-CBC encrypted, PKCS7 padded
|
|
45
|
+
* - HMAC (32 bytes): SHA256 HMAC of version || timestamp || iv || ciphertext
|
|
46
|
+
*
|
|
47
|
+
* Key format: URL-safe base64 encoded 32 bytes (16 bytes signing key + 16 bytes encryption key)
|
|
48
|
+
*/
|
|
49
|
+
export class FernetEncryptor {
|
|
50
|
+
signingKey = null;
|
|
51
|
+
encryptionKey = null;
|
|
52
|
+
constructor(key, keyFile) {
|
|
53
|
+
if (key) {
|
|
54
|
+
this.setKey(key);
|
|
55
|
+
}
|
|
56
|
+
else if (keyFile && existsSync(keyFile)) {
|
|
57
|
+
this.setKey(readFileSync(keyFile, 'utf8').trim());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
decodeKey(key) {
|
|
61
|
+
// Handle URL-safe base64
|
|
62
|
+
const base64 = key.replace(/-/g, '+').replace(/_/g, '/');
|
|
63
|
+
const keyBuffer = Buffer.from(base64, 'base64');
|
|
64
|
+
if (keyBuffer.length !== 32) {
|
|
65
|
+
throw new KeyNotFoundError(`Invalid Fernet key length: expected 32 bytes, got ${keyBuffer.length}`);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
signingKey: keyBuffer.subarray(0, 16),
|
|
69
|
+
encryptionKey: keyBuffer.subarray(16, 32),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
setKey(key) {
|
|
73
|
+
const { signingKey, encryptionKey } = this.decodeKey(key);
|
|
74
|
+
this.signingKey = signingKey;
|
|
75
|
+
this.encryptionKey = encryptionKey;
|
|
76
|
+
}
|
|
77
|
+
encrypt(plaintext) {
|
|
78
|
+
if (!this.signingKey || !this.encryptionKey) {
|
|
79
|
+
throw new KeyNotFoundError('No Fernet key configured');
|
|
80
|
+
}
|
|
81
|
+
const version = Buffer.from([0x80]);
|
|
82
|
+
const timestamp = Buffer.alloc(8);
|
|
83
|
+
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
84
|
+
timestamp.writeBigUInt64BE(now);
|
|
85
|
+
const iv = randomBytes(16);
|
|
86
|
+
// Encrypt with AES-128-CBC
|
|
87
|
+
const cipher = createCipheriv('aes-128-cbc', this.encryptionKey, iv);
|
|
88
|
+
const ciphertext = Buffer.concat([
|
|
89
|
+
cipher.update(plaintext, 'utf8'),
|
|
90
|
+
cipher.final(),
|
|
91
|
+
]);
|
|
92
|
+
// Create token without HMAC
|
|
93
|
+
const tokenWithoutHmac = Buffer.concat([version, timestamp, iv, ciphertext]);
|
|
94
|
+
// Calculate HMAC
|
|
95
|
+
const hmac = createHmac('sha256', this.signingKey)
|
|
96
|
+
.update(tokenWithoutHmac)
|
|
97
|
+
.digest();
|
|
98
|
+
// Final token
|
|
99
|
+
const token = Buffer.concat([tokenWithoutHmac, hmac]);
|
|
100
|
+
// Return URL-safe base64
|
|
101
|
+
return token.toString('base64').replace(/\+/g, '-').replace(/\//g, '_');
|
|
102
|
+
}
|
|
103
|
+
decrypt(ciphertext) {
|
|
104
|
+
if (!this.signingKey || !this.encryptionKey) {
|
|
105
|
+
throw new KeyNotFoundError('No Fernet key configured');
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
// Decode URL-safe base64
|
|
109
|
+
const base64 = ciphertext.replace(/-/g, '+').replace(/_/g, '/');
|
|
110
|
+
const token = Buffer.from(base64, 'base64');
|
|
111
|
+
if (token.length < 57) {
|
|
112
|
+
// 1 + 8 + 16 + 16 (min ciphertext) + 32 (hmac) = 73, but can be less with small plaintext
|
|
113
|
+
throw new EncryptionError('Token too short');
|
|
114
|
+
}
|
|
115
|
+
// Parse token
|
|
116
|
+
const version = token[0];
|
|
117
|
+
if (version !== 0x80) {
|
|
118
|
+
throw new EncryptionError(`Invalid Fernet version: ${version}`);
|
|
119
|
+
}
|
|
120
|
+
const hmacOffset = token.length - 32;
|
|
121
|
+
const tokenWithoutHmac = token.subarray(0, hmacOffset);
|
|
122
|
+
const providedHmac = token.subarray(hmacOffset);
|
|
123
|
+
// Verify HMAC
|
|
124
|
+
const expectedHmac = createHmac('sha256', this.signingKey)
|
|
125
|
+
.update(tokenWithoutHmac)
|
|
126
|
+
.digest();
|
|
127
|
+
if (!providedHmac.equals(expectedHmac)) {
|
|
128
|
+
throw new EncryptionError('HMAC verification failed');
|
|
129
|
+
}
|
|
130
|
+
// Extract IV and ciphertext
|
|
131
|
+
const iv = token.subarray(9, 25);
|
|
132
|
+
const encryptedData = token.subarray(25, hmacOffset);
|
|
133
|
+
// Decrypt
|
|
134
|
+
const decipher = createDecipheriv('aes-128-cbc', this.encryptionKey, iv);
|
|
135
|
+
const decrypted = Buffer.concat([
|
|
136
|
+
decipher.update(encryptedData),
|
|
137
|
+
decipher.final(),
|
|
138
|
+
]);
|
|
139
|
+
return decrypted.toString('utf8');
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (error instanceof EncryptionError || error instanceof KeyNotFoundError) {
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
throw new EncryptionError(`Decryption failed: ${String(error)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
isAvailable() {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
generateKey() {
|
|
152
|
+
// Generate 32 random bytes and encode as URL-safe base64
|
|
153
|
+
const key = randomBytes(32);
|
|
154
|
+
return key.toString('base64').replace(/\+/g, '-').replace(/\//g, '_');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export class AgeEncryptor {
|
|
158
|
+
recipient;
|
|
159
|
+
identityFile;
|
|
160
|
+
passphrase;
|
|
161
|
+
constructor(recipient, identityFile, passphrase) {
|
|
162
|
+
this.recipient = recipient;
|
|
163
|
+
this.identityFile = identityFile;
|
|
164
|
+
this.passphrase = passphrase;
|
|
165
|
+
}
|
|
166
|
+
findBinary(name) {
|
|
167
|
+
const paths = (process.env.PATH || '').split(':');
|
|
168
|
+
for (const p of paths) {
|
|
169
|
+
const full = join(p, name);
|
|
170
|
+
if (existsSync(full))
|
|
171
|
+
return full;
|
|
172
|
+
}
|
|
173
|
+
throw new EncryptionError(`${name} binary not found`);
|
|
174
|
+
}
|
|
175
|
+
encrypt(plaintext) {
|
|
176
|
+
const agePath = this.findBinary('age');
|
|
177
|
+
const args = ['--armor'];
|
|
178
|
+
if (this.passphrase) {
|
|
179
|
+
args.push('--passphrase');
|
|
180
|
+
}
|
|
181
|
+
else if (this.recipient) {
|
|
182
|
+
args.push('--recipient', this.recipient);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
throw new EncryptionError('No recipient or passphrase configured for age');
|
|
186
|
+
}
|
|
187
|
+
const env = { ...process.env };
|
|
188
|
+
if (this.passphrase)
|
|
189
|
+
env.AGE_PASSPHRASE = this.passphrase;
|
|
190
|
+
const result = spawnSync(agePath, args, { input: plaintext, env, encoding: 'utf8' });
|
|
191
|
+
if (result.status !== 0) {
|
|
192
|
+
throw new EncryptionError(`age encryption failed: ${result.stderr || ''}`.trim());
|
|
193
|
+
}
|
|
194
|
+
return result.stdout;
|
|
195
|
+
}
|
|
196
|
+
decrypt(ciphertext) {
|
|
197
|
+
const agePath = this.findBinary('age');
|
|
198
|
+
const args = ['--decrypt'];
|
|
199
|
+
if (this.identityFile) {
|
|
200
|
+
args.push('--identity', this.identityFile);
|
|
201
|
+
}
|
|
202
|
+
const env = { ...process.env };
|
|
203
|
+
if (this.passphrase)
|
|
204
|
+
env.AGE_PASSPHRASE = this.passphrase;
|
|
205
|
+
const result = spawnSync(agePath, args, { input: ciphertext, env, encoding: 'utf8' });
|
|
206
|
+
if (result.status !== 0) {
|
|
207
|
+
throw new EncryptionError(`age decryption failed: ${result.stderr || ''}`.trim());
|
|
208
|
+
}
|
|
209
|
+
return result.stdout;
|
|
210
|
+
}
|
|
211
|
+
isAvailable() {
|
|
212
|
+
try {
|
|
213
|
+
this.findBinary('age');
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
generateKey() {
|
|
221
|
+
const keygenPath = this.findBinary('age-keygen');
|
|
222
|
+
const result = spawnSync(keygenPath, [], { encoding: 'utf8' });
|
|
223
|
+
if (result.status !== 0) {
|
|
224
|
+
throw new EncryptionError(`age-keygen failed: ${result.stderr || ''}`.trim());
|
|
225
|
+
}
|
|
226
|
+
return result.stdout;
|
|
227
|
+
}
|
|
228
|
+
static extractPublicKey(identityContent) {
|
|
229
|
+
for (const line of identityContent.split('\n')) {
|
|
230
|
+
const trimmed = line.trim();
|
|
231
|
+
if (trimmed.startsWith('# public key:')) {
|
|
232
|
+
return trimmed.split(':', 2)[1]?.trim() ?? '';
|
|
233
|
+
}
|
|
234
|
+
if (trimmed.startsWith('age1') && !trimmed.startsWith('AGE-SECRET-KEY')) {
|
|
235
|
+
return trimmed;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
throw new EncryptionError('Could not extract public key from identity');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export class GPGEncryptor {
|
|
242
|
+
recipient;
|
|
243
|
+
passphrase;
|
|
244
|
+
symmetric;
|
|
245
|
+
constructor(recipient,
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
247
|
+
_keyId, passphrase, symmetric = false) {
|
|
248
|
+
this.recipient = recipient;
|
|
249
|
+
this.passphrase = passphrase;
|
|
250
|
+
this.symmetric = symmetric;
|
|
251
|
+
}
|
|
252
|
+
findBinary() {
|
|
253
|
+
const paths = (process.env.PATH || '').split(':');
|
|
254
|
+
for (const name of ['gpg2', 'gpg']) {
|
|
255
|
+
for (const p of paths) {
|
|
256
|
+
const full = join(p, name);
|
|
257
|
+
if (existsSync(full))
|
|
258
|
+
return full;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
throw new EncryptionError('GPG binary not found. Install gnupg.');
|
|
262
|
+
}
|
|
263
|
+
encrypt(plaintext) {
|
|
264
|
+
const gpgPath = this.findBinary();
|
|
265
|
+
const args = ['--armor', '--batch', '--yes'];
|
|
266
|
+
if (this.symmetric) {
|
|
267
|
+
args.push('--symmetric');
|
|
268
|
+
if (this.passphrase) {
|
|
269
|
+
args.push('--passphrase', this.passphrase);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
if (!this.recipient) {
|
|
274
|
+
throw new EncryptionError('No recipient configured for GPG encryption');
|
|
275
|
+
}
|
|
276
|
+
args.push('--encrypt', '--recipient', this.recipient);
|
|
277
|
+
}
|
|
278
|
+
const result = spawnSync(gpgPath, args, { input: plaintext, encoding: 'utf8' });
|
|
279
|
+
if (result.status !== 0) {
|
|
280
|
+
throw new EncryptionError(`GPG encryption failed: ${result.stderr || ''}`.trim());
|
|
281
|
+
}
|
|
282
|
+
return result.stdout;
|
|
283
|
+
}
|
|
284
|
+
decrypt(ciphertext) {
|
|
285
|
+
const gpgPath = this.findBinary();
|
|
286
|
+
const args = ['--decrypt', '--batch', '--yes'];
|
|
287
|
+
if (this.passphrase) {
|
|
288
|
+
args.push('--passphrase', this.passphrase);
|
|
289
|
+
}
|
|
290
|
+
const result = spawnSync(gpgPath, args, { input: ciphertext, encoding: 'utf8' });
|
|
291
|
+
if (result.status !== 0) {
|
|
292
|
+
throw new EncryptionError(`GPG decryption failed: ${result.stderr || ''}`.trim());
|
|
293
|
+
}
|
|
294
|
+
return result.stdout;
|
|
295
|
+
}
|
|
296
|
+
isAvailable() {
|
|
297
|
+
try {
|
|
298
|
+
this.findBinary();
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
generateKey() {
|
|
306
|
+
return `Key-Type: RSA
|
|
307
|
+
Key-Length: 4096
|
|
308
|
+
Subkey-Type: RSA
|
|
309
|
+
Subkey-Length: 4096
|
|
310
|
+
Name-Real: AI Workflow
|
|
311
|
+
Name-Email: marktoflow@localhost
|
|
312
|
+
Expire-Date: 1y
|
|
313
|
+
%no-protection
|
|
314
|
+
%commit`;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
export class InMemoryCredentialStore {
|
|
318
|
+
credentials = new Map();
|
|
319
|
+
save(credential) {
|
|
320
|
+
credential.updatedAt = new Date();
|
|
321
|
+
this.credentials.set(credential.name, credential);
|
|
322
|
+
}
|
|
323
|
+
get(name) {
|
|
324
|
+
return this.credentials.get(name) ?? null;
|
|
325
|
+
}
|
|
326
|
+
delete(name) {
|
|
327
|
+
return this.credentials.delete(name);
|
|
328
|
+
}
|
|
329
|
+
list(tag) {
|
|
330
|
+
const values = Array.from(this.credentials.values());
|
|
331
|
+
if (!tag)
|
|
332
|
+
return values;
|
|
333
|
+
return values.filter((c) => c.tags.includes(tag));
|
|
334
|
+
}
|
|
335
|
+
exists(name) {
|
|
336
|
+
return this.credentials.has(name);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
export class SQLiteCredentialStore {
|
|
340
|
+
db;
|
|
341
|
+
constructor(dbPath) {
|
|
342
|
+
const dir = dbPath.substring(0, dbPath.lastIndexOf('/'));
|
|
343
|
+
if (dir && !existsSync(dir)) {
|
|
344
|
+
mkdirSync(dir, { recursive: true });
|
|
345
|
+
}
|
|
346
|
+
this.db = new Database(dbPath);
|
|
347
|
+
this.init();
|
|
348
|
+
}
|
|
349
|
+
init() {
|
|
350
|
+
this.db.exec(`
|
|
351
|
+
CREATE TABLE IF NOT EXISTS credentials (
|
|
352
|
+
name TEXT PRIMARY KEY,
|
|
353
|
+
credential_type TEXT NOT NULL,
|
|
354
|
+
value TEXT NOT NULL,
|
|
355
|
+
description TEXT,
|
|
356
|
+
metadata TEXT,
|
|
357
|
+
created_at TEXT NOT NULL,
|
|
358
|
+
updated_at TEXT NOT NULL,
|
|
359
|
+
expires_at TEXT,
|
|
360
|
+
tags TEXT
|
|
361
|
+
);
|
|
362
|
+
CREATE INDEX IF NOT EXISTS idx_credentials_type ON credentials(credential_type);
|
|
363
|
+
`);
|
|
364
|
+
}
|
|
365
|
+
save(credential) {
|
|
366
|
+
const now = new Date();
|
|
367
|
+
credential.updatedAt = now;
|
|
368
|
+
this.db.prepare(`INSERT OR REPLACE INTO credentials
|
|
369
|
+
(name, credential_type, value, description, metadata, created_at, updated_at, expires_at, tags)
|
|
370
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(credential.name, credential.credentialType, credential.value, credential.description ?? '', JSON.stringify(credential.metadata ?? {}), credential.createdAt.toISOString(), credential.updatedAt.toISOString(), credential.expiresAt ? credential.expiresAt.toISOString() : null, JSON.stringify(credential.tags ?? []));
|
|
371
|
+
}
|
|
372
|
+
get(name) {
|
|
373
|
+
const row = this.db
|
|
374
|
+
.prepare('SELECT * FROM credentials WHERE name = ?')
|
|
375
|
+
.get(name);
|
|
376
|
+
if (!row)
|
|
377
|
+
return null;
|
|
378
|
+
return {
|
|
379
|
+
name: row.name,
|
|
380
|
+
credentialType: row.credential_type,
|
|
381
|
+
value: row.value,
|
|
382
|
+
description: row.description ?? '',
|
|
383
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {},
|
|
384
|
+
createdAt: new Date(row.created_at),
|
|
385
|
+
updatedAt: new Date(row.updated_at),
|
|
386
|
+
expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,
|
|
387
|
+
tags: row.tags ? JSON.parse(row.tags) : [],
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
delete(name) {
|
|
391
|
+
const res = this.db.prepare('DELETE FROM credentials WHERE name = ?').run(name);
|
|
392
|
+
return res.changes > 0;
|
|
393
|
+
}
|
|
394
|
+
list(tag) {
|
|
395
|
+
const rows = this.db.prepare('SELECT * FROM credentials ORDER BY name').all();
|
|
396
|
+
const creds = rows.map((row) => ({
|
|
397
|
+
name: row.name,
|
|
398
|
+
credentialType: row.credential_type,
|
|
399
|
+
value: row.value,
|
|
400
|
+
description: row.description ?? '',
|
|
401
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {},
|
|
402
|
+
createdAt: new Date(row.created_at),
|
|
403
|
+
updatedAt: new Date(row.updated_at),
|
|
404
|
+
expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,
|
|
405
|
+
tags: row.tags ? JSON.parse(row.tags) : [],
|
|
406
|
+
}));
|
|
407
|
+
if (!tag)
|
|
408
|
+
return creds;
|
|
409
|
+
return creds.filter((c) => c.tags.includes(tag));
|
|
410
|
+
}
|
|
411
|
+
exists(name) {
|
|
412
|
+
const row = this.db.prepare('SELECT 1 FROM credentials WHERE name = ?').get(name);
|
|
413
|
+
return Boolean(row);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
export class CredentialManager {
|
|
417
|
+
store;
|
|
418
|
+
encryptor;
|
|
419
|
+
constructor(store, encryptor) {
|
|
420
|
+
this.store = store;
|
|
421
|
+
this.encryptor = encryptor;
|
|
422
|
+
}
|
|
423
|
+
set(params) {
|
|
424
|
+
const encryptedValue = this.encryptor.encrypt(params.value);
|
|
425
|
+
const now = new Date();
|
|
426
|
+
const credential = {
|
|
427
|
+
name: params.name,
|
|
428
|
+
credentialType: params.credentialType ?? CredentialType.SECRET,
|
|
429
|
+
value: encryptedValue,
|
|
430
|
+
description: params.description ?? '',
|
|
431
|
+
metadata: params.metadata ?? {},
|
|
432
|
+
createdAt: now,
|
|
433
|
+
updatedAt: now,
|
|
434
|
+
expiresAt: params.expiresAt,
|
|
435
|
+
tags: params.tags ?? [],
|
|
436
|
+
};
|
|
437
|
+
this.store.save(credential);
|
|
438
|
+
return credential;
|
|
439
|
+
}
|
|
440
|
+
get(name, decrypt = true) {
|
|
441
|
+
const credential = this.store.get(name);
|
|
442
|
+
if (!credential) {
|
|
443
|
+
throw new CredentialNotFoundError(`Credential '${name}' not found`);
|
|
444
|
+
}
|
|
445
|
+
if (credential.expiresAt && credential.expiresAt < new Date()) {
|
|
446
|
+
throw new CredentialNotFoundError(`Credential '${name}' has expired`);
|
|
447
|
+
}
|
|
448
|
+
return decrypt ? this.encryptor.decrypt(credential.value) : credential.value;
|
|
449
|
+
}
|
|
450
|
+
getCredential(name) {
|
|
451
|
+
return this.store.get(name);
|
|
452
|
+
}
|
|
453
|
+
delete(name) {
|
|
454
|
+
return this.store.delete(name);
|
|
455
|
+
}
|
|
456
|
+
exists(name) {
|
|
457
|
+
return this.store.exists(name);
|
|
458
|
+
}
|
|
459
|
+
list(tag, includeExpired = false) {
|
|
460
|
+
const creds = this.store.list(tag);
|
|
461
|
+
if (includeExpired)
|
|
462
|
+
return creds;
|
|
463
|
+
return creds.filter((c) => !c.expiresAt || c.expiresAt >= new Date());
|
|
464
|
+
}
|
|
465
|
+
rotate(name, newValue) {
|
|
466
|
+
const existing = this.store.get(name);
|
|
467
|
+
if (!existing) {
|
|
468
|
+
throw new CredentialNotFoundError(`Credential '${name}' not found`);
|
|
469
|
+
}
|
|
470
|
+
return this.set({
|
|
471
|
+
name,
|
|
472
|
+
value: newValue,
|
|
473
|
+
credentialType: existing.credentialType,
|
|
474
|
+
...(existing.description !== undefined && { description: existing.description }),
|
|
475
|
+
...(existing.metadata !== undefined && { metadata: existing.metadata }),
|
|
476
|
+
...(existing.expiresAt !== undefined && { expiresAt: existing.expiresAt }),
|
|
477
|
+
...(existing.tags !== undefined && { tags: existing.tags }),
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
export(name) {
|
|
481
|
+
const credential = this.store.get(name);
|
|
482
|
+
if (!credential) {
|
|
483
|
+
throw new CredentialNotFoundError(`Credential '${name}' not found`);
|
|
484
|
+
}
|
|
485
|
+
return {
|
|
486
|
+
name: credential.name,
|
|
487
|
+
credential_type: credential.credentialType,
|
|
488
|
+
value: credential.value,
|
|
489
|
+
description: credential.description ?? '',
|
|
490
|
+
metadata: credential.metadata ?? {},
|
|
491
|
+
created_at: credential.createdAt.toISOString(),
|
|
492
|
+
updated_at: credential.updatedAt.toISOString(),
|
|
493
|
+
expires_at: credential.expiresAt ? credential.expiresAt.toISOString() : null,
|
|
494
|
+
tags: credential.tags ?? [],
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
importCredential(data) {
|
|
498
|
+
const now = new Date();
|
|
499
|
+
const credential = {
|
|
500
|
+
name: String(data.name),
|
|
501
|
+
credentialType: data.credential_type,
|
|
502
|
+
value: String(data.value),
|
|
503
|
+
description: String(data.description ?? ''),
|
|
504
|
+
metadata: data.metadata ?? {},
|
|
505
|
+
createdAt: data.created_at ? new Date(String(data.created_at)) : now,
|
|
506
|
+
updatedAt: data.updated_at ? new Date(String(data.updated_at)) : now,
|
|
507
|
+
expiresAt: data.expires_at ? new Date(String(data.expires_at)) : undefined,
|
|
508
|
+
tags: data.tags ?? [],
|
|
509
|
+
};
|
|
510
|
+
this.store.save(credential);
|
|
511
|
+
return credential;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
export class KeyManager {
|
|
515
|
+
keyDir;
|
|
516
|
+
constructor(keyDir) {
|
|
517
|
+
this.keyDir = keyDir;
|
|
518
|
+
if (!existsSync(keyDir)) {
|
|
519
|
+
mkdirSync(keyDir, { recursive: true });
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
keyFile(name) {
|
|
523
|
+
return join(this.keyDir, `${name}.key`);
|
|
524
|
+
}
|
|
525
|
+
generateFernetKey(name = 'default') {
|
|
526
|
+
const encryptor = new FernetEncryptor();
|
|
527
|
+
const key = encryptor.generateKey();
|
|
528
|
+
const keyFile = this.keyFile(name);
|
|
529
|
+
writeFileSync(keyFile, key);
|
|
530
|
+
return key;
|
|
531
|
+
}
|
|
532
|
+
generateAgeIdentity(name = 'default') {
|
|
533
|
+
const encryptor = new AgeEncryptor();
|
|
534
|
+
const identity = encryptor.generateKey();
|
|
535
|
+
const identityFile = join(this.keyDir, `${name}.age`);
|
|
536
|
+
writeFileSync(identityFile, identity);
|
|
537
|
+
const publicKey = AgeEncryptor.extractPublicKey(identity);
|
|
538
|
+
const pubFile = join(this.keyDir, `${name}.age.pub`);
|
|
539
|
+
writeFileSync(pubFile, publicKey);
|
|
540
|
+
return { identity, publicKey };
|
|
541
|
+
}
|
|
542
|
+
getFernetKey(name = 'default') {
|
|
543
|
+
const keyFile = this.keyFile(name);
|
|
544
|
+
return existsSync(keyFile) ? readFileSync(keyFile, 'utf8').trim() : null;
|
|
545
|
+
}
|
|
546
|
+
getAgeIdentityFile(name = 'default') {
|
|
547
|
+
const identityFile = join(this.keyDir, `${name}.age`);
|
|
548
|
+
return existsSync(identityFile) ? identityFile : null;
|
|
549
|
+
}
|
|
550
|
+
getAgePublicKey(name = 'default') {
|
|
551
|
+
const pubFile = join(this.keyDir, `${name}.age.pub`);
|
|
552
|
+
return existsSync(pubFile) ? readFileSync(pubFile, 'utf8').trim() : null;
|
|
553
|
+
}
|
|
554
|
+
listKeys() {
|
|
555
|
+
const keys = [];
|
|
556
|
+
if (!existsSync(this.keyDir))
|
|
557
|
+
return keys;
|
|
558
|
+
const entries = readdirSync(this.keyDir);
|
|
559
|
+
for (const entry of entries) {
|
|
560
|
+
if (entry.endsWith('.key')) {
|
|
561
|
+
keys.push({
|
|
562
|
+
name: entry.replace(/\.key$/, ''),
|
|
563
|
+
type: 'fernet',
|
|
564
|
+
file: join(this.keyDir, entry),
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
else if (entry.endsWith('.age') && !entry.endsWith('.age.pub')) {
|
|
568
|
+
const name = entry.replace(/\.age$/, '');
|
|
569
|
+
keys.push({
|
|
570
|
+
name,
|
|
571
|
+
type: 'age',
|
|
572
|
+
file: join(this.keyDir, entry),
|
|
573
|
+
public_key: this.getAgePublicKey(name),
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return keys;
|
|
578
|
+
}
|
|
579
|
+
deleteKey(name) {
|
|
580
|
+
let deleted = false;
|
|
581
|
+
const fernetKey = this.keyFile(name);
|
|
582
|
+
if (existsSync(fernetKey)) {
|
|
583
|
+
unlinkSync(fernetKey);
|
|
584
|
+
deleted = true;
|
|
585
|
+
}
|
|
586
|
+
const ageFile = join(this.keyDir, `${name}.age`);
|
|
587
|
+
if (existsSync(ageFile)) {
|
|
588
|
+
unlinkSync(ageFile);
|
|
589
|
+
deleted = true;
|
|
590
|
+
}
|
|
591
|
+
const pubFile = join(this.keyDir, `${name}.age.pub`);
|
|
592
|
+
if (existsSync(pubFile)) {
|
|
593
|
+
unlinkSync(pubFile);
|
|
594
|
+
deleted = true;
|
|
595
|
+
}
|
|
596
|
+
return deleted;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
export function createCredentialManager(params) {
|
|
600
|
+
const backend = params.backend ?? EncryptionBackend.FERNET;
|
|
601
|
+
const keyName = params.keyName ?? 'default';
|
|
602
|
+
const keyDir = join(params.stateDir, 'keys');
|
|
603
|
+
const dbPath = join(params.stateDir, 'credentials.db');
|
|
604
|
+
const keyManager = new KeyManager(keyDir);
|
|
605
|
+
const store = new SQLiteCredentialStore(dbPath);
|
|
606
|
+
if (backend === EncryptionBackend.FERNET) {
|
|
607
|
+
let key = keyManager.getFernetKey(keyName);
|
|
608
|
+
if (!key) {
|
|
609
|
+
key = keyManager.generateFernetKey(keyName);
|
|
610
|
+
}
|
|
611
|
+
return new CredentialManager(store, new FernetEncryptor(key));
|
|
612
|
+
}
|
|
613
|
+
if (backend === EncryptionBackend.AGE) {
|
|
614
|
+
if (params.passphrase) {
|
|
615
|
+
return new CredentialManager(store, new AgeEncryptor(undefined, undefined, params.passphrase));
|
|
616
|
+
}
|
|
617
|
+
let identityFile = keyManager.getAgeIdentityFile(keyName);
|
|
618
|
+
let publicKey = keyManager.getAgePublicKey(keyName);
|
|
619
|
+
if (!identityFile || !publicKey) {
|
|
620
|
+
const generated = keyManager.generateAgeIdentity(keyName);
|
|
621
|
+
identityFile = keyManager.getAgeIdentityFile(keyName);
|
|
622
|
+
publicKey = generated.publicKey;
|
|
623
|
+
}
|
|
624
|
+
return new CredentialManager(store, new AgeEncryptor(publicKey ?? undefined, identityFile ?? undefined));
|
|
625
|
+
}
|
|
626
|
+
if (backend === EncryptionBackend.GPG) {
|
|
627
|
+
if (params.passphrase) {
|
|
628
|
+
return new CredentialManager(store, new GPGEncryptor(undefined, undefined, params.passphrase, true));
|
|
629
|
+
}
|
|
630
|
+
throw new EncryptionError('GPG asymmetric encryption requires recipient configuration. Use passphrase for symmetric encryption or configure recipient manually.');
|
|
631
|
+
}
|
|
632
|
+
throw new Error(`Unknown backend: ${backend}`);
|
|
633
|
+
}
|
|
634
|
+
export function getAvailableBackends() {
|
|
635
|
+
const available = [EncryptionBackend.FERNET];
|
|
636
|
+
const age = new AgeEncryptor();
|
|
637
|
+
if (age.isAvailable()) {
|
|
638
|
+
available.push(EncryptionBackend.AGE);
|
|
639
|
+
}
|
|
640
|
+
const gpg = new GPGEncryptor();
|
|
641
|
+
if (gpg.isAvailable()) {
|
|
642
|
+
available.push(EncryptionBackend.GPG);
|
|
643
|
+
}
|
|
644
|
+
return available;
|
|
645
|
+
}
|
|
646
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|