@nourmohamed/vaultix-cli 1.0.0 → 1.0.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/bin/cli.js +78 -21
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,51 +1,108 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const CONFIG_PATH = path.join(os.homedir(), '.vaultix.json');
|
|
7
|
+
|
|
8
|
+
function saveConfig(config) {
|
|
9
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function loadConfig() {
|
|
13
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
4
22
|
|
|
5
23
|
async function run() {
|
|
6
24
|
const args = process.argv.slice(2);
|
|
7
25
|
const command = args[0];
|
|
8
26
|
const target = args[1];
|
|
27
|
+
const config = loadConfig();
|
|
28
|
+
|
|
29
|
+
if (command === 'login') {
|
|
30
|
+
const key = args[1];
|
|
31
|
+
if (!key) {
|
|
32
|
+
console.error('\x1b[31m[Error]\x1b[0m Please provide your API key: vaultix login vtx_your_key');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
saveConfig({ ...config, apiKey: key });
|
|
36
|
+
console.log('\x1b[32m[Success]\x1b[0m Authenticated successfully. Your key is saved locally.');
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
9
39
|
|
|
10
40
|
if (!command) {
|
|
11
41
|
console.error(`
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
42
|
+
\x1b[36mVaultix CLI Help\x1b[0m
|
|
43
|
+
----------------
|
|
44
|
+
Steps to get started:
|
|
45
|
+
1. \x1b[33mvaultix login <API_KEY>\x1b[0m (Authenticates your machine)
|
|
46
|
+
2. \x1b[33mvaultix list\x1b[0m (Shows your secrets)
|
|
47
|
+
3. \x1b[33mvaultix get <NAME>\x1b[0m (Retrieves a secret)
|
|
17
48
|
|
|
18
|
-
|
|
49
|
+
Full Commands:
|
|
50
|
+
vaultix login <KEY>
|
|
51
|
+
vaultix get <NAME>
|
|
52
|
+
vaultix list
|
|
53
|
+
vaultix set <NAME> <VALUE>
|
|
54
|
+
vaultix delete <NAME>
|
|
19
55
|
`);
|
|
20
56
|
process.exit(1);
|
|
21
57
|
}
|
|
22
58
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
59
|
+
const { apiKey } = loadConfig();
|
|
60
|
+
const token = process.env.VAULTIX_API_KEY || apiKey;
|
|
61
|
+
const baseUrl = process.env.VAULTIX_URL || 'http://localhost:3000';
|
|
62
|
+
|
|
63
|
+
if (!token) {
|
|
64
|
+
console.error(`\x1b[31m[Error]\x1b[0m No API key found.`);
|
|
65
|
+
console.log('\x1b[33mTip:\x1b[0m Run "vaultix login <key>" to authenticate.');
|
|
28
66
|
process.exit(1);
|
|
29
67
|
}
|
|
30
68
|
|
|
69
|
+
// Simplified internal client to avoid dependency issues
|
|
70
|
+
const callApi = async (path, method = 'GET', body = null) => {
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
73
|
+
method,
|
|
74
|
+
headers: {
|
|
75
|
+
'Authorization': `Bearer ${token}`,
|
|
76
|
+
'Content-Type': 'application/json'
|
|
77
|
+
},
|
|
78
|
+
body: body ? JSON.stringify(body) : null
|
|
79
|
+
});
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
if (!response.ok) throw new Error(data.error || response.statusText);
|
|
82
|
+
return data;
|
|
83
|
+
} catch (err) {
|
|
84
|
+
throw new Error(`Vaultix API Error: ${err.message}`);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
31
88
|
if (command === 'get') {
|
|
32
89
|
if (!target) {
|
|
33
|
-
console.error('\x1b[31m[Error]\x1b[0m
|
|
90
|
+
console.error('\x1b[31m[Error]\x1b[0m Missing secret name.');
|
|
34
91
|
process.exit(1);
|
|
35
92
|
}
|
|
36
93
|
|
|
37
94
|
try {
|
|
38
|
-
const
|
|
39
|
-
console.log(value);
|
|
95
|
+
const data = await callApi(`/api/v1/secrets/${encodeURIComponent(target)}`);
|
|
96
|
+
console.log(data.value);
|
|
40
97
|
} catch (err) {
|
|
41
98
|
console.error(`\x1b[31m[Error]\x1b[0m ${err.message}`);
|
|
42
99
|
process.exit(1);
|
|
43
100
|
}
|
|
44
101
|
} else if (command === 'list') {
|
|
45
102
|
try {
|
|
46
|
-
const
|
|
103
|
+
const data = await callApi('/api/v1/secrets');
|
|
47
104
|
console.log('\x1b[36m--- Active Secrets ---\x1b[0m');
|
|
48
|
-
secrets.forEach(s => {
|
|
105
|
+
data.secrets.forEach(s => {
|
|
49
106
|
console.log(`\x1b[32m${s.name}\x1b[0m (Service: ${s.service})`);
|
|
50
107
|
});
|
|
51
108
|
} catch (err) {
|
|
@@ -55,12 +112,12 @@ Make sure VAULTIX_API_KEY environment variable is set.
|
|
|
55
112
|
} else if (command === 'set') {
|
|
56
113
|
const value = args[2];
|
|
57
114
|
if (!target || !value) {
|
|
58
|
-
console.error('\x1b[31m[Error]\x1b[0m
|
|
115
|
+
console.error('\x1b[31m[Error]\x1b[0m Usage: vaultix set <NAME> <VALUE>');
|
|
59
116
|
process.exit(1);
|
|
60
117
|
}
|
|
61
118
|
|
|
62
119
|
try {
|
|
63
|
-
await
|
|
120
|
+
await callApi(`/api/v1/secrets/${encodeURIComponent(target)}`, 'PUT', { value });
|
|
64
121
|
console.log(`\x1b[32m[Success]\x1b[0m Secret '${target}' configured successfully.`);
|
|
65
122
|
} catch (err) {
|
|
66
123
|
console.error(`\x1b[31m[Error]\x1b[0m ${err.message}`);
|
|
@@ -68,12 +125,12 @@ Make sure VAULTIX_API_KEY environment variable is set.
|
|
|
68
125
|
}
|
|
69
126
|
} else if (command === 'delete') {
|
|
70
127
|
if (!target) {
|
|
71
|
-
console.error('\x1b[31m[Error]\x1b[0m
|
|
128
|
+
console.error('\x1b[31m[Error]\x1b[0m Missing secret name.');
|
|
72
129
|
process.exit(1);
|
|
73
130
|
}
|
|
74
131
|
|
|
75
132
|
try {
|
|
76
|
-
await
|
|
133
|
+
await callApi(`/api/v1/secrets/${encodeURIComponent(target)}`, 'DELETE');
|
|
77
134
|
console.log(`\x1b[32m[Success]\x1b[0m Secret '${target}' deleted successfully.`);
|
|
78
135
|
} catch (err) {
|
|
79
136
|
console.error(`\x1b[31m[Error]\x1b[0m ${err.message}`);
|