aivault-mcp 0.1.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/LICENSE +21 -0
- package/README.md +172 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +111 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +2 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +155 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +2 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +28 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/export.d.ts +2 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +27 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +32 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +22 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/set.d.ts +2 -0
- package/dist/cli/commands/set.d.ts.map +1 -0
- package/dist/cli/commands/set.js +31 -0
- package/dist/cli/commands/set.js.map +1 -0
- package/dist/cli/utils.d.ts +4 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +57 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/executor/parser.d.ts +6 -0
- package/dist/executor/parser.d.ts.map +1 -0
- package/dist/executor/parser.js +17 -0
- package/dist/executor/parser.js.map +1 -0
- package/dist/executor/runner.d.ts +17 -0
- package/dist/executor/runner.d.ts.map +1 -0
- package/dist/executor/runner.js +63 -0
- package/dist/executor/runner.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/scrubber/scrubber.d.ts +7 -0
- package/dist/scrubber/scrubber.d.ts.map +1 -0
- package/dist/scrubber/scrubber.js +40 -0
- package/dist/scrubber/scrubber.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +87 -0
- package/dist/server.js.map +1 -0
- package/dist/vault/crypto.d.ts +4 -0
- package/dist/vault/crypto.d.ts.map +1 -0
- package/dist/vault/crypto.js +44 -0
- package/dist/vault/crypto.js.map +1 -0
- package/dist/vault/store.d.ts +19 -0
- package/dist/vault/store.d.ts.map +1 -0
- package/dist/vault/store.js +118 -0
- package/dist/vault/store.js.map +1 -0
- package/dist/vault/types.d.ts +25 -0
- package/dist/vault/types.d.ts.map +1 -0
- package/dist/vault/types.js +9 -0
- package/dist/vault/types.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mohammed Shomis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# š AIVault
|
|
2
|
+
|
|
3
|
+
**Stop pasting API keys into AI chat.**
|
|
4
|
+
|
|
5
|
+
AIVault is an [MCP server](https://modelcontextprotocol.io) that lets AI agents use your credentials **without ever seeing them**. The AI references secrets by name (`$GITHUB_TOKEN`), AIVault injects the real values at runtime, and scrubs them from the output before the AI sees anything.
|
|
6
|
+
|
|
7
|
+
Works with **Claude Desktop**, **Kiro**, **Cursor**, **Windsurf**, and any MCP-compatible client.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## The Problem
|
|
12
|
+
|
|
13
|
+
Every day, developers paste API keys, database passwords, and tokens directly into AI chat. This is a massive security risk ā those secrets end up in logs, training data, and who knows where else.
|
|
14
|
+
|
|
15
|
+
## The Solution
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
You: "Deploy my app to AWS"
|
|
19
|
+
AI: calls run_command ā "aws s3 cp ./build s3://my-bucket"
|
|
20
|
+
AIVault: ā
Injects $AWS_ACCESS_KEY_ID and $AWS_SECRET_ACCESS_KEY as env vars
|
|
21
|
+
ā
Runs the command
|
|
22
|
+
ā
Scrubs any leaked secrets from output
|
|
23
|
+
ā
Returns clean result to AI
|
|
24
|
+
AI: "Done! All files uploaded to S3."
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The AI never sees your actual credentials. Ever.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g aivault-mcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Initialize your vault
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
aivault init
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Add your secrets
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
aivault set GITHUB_TOKEN --desc "GitHub PAT for repo access" --tags "github"
|
|
49
|
+
aivault set AWS_ACCESS_KEY_ID --desc "AWS access key" --tags "aws"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 4. Connect to your AI tool
|
|
53
|
+
|
|
54
|
+
Add to your MCP config:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"aivault": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "aivault-mcp"],
|
|
62
|
+
"env": {
|
|
63
|
+
"AIVAULT_MASTER_PASSWORD": "your-master-password"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
| AI Tool | Config File Location |
|
|
72
|
+
|---------|---------------------|
|
|
73
|
+
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |
|
|
74
|
+
| Kiro | `~/.kiro/settings/mcp.json` |
|
|
75
|
+
| Cursor | `.cursor/mcp.json` in your project |
|
|
76
|
+
| Windsurf | `~/.windsurf/mcp.json` |
|
|
77
|
+
|
|
78
|
+
### 5. Done! Ask your AI to use your secrets
|
|
79
|
+
|
|
80
|
+
> "Check how many users are in my database"
|
|
81
|
+
|
|
82
|
+
The AI will call `list_secrets`, find your `DB_URL`, run the query with `run_command`, and return scrubbed results.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Web Dashboard
|
|
87
|
+
|
|
88
|
+
Manage secrets visually instead of the CLI:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
aivault dashboard
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Opens a local web UI at `http://localhost:7470` where you can add, view, and delete secrets from your browser.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## How It Works
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
User āā AI (Claude, Kiro, Cursor, etc.)
|
|
102
|
+
ā
|
|
103
|
+
MCP Protocol
|
|
104
|
+
ā
|
|
105
|
+
āāāāāāāāāāāāāāāāāāā
|
|
106
|
+
ā AIVault MCP ā
|
|
107
|
+
ā ā
|
|
108
|
+
ā Secret Store ā ā AES-256-GCM encrypted local file
|
|
109
|
+
ā Executor ā ā Injects secrets as env vars
|
|
110
|
+
ā Scrubber ā ā Removes secret values from output
|
|
111
|
+
āāāāāāāāāāāāāāāāāāā
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### MCP Tools
|
|
115
|
+
|
|
116
|
+
| Tool | What it does |
|
|
117
|
+
|------|-------------|
|
|
118
|
+
| `list_secrets` | Shows available secrets (name + description only, **never values**) |
|
|
119
|
+
| `run_command` | Runs a shell command with secrets injected as env vars, output scrubbed |
|
|
120
|
+
| `request_secret` | AI asks the user to add a missing secret |
|
|
121
|
+
|
|
122
|
+
### Security
|
|
123
|
+
|
|
124
|
+
- š **Encrypted at rest** ā AES-256-GCM with PBKDF2 key derivation (100k iterations, SHA-512)
|
|
125
|
+
- š« **AI never sees values** ā only names, descriptions, and tags
|
|
126
|
+
- š§¹ **Output always scrubbed** ā raw, URL-encoded, and Base64-encoded values are all caught
|
|
127
|
+
- š **Env var injection only** ā secrets are never interpolated into command strings (prevents shell injection)
|
|
128
|
+
- ā±ļø **Timeout enforcement** ā commands are killed after 30s (configurable, max 300s)
|
|
129
|
+
- š **100% local** ā no cloud, no network, no telemetry
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## CLI Reference
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
aivault init # Set up vault with master password
|
|
137
|
+
aivault set <NAME> --desc "..." [--tags "a,b"] # Add or update a secret
|
|
138
|
+
aivault list [--tag "..."] # List secrets (never shows values)
|
|
139
|
+
aivault delete <NAME> # Remove a secret
|
|
140
|
+
aivault dashboard # Open web UI
|
|
141
|
+
aivault export-descriptions [--json] # Export metadata for docs/sharing
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Set `AIVAULT_MASTER_PASSWORD` env var to skip password prompts.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Example Interactions
|
|
149
|
+
|
|
150
|
+
**Using a database:**
|
|
151
|
+
> You: "How many orders were placed today?"
|
|
152
|
+
> AI ā `run_command`: `psql $DB_URL -c "SELECT COUNT(*) FROM orders WHERE date = CURRENT_DATE"`
|
|
153
|
+
> Result: `count: 847` (connection string scrubbed)
|
|
154
|
+
|
|
155
|
+
**Deploying code:**
|
|
156
|
+
> You: "Push my Docker image to ECR"
|
|
157
|
+
> AI ā `run_command`: `aws ecr get-login-password | docker login ... && docker push`
|
|
158
|
+
> AWS credentials injected via env vars, never visible to AI
|
|
159
|
+
|
|
160
|
+
**Missing credential:**
|
|
161
|
+
> You: "Send a Slack notification"
|
|
162
|
+
> AI ā `request_secret`: "I need a SLACK_WEBHOOK_URL. Please run: `aivault set SLACK_WEBHOOK_URL --desc 'Slack webhook'`"
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
MIT
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
Built by [Mohammed Shomis](https://github.com/mohshomis) with ā¤ļø for developers who care about security.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli/cli.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const init_1 = require("./commands/init");
|
|
5
|
+
const set_1 = require("./commands/set");
|
|
6
|
+
const list_1 = require("./commands/list");
|
|
7
|
+
const delete_1 = require("./commands/delete");
|
|
8
|
+
const export_1 = require("./commands/export");
|
|
9
|
+
const dashboard_1 = require("./commands/dashboard");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
async function getPassword() {
|
|
12
|
+
const envPassword = process.env.AIVAULT_MASTER_PASSWORD;
|
|
13
|
+
if (envPassword)
|
|
14
|
+
return envPassword;
|
|
15
|
+
return (0, utils_1.promptHidden)('Master password: ');
|
|
16
|
+
}
|
|
17
|
+
function parseArgs(args) {
|
|
18
|
+
const command = args[0] || 'help';
|
|
19
|
+
const positional = [];
|
|
20
|
+
const flags = {};
|
|
21
|
+
for (let i = 1; i < args.length; i++) {
|
|
22
|
+
if (args[i].startsWith('--')) {
|
|
23
|
+
const key = args[i].slice(2);
|
|
24
|
+
const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[++i] : 'true';
|
|
25
|
+
flags[key] = value;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
positional.push(args[i]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { command, positional, flags };
|
|
32
|
+
}
|
|
33
|
+
function printHelp() {
|
|
34
|
+
console.log(`
|
|
35
|
+
AIVault ā Secure secret management for AI agents
|
|
36
|
+
|
|
37
|
+
Usage:
|
|
38
|
+
aivault init Initialize vault with master password
|
|
39
|
+
aivault set <NAME> --desc "description" [--tags "tag1,tag2"] Add or update a secret
|
|
40
|
+
aivault list [--tag "tag"] List secrets (names only, never values)
|
|
41
|
+
aivault delete <NAME> Delete a secret
|
|
42
|
+
aivault dashboard Open web UI to manage secrets
|
|
43
|
+
aivault export-descriptions [--json] [--tag "tag"] Export secret metadata
|
|
44
|
+
|
|
45
|
+
Environment:
|
|
46
|
+
AIVAULT_MASTER_PASSWORD Master password (avoids interactive prompt)
|
|
47
|
+
`);
|
|
48
|
+
}
|
|
49
|
+
async function main() {
|
|
50
|
+
const { command, positional, flags } = parseArgs(process.argv.slice(2));
|
|
51
|
+
switch (command) {
|
|
52
|
+
case 'init':
|
|
53
|
+
await (0, init_1.initCommand)();
|
|
54
|
+
break;
|
|
55
|
+
case 'set': {
|
|
56
|
+
const name = positional[0];
|
|
57
|
+
if (!name) {
|
|
58
|
+
console.error('Usage: aivault set <NAME> --desc "description" [--tags "tag1,tag2"]');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const desc = flags.desc || flags.description;
|
|
62
|
+
if (!desc) {
|
|
63
|
+
console.error('Error: --desc is required.');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const tags = flags.tags ? flags.tags.split(',').map(t => t.trim()) : [];
|
|
67
|
+
const password = await getPassword();
|
|
68
|
+
await (0, set_1.setCommand)(name, desc, tags, password);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'list': {
|
|
72
|
+
const password = await getPassword();
|
|
73
|
+
(0, list_1.listCommand)(flags.tag, password);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case 'delete': {
|
|
77
|
+
const name = positional[0];
|
|
78
|
+
if (!name) {
|
|
79
|
+
console.error('Usage: aivault delete <NAME>');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const password = await getPassword();
|
|
83
|
+
await (0, delete_1.deleteCommand)(name, password);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'export-descriptions': {
|
|
87
|
+
const password = await getPassword();
|
|
88
|
+
(0, export_1.exportCommand)(flags.json === 'true', flags.tag, password);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'dashboard': {
|
|
92
|
+
const password = await getPassword();
|
|
93
|
+
(0, dashboard_1.dashboardCommand)(password);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case 'help':
|
|
97
|
+
case '--help':
|
|
98
|
+
case '-h':
|
|
99
|
+
printHelp();
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
console.error(`Unknown command: ${command}`);
|
|
103
|
+
printHelp();
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
main().catch((err) => {
|
|
108
|
+
console.error('Fatal error:', err.message);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"AAwGA,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CA6DvD"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.dashboardCommand = dashboardCommand;
|
|
7
|
+
const http_1 = __importDefault(require("http"));
|
|
8
|
+
const store_1 = require("../../vault/store");
|
|
9
|
+
const PORT = 7470;
|
|
10
|
+
function html(store, message) {
|
|
11
|
+
let secrets = [];
|
|
12
|
+
try {
|
|
13
|
+
secrets = store.listSecrets();
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
const rows = secrets.map(s => `
|
|
17
|
+
<tr>
|
|
18
|
+
<td><code>${esc(s.name)}</code></td>
|
|
19
|
+
<td>${esc(s.description)}</td>
|
|
20
|
+
<td>${s.tags.map(t => `<span class="tag">${esc(t)}</span>`).join(' ')}</td>
|
|
21
|
+
<td>
|
|
22
|
+
<form method="POST" action="/delete" style="margin:0">
|
|
23
|
+
<input type="hidden" name="name" value="${esc(s.name)}">
|
|
24
|
+
<button type="submit" class="btn-delete" onclick="return confirm('Delete ${esc(s.name)}?')">Delete</button>
|
|
25
|
+
</form>
|
|
26
|
+
</td>
|
|
27
|
+
</tr>`).join('');
|
|
28
|
+
const banner = message ? `<div class="banner">${esc(message)}</div>` : '';
|
|
29
|
+
return `<!DOCTYPE html>
|
|
30
|
+
<html lang="en"><head>
|
|
31
|
+
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
32
|
+
<title>AIVault Dashboard</title>
|
|
33
|
+
<style>
|
|
34
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
35
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0d1117; color: #e6edf3; padding: 2rem; }
|
|
36
|
+
h1 { font-size: 1.6rem; margin-bottom: .3rem; }
|
|
37
|
+
.subtitle { color: #8b949e; margin-bottom: 1.5rem; font-size: .9rem; }
|
|
38
|
+
.banner { background: #1a7f37; color: #fff; padding: .6rem 1rem; border-radius: 6px; margin-bottom: 1rem; }
|
|
39
|
+
.card { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 1.5rem; margin-bottom: 1.5rem; }
|
|
40
|
+
table { width: 100%; border-collapse: collapse; }
|
|
41
|
+
th { text-align: left; color: #8b949e; font-size: .8rem; text-transform: uppercase; padding: .5rem .8rem; border-bottom: 1px solid #30363d; }
|
|
42
|
+
td { padding: .7rem .8rem; border-bottom: 1px solid #21262d; }
|
|
43
|
+
code { background: #1c2128; padding: .15rem .4rem; border-radius: 4px; font-size: .85rem; color: #79c0ff; }
|
|
44
|
+
.tag { background: #1f6feb33; color: #58a6ff; padding: .1rem .5rem; border-radius: 10px; font-size: .75rem; }
|
|
45
|
+
.empty { color: #8b949e; text-align: center; padding: 2rem; }
|
|
46
|
+
form.add { display: grid; grid-template-columns: 1fr 2fr 1fr 1fr auto; gap: .6rem; align-items: end; }
|
|
47
|
+
label { font-size: .8rem; color: #8b949e; display: block; margin-bottom: .2rem; }
|
|
48
|
+
input[type="text"], input[type="password"] { width: 100%; background: #0d1117; border: 1px solid #30363d; color: #e6edf3; padding: .5rem .7rem; border-radius: 6px; font-size: .85rem; }
|
|
49
|
+
input:focus { outline: none; border-color: #58a6ff; }
|
|
50
|
+
.btn { background: #238636; color: #fff; border: none; padding: .55rem 1.2rem; border-radius: 6px; cursor: pointer; font-size: .85rem; }
|
|
51
|
+
.btn:hover { background: #2ea043; }
|
|
52
|
+
.btn-delete { background: transparent; color: #f85149; border: 1px solid #f8514933; padding: .3rem .8rem; border-radius: 6px; cursor: pointer; font-size: .8rem; }
|
|
53
|
+
.btn-delete:hover { background: #f8514922; }
|
|
54
|
+
.count { color: #8b949e; font-size: .85rem; }
|
|
55
|
+
@media (max-width: 700px) { form.add { grid-template-columns: 1fr; } }
|
|
56
|
+
</style>
|
|
57
|
+
</head><body>
|
|
58
|
+
<h1>š AIVault Dashboard</h1>
|
|
59
|
+
<p class="subtitle">Manage your secrets securely. Values are never displayed.</p>
|
|
60
|
+
${banner}
|
|
61
|
+
|
|
62
|
+
<div class="card">
|
|
63
|
+
<h2 style="font-size:1rem;margin-bottom:1rem;">Add Secret</h2>
|
|
64
|
+
<form class="add" method="POST" action="/add">
|
|
65
|
+
<div><label>Name</label><input type="text" name="name" placeholder="GITHUB_TOKEN" required pattern="[A-Z][A-Z0-9_]*"></div>
|
|
66
|
+
<div><label>Description</label><input type="text" name="description" placeholder="GitHub PAT for repos" required></div>
|
|
67
|
+
<div><label>Value</label><input type="password" name="value" placeholder="ā¢ā¢ā¢ā¢ā¢ā¢ā¢ā¢" required></div>
|
|
68
|
+
<div><label>Tags (comma-separated)</label><input type="text" name="tags" placeholder="github, vcs"></div>
|
|
69
|
+
<div><label> </label><button type="submit" class="btn">Add</button></div>
|
|
70
|
+
</form>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="card">
|
|
74
|
+
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">
|
|
75
|
+
<h2 style="font-size:1rem;">Secrets</h2>
|
|
76
|
+
<span class="count">${secrets.length} secret${secrets.length !== 1 ? 's' : ''}</span>
|
|
77
|
+
</div>
|
|
78
|
+
${secrets.length === 0
|
|
79
|
+
? '<p class="empty">No secrets yet. Add one above.</p>'
|
|
80
|
+
: `<table><thead><tr><th>Name</th><th>Description</th><th>Tags</th><th></th></tr></thead><tbody>${rows}</tbody></table>`}
|
|
81
|
+
</div>
|
|
82
|
+
</body></html>`;
|
|
83
|
+
}
|
|
84
|
+
function esc(s) {
|
|
85
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
86
|
+
}
|
|
87
|
+
function parseBody(body) {
|
|
88
|
+
const params = {};
|
|
89
|
+
for (const pair of body.split('&')) {
|
|
90
|
+
const [key, ...rest] = pair.split('=');
|
|
91
|
+
params[decodeURIComponent(key)] = decodeURIComponent(rest.join('=').replace(/\+/g, ' '));
|
|
92
|
+
}
|
|
93
|
+
return params;
|
|
94
|
+
}
|
|
95
|
+
function readBody(req) {
|
|
96
|
+
return new Promise((resolve) => {
|
|
97
|
+
let data = '';
|
|
98
|
+
req.on('data', (chunk) => { data += chunk.toString(); });
|
|
99
|
+
req.on('end', () => resolve(data));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function dashboardCommand(password) {
|
|
103
|
+
const store = new store_1.VaultStore(password);
|
|
104
|
+
if (!store.isInitialized()) {
|
|
105
|
+
console.error('Vault not initialized. Run "aivault init" first.');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
const server = http_1.default.createServer(async (req, res) => {
|
|
109
|
+
const url = req.url || '/';
|
|
110
|
+
if (req.method === 'GET' && url === '/') {
|
|
111
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
112
|
+
res.end(html(store));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (req.method === 'POST' && url === '/add') {
|
|
116
|
+
const body = await readBody(req);
|
|
117
|
+
const params = parseBody(body);
|
|
118
|
+
const { name, description, value, tags } = params;
|
|
119
|
+
let msg;
|
|
120
|
+
try {
|
|
121
|
+
const tagList = tags ? tags.split(',').map(t => t.trim()).filter(Boolean) : [];
|
|
122
|
+
store.setSecret(name, value, description, tagList);
|
|
123
|
+
msg = `Secret ${name} saved`;
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
msg = `Error: ${err.message}`;
|
|
127
|
+
}
|
|
128
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
129
|
+
res.end(html(store, msg));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (req.method === 'POST' && url === '/delete') {
|
|
133
|
+
const body = await readBody(req);
|
|
134
|
+
const params = parseBody(body);
|
|
135
|
+
const { name } = params;
|
|
136
|
+
let msg;
|
|
137
|
+
if (store.deleteSecret(name)) {
|
|
138
|
+
msg = `Secret ${name} deleted`;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
msg = `Secret ${name} not found`;
|
|
142
|
+
}
|
|
143
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
144
|
+
res.end(html(store, msg));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
res.writeHead(404);
|
|
148
|
+
res.end('Not found');
|
|
149
|
+
});
|
|
150
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
151
|
+
console.log(`\nš AIVault Dashboard running at http://localhost:${PORT}\n`);
|
|
152
|
+
console.log('Press Ctrl+C to stop.\n');
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":";;;;;AAwGA,4CA6DC;AArKD,gDAAwB;AACxB,6CAA+C;AAE/C,MAAM,IAAI,GAAG,IAAI,CAAC;AAElB,SAAS,IAAI,CAAC,KAAiB,EAAE,OAAgB;IAC/C,IAAI,OAAO,GAAiE,EAAE,CAAC;IAC/E,IAAI,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC,CAAC,CAAC;IAEX,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;;kBAEd,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YACjB,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;YAClB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;oDAGvB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;qFACsB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;;;UAGtF,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEnB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,uBAAuB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1E,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+BL,MAAM;;;;;;;;;;;;;;;;4BAgBkB,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;;MAE7E,OAAO,CAAC,MAAM,KAAK,CAAC;QACpB,CAAC,CAAC,qDAAqD;QACvD,CAAC,CAAC,gGAAgG,IAAI,kBACxG;;eAEW,CAAC;AAChB,CAAC;AAED,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACtG,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAyB;IACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,IAAI,kBAAU,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,cAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAE3B,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YACxC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YAElD,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/E,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;gBACnD,GAAG,GAAG,UAAU,IAAI,QAAQ,CAAC;YAC/B,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,GAAG,GAAG,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC;YAChC,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YAExB,IAAI,GAAW,CAAC;YAChB,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,GAAG,GAAG,UAAU,IAAI,UAAU,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,UAAU,IAAI,YAAY,CAAC;YACnC,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,sDAAsD,IAAI,IAAI,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/delete.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBjF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteCommand = deleteCommand;
|
|
4
|
+
const store_1 = require("../../vault/store");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
async function deleteCommand(name, password) {
|
|
7
|
+
const store = new store_1.VaultStore(password);
|
|
8
|
+
const confirm = await (0, utils_1.promptConfirm)(`Are you sure you want to delete ${name}? (y/N): `);
|
|
9
|
+
if (!confirm) {
|
|
10
|
+
console.log('Aborted.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const deleted = store.deleteSecret(name);
|
|
15
|
+
if (deleted) {
|
|
16
|
+
console.log(`\nā Secret ${name} deleted`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.error(`Error: Secret ${name} not found.`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error(`Error: ${err.message}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/cli/commands/delete.ts"],"names":[],"mappings":";;AAGA,sCAqBC;AAxBD,6CAA+C;AAC/C,oCAAyC;AAElC,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,QAAgB;IAChE,MAAM,KAAK,GAAG,IAAI,kBAAU,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,IAAA,qBAAa,EAAC,mCAAmC,IAAI,WAAW,CAAC,CAAC;IACxF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,UAAU,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,aAAa,CAAC,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAoB5F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exportCommand = exportCommand;
|
|
4
|
+
const store_1 = require("../../vault/store");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
function exportCommand(json, tag, password) {
|
|
7
|
+
const store = new store_1.VaultStore(password);
|
|
8
|
+
try {
|
|
9
|
+
const secrets = store.listSecrets(tag);
|
|
10
|
+
if (json) {
|
|
11
|
+
console.log(JSON.stringify(secrets, null, 2));
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
if (secrets.length === 0) {
|
|
15
|
+
console.log('No secrets to export.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rows = secrets.map(s => [s.name, s.description, s.tags.join(', ')]);
|
|
19
|
+
console.log((0, utils_1.formatTable)(rows, ['NAME', 'DESCRIPTION', 'TAGS']));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.error(`Error: ${err.message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":";;AAGA,sCAoBC;AAvBD,6CAA+C;AAC/C,oCAAuC;AAEvC,SAAgB,aAAa,CAAC,IAAa,EAAE,GAAuB,EAAE,QAAgB;IACpF,MAAM,KAAK,GAAG,IAAI,kBAAU,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,IAAA,mBAAW,EAAC,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BjD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initCommand = initCommand;
|
|
4
|
+
const store_1 = require("../../vault/store");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
async function initCommand() {
|
|
7
|
+
console.log('Initializing AIVault...\n');
|
|
8
|
+
let password = process.env.AIVAULT_MASTER_PASSWORD;
|
|
9
|
+
if (!password) {
|
|
10
|
+
password = await (0, utils_1.promptHidden)('Set master password: ');
|
|
11
|
+
if (!password) {
|
|
12
|
+
console.error('Error: Password cannot be empty.');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const confirm = await (0, utils_1.promptHidden)('Confirm master password: ');
|
|
16
|
+
if (password !== confirm) {
|
|
17
|
+
console.error('Error: Passwords do not match.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const store = new store_1.VaultStore(password);
|
|
23
|
+
store.init();
|
|
24
|
+
console.log('\nā Vault initialized at ~/.aivault/');
|
|
25
|
+
console.log(' Use "aivault set <NAME> --desc <description>" to add secrets.');
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`Error: ${err.message}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":";;AAGA,kCA4BC;AA/BD,6CAA+C;AAC/C,oCAAwC;AAEjC,KAAK,UAAU,WAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEzC,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAEnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,MAAM,IAAA,oBAAY,EAAC,uBAAuB,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAY,EAAC,2BAA2B,CAAC,CAAC;QAChE,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,kBAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;IACjF,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAiB3E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listCommand = listCommand;
|
|
4
|
+
const store_1 = require("../../vault/store");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
function listCommand(tag, password) {
|
|
7
|
+
const store = new store_1.VaultStore(password);
|
|
8
|
+
try {
|
|
9
|
+
const secrets = store.listSecrets(tag);
|
|
10
|
+
if (secrets.length === 0) {
|
|
11
|
+
console.log(tag ? `No secrets found with tag "${tag}".` : 'No secrets in vault.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const rows = secrets.map(s => [s.name, s.description, s.tags.join(', ')]);
|
|
15
|
+
console.log((0, utils_1.formatTable)(rows, ['NAME', 'DESCRIPTION', 'TAGS']));
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error(`Error: ${err.message}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=list.js.map
|