@vybestack/llxprt-code-storage 0.10.0-nightly.260613.1adad3b34

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.
Files changed (41) hide show
  1. package/dist/.last_build +0 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/config/storage.d.ts +39 -0
  6. package/dist/src/config/storage.js +118 -0
  7. package/dist/src/config/storage.js.map +1 -0
  8. package/dist/src/conversation/ConversationFileWriter.d.ts +27 -0
  9. package/dist/src/conversation/ConversationFileWriter.js +78 -0
  10. package/dist/src/conversation/ConversationFileWriter.js.map +1 -0
  11. package/dist/src/index.d.ts +12 -0
  12. package/dist/src/index.js +14 -0
  13. package/dist/src/index.js.map +1 -0
  14. package/dist/src/secure-store/provider-key-storage.d.ts +53 -0
  15. package/dist/src/secure-store/provider-key-storage.js +117 -0
  16. package/dist/src/secure-store/provider-key-storage.js.map +1 -0
  17. package/dist/src/secure-store/secure-store.d.ts +69 -0
  18. package/dist/src/secure-store/secure-store.js +606 -0
  19. package/dist/src/secure-store/secure-store.js.map +1 -0
  20. package/dist/src/services/fileDiscoveryService.d.ts +48 -0
  21. package/dist/src/services/fileDiscoveryService.js +154 -0
  22. package/dist/src/services/fileDiscoveryService.js.map +1 -0
  23. package/dist/src/services/fileSystemService.d.ts +33 -0
  24. package/dist/src/services/fileSystemService.js +25 -0
  25. package/dist/src/services/fileSystemService.js.map +1 -0
  26. package/dist/src/session/sessionTypes.d.ts +39 -0
  27. package/dist/src/session/sessionTypes.js +10 -0
  28. package/dist/src/session/sessionTypes.js.map +1 -0
  29. package/dist/src/testing.d.ts +1 -0
  30. package/dist/src/testing.js +4 -0
  31. package/dist/src/testing.js.map +1 -0
  32. package/dist/src/types/logger.d.ts +17 -0
  33. package/dist/src/types/logger.js +17 -0
  34. package/dist/src/types/logger.js.map +1 -0
  35. package/dist/src/utils/gitIgnoreParser.d.ts +29 -0
  36. package/dist/src/utils/gitIgnoreParser.js +199 -0
  37. package/dist/src/utils/gitIgnoreParser.js.map +1 -0
  38. package/dist/src/utils/gitUtils.d.ts +17 -0
  39. package/dist/src/utils/gitUtils.js +68 -0
  40. package/dist/src/utils/gitUtils.js.map +1 -0
  41. package/package.json +77 -0
