lsh-framework 0.9.3 ā 0.10.1
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/cli.js +3 -2
- package/dist/services/secrets/secrets.js +77 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -75,11 +75,12 @@ program
|
|
|
75
75
|
console.log(' sync Check sync status & get recommendations');
|
|
76
76
|
console.log(' push Upload .env to encrypted cloud storage');
|
|
77
77
|
console.log(' pull Download .env from cloud storage');
|
|
78
|
-
console.log(' list List
|
|
78
|
+
console.log(' list List secrets in current local .env file');
|
|
79
|
+
console.log(' env List all stored environments');
|
|
79
80
|
console.log(' show View secrets (masked)');
|
|
80
81
|
console.log(' key Generate encryption key');
|
|
81
82
|
console.log(' create Create new .env file');
|
|
82
|
-
console.log(' get <key> Get a specific secret value');
|
|
83
|
+
console.log(' get <key> Get a specific secret value (--all for all)');
|
|
83
84
|
console.log(' set <key> <value> Set a specific secret value');
|
|
84
85
|
console.log(' delete Delete .env file');
|
|
85
86
|
console.log(' status Get detailed secrets status');
|
|
@@ -43,10 +43,71 @@ export async function init_secrets(program) {
|
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
|
-
// List
|
|
46
|
+
// List current local secrets
|
|
47
47
|
program
|
|
48
|
-
.command('list
|
|
48
|
+
.command('list')
|
|
49
49
|
.alias('ls')
|
|
50
|
+
.description('List secrets in the current local .env file')
|
|
51
|
+
.option('-f, --file <path>', 'Path to .env file', '.env')
|
|
52
|
+
.option('--keys-only', 'Show only keys, not values')
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
try {
|
|
55
|
+
const envPath = path.resolve(options.file);
|
|
56
|
+
if (!fs.existsSync(envPath)) {
|
|
57
|
+
console.error(`ā File not found: ${envPath}`);
|
|
58
|
+
console.log('š” Tip: Pull from cloud with: lsh pull --env <environment>');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
62
|
+
const lines = content.split('\n');
|
|
63
|
+
const secrets = [];
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
if (line.trim().startsWith('#') || !line.trim())
|
|
66
|
+
continue;
|
|
67
|
+
const match = line.match(/^([^=]+)=(.*)$/);
|
|
68
|
+
if (match) {
|
|
69
|
+
const key = match[1].trim();
|
|
70
|
+
let value = match[2].trim();
|
|
71
|
+
// Remove quotes if present
|
|
72
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
73
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
74
|
+
value = value.slice(1, -1);
|
|
75
|
+
}
|
|
76
|
+
secrets.push({ key, value });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (secrets.length === 0) {
|
|
80
|
+
console.log('No secrets found in .env file');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
console.log(`\nš Secrets in ${options.file}:\n`);
|
|
84
|
+
for (const { key, value } of secrets) {
|
|
85
|
+
if (options.keysOnly) {
|
|
86
|
+
console.log(` ${key}`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Mask the value but show first/last 3 chars if long enough
|
|
90
|
+
let maskedValue = value;
|
|
91
|
+
if (value.length > 8) {
|
|
92
|
+
maskedValue = `${value.substring(0, 3)}${'*'.repeat(value.length - 6)}${value.substring(value.length - 3)}`;
|
|
93
|
+
}
|
|
94
|
+
else if (value.length > 0) {
|
|
95
|
+
maskedValue = '*'.repeat(value.length);
|
|
96
|
+
}
|
|
97
|
+
console.log(` ${key}=${maskedValue}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
console.log(`\n Total: ${secrets.length} secrets\n`);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
const err = error;
|
|
104
|
+
console.error('ā Failed to list secrets:', err.message);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// Manage environments (old 'list' functionality)
|
|
109
|
+
program
|
|
110
|
+
.command('env [environment]')
|
|
50
111
|
.description('List all stored environments or show secrets for specific environment')
|
|
51
112
|
.option('--all-files', 'List all tracked .env files across environments')
|
|
52
113
|
.action(async (environment, options) => {
|
|
@@ -109,13 +170,22 @@ export async function init_secrets(program) {
|
|
|
109
170
|
program
|
|
110
171
|
.command('key')
|
|
111
172
|
.description('Generate a new encryption key')
|
|
112
|
-
.
|
|
173
|
+
.option('--export', 'Output in export format for shell evaluation')
|
|
174
|
+
.action(async (options) => {
|
|
113
175
|
const { randomBytes } = await import('crypto');
|
|
114
176
|
const key = randomBytes(32).toString('hex');
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
177
|
+
if (options.export) {
|
|
178
|
+
// Just output the export statement for eval
|
|
179
|
+
console.log(`export LSH_SECRETS_KEY='${key}'`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Interactive output with tips
|
|
183
|
+
console.log('\nš New encryption key (add to your .env):\n');
|
|
184
|
+
console.log(`export LSH_SECRETS_KEY='${key}'\n`);
|
|
185
|
+
console.log('š” Tip: Share this key securely with your team to sync secrets.');
|
|
186
|
+
console.log(' Never commit it to git!\n');
|
|
187
|
+
console.log('š” To load immediately: eval "$(lsh key --export)"\n');
|
|
188
|
+
}
|
|
119
189
|
});
|
|
120
190
|
// Create .env file
|
|
121
191
|
program
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lsh-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Encrypted secrets manager with automatic rotation, team sync, and multi-environment support. Built on a powerful shell with daemon scheduling and CI/CD integration.",
|
|
5
5
|
"main": "dist/app.js",
|
|
6
6
|
"bin": {
|