@@ -0,0 +1,606 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Secure credential storage with OS keychain integration.
8
+ *
9
+ * Provides get/set/delete/list/has operations against the OS keyring,
10
+ * with injectable adapter for testing via keyringLoader option.
11
+ *
12
+ * @plan PLAN-20260211-SECURESTORE.P06
13
+ * @requirement R1.1, R1.3, R2.1, R3.1a, R3.1b, R3.2-R3.8, R4.1-R4.8, R5.1-R5.2, R6.1
14
+ */
15
+ import * as crypto from 'node:crypto';
16
+ import { promises as fs } from 'node:fs';
17
+ import * as path from 'node:path';
18
+ import * as os from 'node:os';
19
+ import envPaths from 'env-paths';
20
+ import { NullStorageLoggerImpl } from '../types/logger.js';
21
+ // Platform-standard paths for llxprt-code app data (no suffix to match documented paths)
22
+ const platformPaths = envPaths('llxprt-code', { suffix: '' });
23
+ let _moduleLogger = new NullStorageLoggerImpl();
24
+ function setSecureStoreModuleLogger(logger) {
25
+ _moduleLogger = logger;
26
+ }
27
+ export class SecureStoreError extends Error {
28
+ code;
29
+ remediation;
30
+ constructor(message, code, remediation) {
31
+ super(message);
32
+ this.name = 'SecureStoreError';
33
+ this.code = code;
34
+ this.remediation = remediation;
35
+ }
36
+ }
37
+ // ─── Helper Functions ────────────────────────────────────────────────────────
38
+ function safeUsername() {
39
+ try {
40
+ return os.userInfo().username;
41
+ }
42
+ catch {
43
+ return String(process.getuid?.() ?? 'unknown');
44
+ }
45
+ }
46
+ function classifyError(error) {
47
+ const msg = error instanceof Error
48
+ ? error.message.toLowerCase()
49
+ : String(error).toLowerCase();
50
+ if (msg.includes('locked'))
51
+ return 'LOCKED';
52
+ if (msg.includes('denied') || msg.includes('permission'))
53
+ return 'DENIED';
54
+ if (msg.includes('timeout') || msg.includes('timed out'))
55
+ return 'TIMEOUT';
56
+ if (msg.includes('not found'))
57
+ return 'NOT_FOUND';
58
+ const errObj = error;
59
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
60
+ if (errObj?.code === 'ENOENT')
61
+ return 'NOT_FOUND';
62
+ return 'UNAVAILABLE';
63
+ }
64
+ function getRemediation(code) {
65
+ switch (code) {
66
+ case 'UNAVAILABLE':
67
+ return 'Use --key, install a keyring backend, or use seatbelt mode';
68
+ case 'LOCKED':
69
+ return 'Unlock your keyring';
70
+ case 'DENIED':
71
+ return 'Check permissions, run as correct user';
72
+ case 'CORRUPT':
73
+ return 'Re-save the key or re-authenticate';
74
+ case 'TIMEOUT':
75
+ return 'Retry, check system load';
76
+ case 'NOT_FOUND':
77
+ return 'Save the key first';
78
+ default:
79
+ return 'An unexpected error occurred';
80
+ }
81
+ }
82
+ function isTransientError(error) {
83
+ return classifyError(error) === 'TIMEOUT';
84
+ }
85
+ function isValidEnvelope(envelope) {
86
+ if (typeof envelope !== 'object' || envelope === null)
87
+ return false;
88
+ const env = envelope;
89
+ if (env.v !== 1)
90
+ return false;
91
+ if (typeof env.crypto !== 'object' || env.crypto === null)
92
+ return false;
93
+ const c = env.crypto;
94
+ if (c.alg !== 'aes-256-gcm')
95
+ return false;
96
+ if (c.kdf !== 'scrypt')
97
+ return false;
98
+ if (typeof env.data !== 'string')
99
+ return false;
100
+ return true;
101
+ }
102
+ function withFindCredentials(adapter, findCredentialsFn) {
103
+ if (findCredentialsFn !== undefined) {
104
+ adapter.findCredentials = async (service) => {
105
+ try {
106
+ return await findCredentialsFn(service);
107
+ }
108
+ catch {
109
+ return [];
110
+ }
111
+ };
112
+ }
113
+ return adapter;
114
+ }
115
+ /**
116
+ * Creates a default KeyringAdapter by loading @napi-rs/keyring.
117
+ * Exported so that other modules can reuse this without duplicating
118
+ * the @napi-rs/keyring import.
119
+ *
120
+ * @plan PLAN-20260211-SECURESTORE.P08
121
+ */
122
+ export async function createDefaultKeyringAdapter() {
123
+ try {
124
+ const module = await import('@napi-rs/keyring');
125
+ const keyring = module.default ?? module;
126
+ const kr = keyring;
127
+ const findCredentialsFn = kr.findCredentials ?? kr.findCredentialsAsync;
128
+ const adapter = {
129
+ getPassword: async (service, account) => {
130
+ const entry = new kr.AsyncEntry(service, account);
131
+ return entry.getPassword();
132
+ },
133
+ setPassword: async (service, account, password) => {
134
+ const entry = new kr.AsyncEntry(service, account);
135
+ await entry.setPassword(password);
136
+ },
137
+ deletePassword: async (service, account) => {
138
+ const entry = new kr.AsyncEntry(service, account);
139
+ return entry.deleteCredential();
140
+ },
141
+ };
142
+ return withFindCredentials(adapter, findCredentialsFn);
143
+ }
144
+ catch (error) {
145
+ const err = error;
146
+ const isModuleMissing =
147
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
148
+ err?.code === 'ERR_MODULE_NOT_FOUND' ||
149
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
150
+ err?.code === 'MODULE_NOT_FOUND' ||
151
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
152
+ err?.code === 'ERR_DLOPEN_FAILED' ||
153
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
154
+ err?.message?.includes('@napi-rs/keyring');
155
+ if (!isModuleMissing && process.env.DEBUG) {
156
+ _moduleLogger.warn(
157
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Secure storage adapters can return malformed runtime data despite declared types.
158
+ `[SecureStore] Unexpected error loading @napi-rs/keyring: ${err?.message}`);
159
+ }
160
+ return null;
161
+ }
162
+ }
163
+ function scryptAsync(password, salt, keyLen, options) {
164
+ return new Promise((resolve, reject) => {
165
+ crypto.scrypt(password, salt, keyLen, options, (err, key) => {
166
+ if (err)
167
+ reject(err);
168
+ else
169
+ resolve(key);
170
+ });
171
+ });
172
+ }
173
+ // ─── SecureStore Class ───────────────────────────────────────────────────────
174
+ /**
175
+ * Stores and retrieves secrets via the OS keychain or encrypted file fallback.
176
+ *
177
+ * @plan PLAN-20260211-SECURESTORE.P06
178
+ * @requirement R1.1, R1.3
179
+ */
180
+ export class SecureStore {
181
+ serviceName;
182
+ fallbackPolicy;
183
+ keyringLoaderFn;
184
+ fallbackDir;
185
+ logger;
186
+ keyringInstance = undefined;
187
+ keyringLoadAttempted = false;
188
+ probeCache = null;
189
+ PROBE_TTL_MS = 60000;
190
+ consecutiveKeyringFailures = 0;
191
+ KEYRING_FAILURE_THRESHOLD = 3;
192
+ constructor(serviceName, options) {
193
+ this.serviceName = serviceName;
194
+ this.fallbackDir =
195
+ options?.fallbackDir ??
196
+ path.join(platformPaths.data, 'secure-store', serviceName);
197
+ this.fallbackPolicy = options?.fallbackPolicy ?? 'allow';
198
+ this.keyringLoaderFn =
199
+ options?.keyringLoader ?? createDefaultKeyringAdapter;
200
+ this.logger = options?.logger ?? new NullStorageLoggerImpl();
201
+ setSecureStoreModuleLogger(this.logger);
202
+ }
203
+ // ─── Keyring Loading ──────────────────────────────────────────────────────
204
+ async getKeyring() {
205
+ if (this.keyringLoadAttempted) {
206
+ return this.keyringInstance ?? null;
207
+ }
208
+ this.keyringLoadAttempted = true;
209
+ try {
210
+ const adapter = await this.keyringLoaderFn();
211
+ this.keyringInstance = adapter;
212
+ this.logger.debug(() => `[keyring] @napi-rs/keyring loaded=${adapter !== null}`);
213
+ return adapter;
214
+ }
215
+ catch (error) {
216
+ this.keyringInstance = null;
217
+ const msg = error instanceof Error ? error.message : String(error);
218
+ this.logger.debug(() => `[keyring] @napi-rs/keyring load failed: ${msg}`);
219
+ return null;
220
+ }
221
+ }
222
+ // ─── Key Validation ──────────────────────────────────────────────────────
223
+ validateKey(key) {
224
+ if (key.length === 0) {
225
+ throw new SecureStoreError('Key must not be empty', 'CORRUPT', 'Provide a non-empty key name');
226
+ }
227
+ if (key.includes('/') || key.includes('\\')) {
228
+ throw new SecureStoreError(`Key contains path separator: ${key}`, 'CORRUPT', 'Key names must not contain path separators');
229
+ }
230
+ if (key.includes('\0')) {
231
+ throw new SecureStoreError('Key contains null byte', 'CORRUPT', 'Key names must not contain null bytes');
232
+ }
233
+ if (key === '.' ||
234
+ key === '..' ||
235
+ key.startsWith('./') ||
236
+ key.startsWith('../')) {
237
+ throw new SecureStoreError(`Key contains relative-path component: ${key}`, 'CORRUPT', 'Key names must not be "." or ".." or start with "./" or "../"');
238
+ }
239
+ }
240
+ getFallbackFilePath(key) {
241
+ this.validateKey(key);
242
+ return path.join(this.fallbackDir, key + '.enc');
243
+ }
244
+ // ─── Consecutive Failure Tracking ────────────────────────────────────────
245
+ recordKeyringSuccess() {
246
+ this.consecutiveKeyringFailures = 0;
247
+ }
248
+ recordKeyringFailure() {
249
+ this.consecutiveKeyringFailures += 1;
250
+ if (this.consecutiveKeyringFailures >= this.KEYRING_FAILURE_THRESHOLD) {
251
+ this.probeCache = null;
252
+ }
253
+ }
254
+ // ─── Availability Probe ──────────────────────────────────────────────────
255
+ async isKeychainAvailable() {
256
+ // Check cache — honor both positive and negative results within TTL
257
+ if (this.probeCache !== null) {
258
+ const elapsed = Date.now() - this.probeCache.timestamp;
259
+ if (elapsed < this.PROBE_TTL_MS) {
260
+ this.logger.debug(() => `[probe] cached=${this.probeCache.available} (within TTL)`);
261
+ return this.probeCache.available;
262
+ }
263
+ }
264
+ const adapter = await this.getKeyring();
265
+ if (adapter === null) {
266
+ this.probeCache = { available: false, timestamp: Date.now() };
267
+ this.logger.debug(() => '[probe] @napi-rs/keyring not loaded — unavailable');
268
+ return false;
269
+ }
270
+ const testAccount = '__securestore_probe__' + crypto.randomUUID().substring(0, 8);
271
+ const testValue = 'probe-' + Date.now();
272
+ try {
273
+ await adapter.setPassword(this.serviceName, testAccount, testValue);
274
+ const retrieved = await adapter.getPassword(this.serviceName, testAccount);
275
+ await adapter.deletePassword(this.serviceName, testAccount);
276
+ const probeOk = retrieved === testValue;
277
+ this.probeCache = { available: probeOk, timestamp: Date.now() };
278
+ if (!probeOk) {
279
+ this.logger.debug(() => '[probe] keyring probe value mismatch — marking unavailable');
280
+ }
281
+ else {
282
+ this.logger.debug(() => '[probe] keyring available — OS keychain active');
283
+ }
284
+ return probeOk;
285
+ }
286
+ catch (error) {
287
+ const msg = error instanceof Error ? error.message : String(error);
288
+ this.logger.debug(() => `[probe] keyring probe failed: ${msg}`);
289
+ if (isTransientError(error)) {
290
+ this.probeCache = null;
291
+ }
292
+ else {
293
+ this.probeCache = { available: false, timestamp: Date.now() };
294
+ }
295
+ return false;
296
+ }
297
+ }
298
+ async writeFallbackAfterKeyringSuccess(key, value) {
299
+ try {
300
+ await this.writeFallbackFile(key, value);
301
+ }
302
+ catch (error) {
303
+ const msg = error instanceof Error ? error.message : String(error);
304
+ this.logger.debug(() => `[set] key='${key}' fallback backup failed after keyring success (${this.fallbackDir}): ${msg}`);
305
+ }
306
+ }
307
+ // ─── CRUD: set() ─────────────────────────────────────────────────────────
308
+ async set(key, value) {
309
+ this.validateKey(key);
310
+ // Try keyring first (directly, not via isKeychainAvailable)
311
+ const adapter = await this.getKeyring();
312
+ let keyringWriteSucceeded = false;
313
+ let keyringWriteError = null;
314
+ if (adapter !== null) {
315
+ try {
316
+ await adapter.setPassword(this.serviceName, key, value);
317
+ this.recordKeyringSuccess();
318
+ this.logger.debug(() => `[set] key='${key}' → keyring (OS keychain)`);
319
+ keyringWriteSucceeded = true;
320
+ }
321
+ catch (error) {
322
+ keyringWriteError = error;
323
+ this.recordKeyringFailure();
324
+ const msg = error instanceof Error ? error.message : String(error);
325
+ this.logger.debug(() => `[set] key='${key}' keyring write failed: ${msg}`);
326
+ }
327
+ }
328
+ // If keyring succeeded and fallbackPolicy is deny, we're done
329
+ if (keyringWriteSucceeded && this.fallbackPolicy === 'deny') {
330
+ return;
331
+ }
332
+ // If keyring unavailable or write failed, check fallback policy
333
+ if (!keyringWriteSucceeded && this.fallbackPolicy === 'deny') {
334
+ if (adapter !== null && keyringWriteError !== null) {
335
+ const classified = classifyError(keyringWriteError);
336
+ const msg = keyringWriteError instanceof Error
337
+ ? keyringWriteError.message
338
+ : String(keyringWriteError);
339
+ this.logger.debug(() => `[set] key='${key}' fallback denied after keyring write failure (${classified})`);
340
+ throw new SecureStoreError(msg, classified, getRemediation(classified));
341
+ }
342
+ this.logger.debug(() => `[set] key='${key}' fallback denied — throwing UNAVAILABLE`);
343
+ throw new SecureStoreError('Keyring is unavailable and fallback is denied', 'UNAVAILABLE', 'Use --key, install a keyring backend, or change fallbackPolicy to allow');
344
+ }
345
+ const shouldWriteFallback = this.fallbackPolicy === 'allow' &&
346
+ (!keyringWriteSucceeded || process.platform === 'linux');
347
+ if (!shouldWriteFallback) {
348
+ return;
349
+ }
350
+ this.logger.debug(() => `[set] key='${key}' → encrypted fallback file (${this.fallbackDir})`);
351
+ if (keyringWriteSucceeded) {
352
+ await this.writeFallbackAfterKeyringSuccess(key, value);
353
+ return;
354
+ }
355
+ await this.writeFallbackFile(key, value);
356
+ }
357
+ // ─── CRUD: get() ─────────────────────────────────────────────────────────
358
+ async get(key) {
359
+ this.validateKey(key);
360
+ // Try keyring first (authoritative)
361
+ const adapter = await this.getKeyring();
362
+ if (adapter !== null) {
363
+ try {
364
+ const value = await adapter.getPassword(this.serviceName, key);
365
+ if (value !== null) {
366
+ this.recordKeyringSuccess();
367
+ this.logger.debug(() => `[get] key='${key}' → found in keyring (OS keychain)`);
368
+ return value;
369
+ }
370
+ this.logger.debug(() => `[get] key='${key}' → not found in keyring`);
371
+ }
372
+ catch (error) {
373
+ this.recordKeyringFailure();
374
+ const classified = classifyError(error);
375
+ const msg = error instanceof Error ? error.message : String(error);
376
+ this.logger.debug(() => `[get] key='${key}' keyring read failed (${classified}): ${msg}`);
377
+ // Re-throw non-transient, non-availability errors so callers know
378
+ // the keyring is actively denying access (not just missing).
379
+ if (classified !== 'UNAVAILABLE' &&
380
+ classified !== 'NOT_FOUND' &&
381
+ classified !== 'TIMEOUT') {
382
+ throw new SecureStoreError(msg, classified, getRemediation(classified));
383
+ }
384
+ }
385
+ }
386
+ else {
387
+ this.logger.debug(() => `[get] key='${key}' keyring adapter not available`);
388
+ }
389
+ // Try fallback file
390
+ const fallbackValue = await this.readFallbackFile(key);
391
+ if (fallbackValue !== null) {
392
+ this.logger.debug(() => `[get] key='${key}' → found in encrypted fallback file`);
393
+ return fallbackValue;
394
+ }
395
+ this.logger.debug(() => `[get] key='${key}' → not found anywhere`);
396
+ return null;
397
+ }
398
+ // ─── CRUD: delete() ──────────────────────────────────────────────────────
399
+ async delete(key) {
400
+ this.validateKey(key);
401
+ let deletedFromKeyring = false;
402
+ let deletedFromFile = false;
403
+ const adapter = await this.getKeyring();
404
+ if (adapter !== null) {
405
+ try {
406
+ deletedFromKeyring = await adapter.deletePassword(this.serviceName, key);
407
+ }
408
+ catch {
409
+ // Keyring delete failed
410
+ }
411
+ }
412
+ const filePath = this.getFallbackFilePath(key);
413
+ try {
414
+ await fs.unlink(filePath);
415
+ deletedFromFile = true;
416
+ }
417
+ catch (error) {
418
+ const err = error;
419
+ if (err.code !== 'ENOENT') {
420
+ // Non-missing-file errors
421
+ }
422
+ }
423
+ this.logger.debug(() => `[delete] key='${key}' keyring=${deletedFromKeyring} fallback=${deletedFromFile}`);
424
+ return deletedFromKeyring || deletedFromFile;
425
+ }
426
+ // ─── CRUD: list() ────────────────────────────────────────────────────────
427
+ async list() {
428
+ const keys = new Set();
429
+ const adapter = await this.getKeyring();
430
+ if (adapter !== null && typeof adapter.findCredentials === 'function') {
431
+ try {
432
+ const creds = await adapter.findCredentials(this.serviceName);
433
+ for (const cred of creds) {
434
+ // eslint-disable-next-line sonarjs/nested-control-flow -- Existing structure is intentionally preserved; refactoring this boundary is outside the lint slice.
435
+ if (!cred.account.startsWith('__securestore_probe__')) {
436
+ keys.add(cred.account);
437
+ }
438
+ }
439
+ }
440
+ catch {
441
+ // Keyring enumeration failed
442
+ }
443
+ }
444
+ try {
445
+ const files = await fs.readdir(this.fallbackDir);
446
+ for (const file of files) {
447
+ if (file.endsWith('.enc')) {
448
+ const keyName = file.slice(0, -4);
449
+ // eslint-disable-next-line sonarjs/nested-control-flow -- Existing structure is intentionally preserved; refactoring this boundary is outside the lint slice.
450
+ try {
451
+ this.validateKey(keyName);
452
+ keys.add(keyName);
453
+ }
454
+ catch {
455
+ // Malformed filename — skip
456
+ }
457
+ }
458
+ }
459
+ }
460
+ catch (error) {
461
+ const err = error;
462
+ if (err.code !== 'ENOENT') {
463
+ // Non-missing-dir errors
464
+ }
465
+ }
466
+ const sorted = Array.from(keys).sort();
467
+ this.logger.debug(() => `[list] found ${sorted.length} key(s)`);
468
+ return sorted;
469
+ }
470
+ // ─── CRUD: has() ─────────────────────────────────────────────────────────
471
+ async has(key) {
472
+ this.validateKey(key);
473
+ const adapter = await this.getKeyring();
474
+ if (adapter !== null) {
475
+ try {
476
+ const value = await adapter.getPassword(this.serviceName, key);
477
+ if (value !== null) {
478
+ return true;
479
+ }
480
+ }
481
+ catch (error) {
482
+ const classified = classifyError(error);
483
+ if (classified !== 'NOT_FOUND') {
484
+ throw new SecureStoreError(error instanceof Error ? error.message : String(error), classified, getRemediation(classified));
485
+ }
486
+ }
487
+ }
488
+ const filePath = this.getFallbackFilePath(key);
489
+ try {
490
+ await fs.access(filePath);
491
+ return true;
492
+ }
493
+ catch {
494
+ return false;
495
+ }
496
+ }
497
+ // ─── Encrypted File Fallback: Write ──────────────────────────────────────
498
+ async writeFallbackFile(key, value) {
499
+ await fs.mkdir(this.fallbackDir, { recursive: true, mode: 0o700 });
500
+ const salt = crypto.randomBytes(16);
501
+ const machineId = crypto
502
+ .createHash('sha256')
503
+ .update(os.hostname() + safeUsername())
504
+ .digest('hex');
505
+ const kdfInput = this.serviceName + '-' + machineId;
506
+ const encKey = await scryptAsync(kdfInput, salt, 32, {
507
+ N: 16384,
508
+ r: 8,
509
+ p: 1,
510
+ });
511
+ const iv = crypto.randomBytes(12);
512
+ const cipher = crypto.createCipheriv('aes-256-gcm', encKey, iv);
513
+ const encrypted = Buffer.concat([
514
+ cipher.update(value, 'utf8'),
515
+ cipher.final(),
516
+ ]);
517
+ const authTag = cipher.getAuthTag();
518
+ const ciphertext = Buffer.concat([salt, iv, authTag, encrypted]);
519
+ const envelope = {
520
+ v: 1,
521
+ crypto: {
522
+ alg: 'aes-256-gcm',
523
+ kdf: 'scrypt',
524
+ N: 16384,
525
+ r: 8,
526
+ p: 1,
527
+ saltLen: 16,
528
+ },
529
+ data: ciphertext.toString('base64'),
530
+ };
531
+ const finalPath = this.getFallbackFilePath(key);
532
+ const tempPath = finalPath + '.tmp.' + crypto.randomUUID().substring(0, 8);
533
+ const fd = await fs.open(tempPath, 'w', 0o600);
534
+ try {
535
+ await fd.writeFile(JSON.stringify(envelope));
536
+ await fd.sync();
537
+ await fd.close();
538
+ await fs.rename(tempPath, finalPath);
539
+ await fs.chmod(finalPath, 0o600);
540
+ }
541
+ catch (error) {
542
+ await fd.close().catch(() => { });
543
+ await fs.unlink(tempPath).catch(() => { });
544
+ throw error;
545
+ }
546
+ }
547
+ // ─── Encrypted File Fallback: Read ───────────────────────────────────────
548
+ async readFallbackFile(key) {
549
+ const filePath = this.getFallbackFilePath(key);
550
+ let content;
551
+ try {
552
+ content = await fs.readFile(filePath, 'utf8');
553
+ }
554
+ catch (error) {
555
+ const err = error;
556
+ if (err.code === 'ENOENT') {
557
+ return null;
558
+ }
559
+ throw error;
560
+ }
561
+ let envelope;
562
+ try {
563
+ envelope = JSON.parse(content);
564
+ }
565
+ catch {
566
+ throw new SecureStoreError('Fallback file is corrupt or uses an unrecognized format', 'CORRUPT', 'Re-save the key or re-authenticate');
567
+ }
568
+ const env = envelope;
569
+ if (env.v !== 1) {
570
+ throw new SecureStoreError('Unrecognized envelope version: ' +
571
+ String(env.v) +
572
+ '. This file may require a newer version.', 'CORRUPT', 'upgrade to the latest version or re-save the key');
573
+ }
574
+ if (!isValidEnvelope(envelope)) {
575
+ throw new SecureStoreError('Fallback file envelope is malformed', 'CORRUPT', 'Re-save the key or re-authenticate');
576
+ }
577
+ const ciphertext = Buffer.from(envelope.data, 'base64');
578
+ const salt = ciphertext.subarray(0, 16);
579
+ const iv = ciphertext.subarray(16, 28);
580
+ const authTag = ciphertext.subarray(28, 44);
581
+ const encryptedData = ciphertext.subarray(44);
582
+ const machineId = crypto
583
+ .createHash('sha256')
584
+ .update(os.hostname() + safeUsername())
585
+ .digest('hex');
586
+ const kdfInput = this.serviceName + '-' + machineId;
587
+ const decKey = await scryptAsync(kdfInput, salt, 32, {
588
+ N: 16384,
589
+ r: 8,
590
+ p: 1,
591
+ });
592
+ try {
593
+ const decipher = crypto.createDecipheriv('aes-256-gcm', decKey, iv);
594
+ decipher.setAuthTag(authTag);
595
+ const decrypted = Buffer.concat([
596
+ decipher.update(encryptedData),
597
+ decipher.final(),
598
+ ]);
599
+ return decrypted.toString('utf8');
600
+ }
601
+ catch {
602
+ throw new SecureStoreError('Failed to decrypt fallback file', 'CORRUPT', 'Re-save the key or re-authenticate. The file may have been created on a different machine.');
603
+ }
604
+ }
605
+ }
606
+ //# sourceMappingURL=secure-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../../src/secure-store/secure-store.ts"],"names":[],"mappings":"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"}