@principle2026/vault 1.0.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/README.md +117 -0
- package/SKILL.md +117 -0
- package/dist/CLI.d.ts +58 -0
- package/dist/CLI.d.ts.map +1 -0
- package/dist/CLI.js +180 -0
- package/dist/CLI.js.map +1 -0
- package/dist/Crypto.d.ts +43 -0
- package/dist/Crypto.d.ts.map +1 -0
- package/dist/Crypto.js +136 -0
- package/dist/Crypto.js.map +1 -0
- package/dist/Keychain.d.ts +30 -0
- package/dist/Keychain.d.ts.map +1 -0
- package/dist/Keychain.js +53 -0
- package/dist/Keychain.js.map +1 -0
- package/dist/Store.d.ts +47 -0
- package/dist/Store.d.ts.map +1 -0
- package/dist/Store.js +103 -0
- package/dist/Store.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +342 -0
- package/dist/index.js.map +1 -0
- package/dist/tools.d.ts +65 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +252 -0
- package/dist/tools.js.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Vault â AI-Powered Secret Management
|
|
2
|
+
|
|
3
|
+
A Claude Code plugin that enables AI to automatically manage your secrets and sensitive information.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- đŁïž **Conversational** â Save and retrieve secrets using natural language
|
|
8
|
+
- đ **End-to-end encryption** â AES-256-GCM encryption
|
|
9
|
+
- âïž **iCloud sync** â Automatically sync across all your devices
|
|
10
|
+
- đ **Keychain integration** â Secure master key storage
|
|
11
|
+
- ⥠**Zero config** â Ready to use after initialization
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### æčćŒ 1: npm ć
šć±ćźèŁ
ïŒæšèïŒ
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @principle2026/vault
|
|
19
|
+
vault init
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### æčćŒ 2: æŹć°ćŒć
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git clone <repository>
|
|
26
|
+
cd Vault
|
|
27
|
+
npm install
|
|
28
|
+
npm run build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Initialize
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
vault init
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Follow the interactive prompts to set up your master passphrase.
|
|
40
|
+
|
|
41
|
+
### Save a secret
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
echo "sk-abc123" | vault set openai_key --description "OpenAI API Key"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Get a secret
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
vault get openai_key
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### List secrets
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
vault list
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Delete a secret
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
vault delete openai_key
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Check status
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
vault status
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## AI Conversation Usage
|
|
72
|
+
|
|
73
|
+
In Claude Code, use natural language:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
You: Remember my OpenAI key is sk-abc123
|
|
77
|
+
AI: [auto-save] Saved: openai_key
|
|
78
|
+
|
|
79
|
+
You: Use that key to call the API
|
|
80
|
+
AI: [auto-retrieve] Using sk-abc123...
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Security Design
|
|
84
|
+
|
|
85
|
+
- **Algorithm**: AES-256-GCM
|
|
86
|
+
- **Key derivation**: PBKDF2 (100,000 iterations)
|
|
87
|
+
- **Storage**: iCloud or local `~/.vault-data/`
|
|
88
|
+
- **Master key**: System keychain (unlocked by passphrase)
|
|
89
|
+
|
|
90
|
+
## Project Structure
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
src/
|
|
94
|
+
âââ Crypto.ts # Encryption/decryption
|
|
95
|
+
âââ Keychain.ts # Keychain operations
|
|
96
|
+
âââ Store.ts # Data storage
|
|
97
|
+
âââ tools.ts # Core functions
|
|
98
|
+
âââ index.ts # CLI entry point
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Development
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Build
|
|
105
|
+
npm run build
|
|
106
|
+
|
|
107
|
+
# Watch mode
|
|
108
|
+
npm run dev
|
|
109
|
+
|
|
110
|
+
# Run CLI
|
|
111
|
+
./dist/index.js status
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Dependencies
|
|
115
|
+
|
|
116
|
+
- `keytar` â Keychain access
|
|
117
|
+
- Web Crypto API â Encryption operations
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vault
|
|
3
|
+
description: |
|
|
4
|
+
AI-powered secret management. Automatically save and retrieve API keys, passwords, and other sensitive information.
|
|
5
|
+
|
|
6
|
+
When users say "remember", "save", or "store", AI will automatically save secrets.
|
|
7
|
+
When users say "my key", "that password", AI will automatically retrieve secrets.
|
|
8
|
+
|
|
9
|
+
After initialization, AI will securely manage your sensitive information in the background.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Vault â AI Secret Management
|
|
13
|
+
|
|
14
|
+
Vault is a Claude Code skill that enables AI to automatically manage your secrets and sensitive information.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
Consider secret operations when users say:
|
|
19
|
+
|
|
20
|
+
**Save secrets:**
|
|
21
|
+
- "Remember my OpenAI key is sk-xxx"
|
|
22
|
+
- "Save this password"
|
|
23
|
+
- "AWS secret key is xxxxx, store it"
|
|
24
|
+
|
|
25
|
+
**Retrieve secrets:**
|
|
26
|
+
- "Use that key to call the API"
|
|
27
|
+
- "What's my password"
|
|
28
|
+
- "Read the saved AWS key"
|
|
29
|
+
|
|
30
|
+
**List secrets:**
|
|
31
|
+
- "What secrets have I saved"
|
|
32
|
+
- "List all secrets"
|
|
33
|
+
|
|
34
|
+
## Steps
|
|
35
|
+
|
|
36
|
+
### 0. Check if Vault is initialized
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
vault status
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If it shows `Initialized: no`, prompt the user:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Vault is not initialized. Please run:
|
|
46
|
+
vault init <username>
|
|
47
|
+
|
|
48
|
+
Then set a passphrase (at least 8 characters).
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 1. Save a secret (set_secret)
|
|
52
|
+
|
|
53
|
+
When the user wants to save a secret, use bash command:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
echo "<secret-value>" | vault set <key-name> --description "<description>"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
```bash
|
|
61
|
+
echo "sk-abc123" | vault set openai_key --description "OpenAI API Key"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Important**: Never pass secret values directly in command history. Use echo pipe.
|
|
65
|
+
|
|
66
|
+
### 2. Get a secret (get_secret)
|
|
67
|
+
|
|
68
|
+
When the user wants to retrieve a secret, use bash command:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
vault get <key-name>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This will prompt for passphrase, then output the secret value.
|
|
75
|
+
|
|
76
|
+
### 3. List secrets (list_secrets)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
vault list
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Shows all saved secret names (without values).
|
|
83
|
+
|
|
84
|
+
## Security Notes
|
|
85
|
+
|
|
86
|
+
- Passphrase must be at least 8 characters
|
|
87
|
+
- Secrets are encrypted using AES-256-GCM
|
|
88
|
+
- Encrypted data is stored in iCloud (if available) or locally
|
|
89
|
+
- Master key is stored in system keychain
|
|
90
|
+
|
|
91
|
+
## Error Handling
|
|
92
|
+
|
|
93
|
+
| Error | Cause | Solution |
|
|
94
|
+
|-------|-------|----------|
|
|
95
|
+
| `Vault is not initialized` | First time use | Run `vault init <username>` |
|
|
96
|
+
| `Passphrase incorrect` | Wrong password | Re-enter correct passphrase |
|
|
97
|
+
| `Secret "xxx" not found` | Secret not found | Check name or use `vault list` |
|
|
98
|
+
| `Key name cannot be empty` | Validation failed | Provide valid key name |
|
|
99
|
+
|
|
100
|
+
## Storage Locations
|
|
101
|
+
|
|
102
|
+
- **iCloud**: `~/Library/Mobile Documents/com~apple~CloudDocs/.vault-data/`
|
|
103
|
+
- **Local fallback**: `~/.vault-data/`
|
|
104
|
+
- **Keychain**: service=`vault-skill`, account=`master-key`
|
|
105
|
+
|
|
106
|
+
## Example Conversations
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
User: Remember my OpenAI key is sk-abc123
|
|
110
|
+
AI: I'll save this secret...
|
|
111
|
+
[run: echo "sk-abc123" | vault set openai_key --description "OpenAI API Key"]
|
|
112
|
+
Saved: openai_key
|
|
113
|
+
|
|
114
|
+
User: Use that key to call the OpenAI API
|
|
115
|
+
AI: [run: vault get openai_key]
|
|
116
|
+
Using sk-abc123 to call the API...
|
|
117
|
+
```
|
package/dist/CLI.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI - Interactive command line interface
|
|
3
|
+
*
|
|
4
|
+
* Handles user input, password prompts, and interactive flows
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Ask a question and get answer
|
|
8
|
+
*/
|
|
9
|
+
export declare function question(prompt: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Ask for password with hidden input
|
|
12
|
+
*/
|
|
13
|
+
export declare function password(prompt?: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Show welcome banner
|
|
16
|
+
*/
|
|
17
|
+
export declare function showWelcome(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Show first-time setup welcome
|
|
20
|
+
*/
|
|
21
|
+
export declare function showSetupWelcome(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Confirm action
|
|
24
|
+
*/
|
|
25
|
+
export declare function confirm(prompt: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Show success message
|
|
28
|
+
*/
|
|
29
|
+
export declare function success(message: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Show error message
|
|
32
|
+
*/
|
|
33
|
+
export declare function error(message: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Show info message
|
|
36
|
+
*/
|
|
37
|
+
export declare function info(message: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check if initialized, show welcome if first time
|
|
40
|
+
*/
|
|
41
|
+
export declare function checkInitialized(): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Run interactive setup
|
|
44
|
+
*/
|
|
45
|
+
export declare function runSetup(): Promise<{
|
|
46
|
+
username: string;
|
|
47
|
+
passphrase: string;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* Show Vault status summary
|
|
51
|
+
*/
|
|
52
|
+
export declare function showStatusSummary(status: {
|
|
53
|
+
initialized: boolean;
|
|
54
|
+
userId?: string;
|
|
55
|
+
storageType: string;
|
|
56
|
+
secretCount: number;
|
|
57
|
+
}): void;
|
|
58
|
+
//# sourceMappingURL=CLI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxD;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,SAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwDvE;AAED;;GAEG;AACH,wBAAgB,WAAW,SAK1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,SAW/B;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,QAEtC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,QAEpC;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,QAEnC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAQzD;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAC,CAkCD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,WAAW,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,QASA"}
|
package/dist/CLI.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI - Interactive command line interface
|
|
3
|
+
*
|
|
4
|
+
* Handles user input, password prompts, and interactive flows
|
|
5
|
+
*/
|
|
6
|
+
import { createInterface } from 'readline';
|
|
7
|
+
import { getVaultStatus } from './tools.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create readline interface
|
|
10
|
+
*/
|
|
11
|
+
function createRL() {
|
|
12
|
+
return createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Ask a question and get answer
|
|
19
|
+
*/
|
|
20
|
+
export function question(prompt) {
|
|
21
|
+
const rl = createRL();
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
rl.question(prompt, (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim());
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Ask for password with hidden input
|
|
31
|
+
*/
|
|
32
|
+
export async function password(prompt = 'Passphrase: ') {
|
|
33
|
+
const rl = createRL();
|
|
34
|
+
// Hide output
|
|
35
|
+
const stdin = process.stdin;
|
|
36
|
+
const stdout = process.stdout;
|
|
37
|
+
stdin.setRawMode(true);
|
|
38
|
+
stdin.resume();
|
|
39
|
+
stdin.setEncoding('utf8');
|
|
40
|
+
stdout.write(prompt);
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
let password = '';
|
|
43
|
+
const onData = (char) => {
|
|
44
|
+
const charCode = char.charCodeAt(0);
|
|
45
|
+
// Enter = 13, Ctrl+D = 4
|
|
46
|
+
if (charCode === 13 || charCode === 4) {
|
|
47
|
+
stdin.pause();
|
|
48
|
+
stdin.removeListener('data', onData);
|
|
49
|
+
stdin.setRawMode(false);
|
|
50
|
+
stdout.write('\n');
|
|
51
|
+
rl.close();
|
|
52
|
+
resolve(password);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Backspace = 127, Ctrl+H = 8
|
|
56
|
+
if (charCode === 127 || charCode === 8) {
|
|
57
|
+
if (password.length > 0) {
|
|
58
|
+
password = password.slice(0, -1);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Ctrl+C = 3
|
|
63
|
+
if (charCode === 3) {
|
|
64
|
+
stdin.pause();
|
|
65
|
+
stdin.removeListener('data', onData);
|
|
66
|
+
stdin.setRawMode(false);
|
|
67
|
+
stdout.write('^C\n');
|
|
68
|
+
rl.close();
|
|
69
|
+
process.exit(1);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Regular character
|
|
73
|
+
password += char;
|
|
74
|
+
};
|
|
75
|
+
stdin.on('data', onData);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Show welcome banner
|
|
80
|
+
*/
|
|
81
|
+
export function showWelcome() {
|
|
82
|
+
console.log(`
|
|
83
|
+
đ Vault - AI-Powered Secret Management
|
|
84
|
+
ââââââââââââââââââââââââââââââââââââââââââ
|
|
85
|
+
`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Show first-time setup welcome
|
|
89
|
+
*/
|
|
90
|
+
export function showSetupWelcome() {
|
|
91
|
+
console.log(`
|
|
92
|
+
đ Welcome to Vault!
|
|
93
|
+
|
|
94
|
+
This is your first time using Vault. Let's get you set up.
|
|
95
|
+
|
|
96
|
+
Vault will store your secrets securely using AES-256 encryption.
|
|
97
|
+
Your data is stored locally (or synced via iCloud on macOS).
|
|
98
|
+
|
|
99
|
+
You'll need to set a master passphrase to protect your secrets.
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Confirm action
|
|
104
|
+
*/
|
|
105
|
+
export async function confirm(prompt) {
|
|
106
|
+
const answer = await question(`${prompt} (y/N): `);
|
|
107
|
+
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Show success message
|
|
111
|
+
*/
|
|
112
|
+
export function success(message) {
|
|
113
|
+
console.log(`â
${message}`);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Show error message
|
|
117
|
+
*/
|
|
118
|
+
export function error(message) {
|
|
119
|
+
console.error(`â ${message}`);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Show info message
|
|
123
|
+
*/
|
|
124
|
+
export function info(message) {
|
|
125
|
+
console.log(`âčïž ${message}`);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check if initialized, show welcome if first time
|
|
129
|
+
*/
|
|
130
|
+
export async function checkInitialized() {
|
|
131
|
+
const status = await getVaultStatus();
|
|
132
|
+
if (!status.initialized) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Run interactive setup
|
|
139
|
+
*/
|
|
140
|
+
export async function runSetup() {
|
|
141
|
+
showSetupWelcome();
|
|
142
|
+
// Get system username
|
|
143
|
+
const os = await import('os');
|
|
144
|
+
const defaultUsername = os.userInfo().username;
|
|
145
|
+
// Ask for username (with default)
|
|
146
|
+
const username = await question(`Username [${defaultUsername}]: `);
|
|
147
|
+
const finalUsername = username || defaultUsername;
|
|
148
|
+
console.log('');
|
|
149
|
+
// Ask for passphrase
|
|
150
|
+
while (true) {
|
|
151
|
+
const passphrase1 = await password('Set a master passphrase (min 8 characters): ');
|
|
152
|
+
if (passphrase1.length < 8) {
|
|
153
|
+
error('Passphrase must be at least 8 characters. Please try again.');
|
|
154
|
+
console.log('');
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const passphrase2 = await password('Confirm passphrase: ');
|
|
158
|
+
if (passphrase1 !== passphrase2) {
|
|
159
|
+
error('Passphrases do not match. Please try again.');
|
|
160
|
+
console.log('');
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
console.log('');
|
|
164
|
+
return { username: finalUsername, passphrase: passphrase1 };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Show Vault status summary
|
|
169
|
+
*/
|
|
170
|
+
export function showStatusSummary(status) {
|
|
171
|
+
console.log(`
|
|
172
|
+
đ Vault Status
|
|
173
|
+
ââââââââââââââââââââââââââââââââââââââââââ
|
|
174
|
+
Initialized: ${status.initialized ? 'â
Yes' : 'â No'}
|
|
175
|
+
Storage: ${status.storageType}
|
|
176
|
+
${status.userId ? ` User: ${status.userId}` : ''}
|
|
177
|
+
Secrets: ${status.secretCount}
|
|
178
|
+
`);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=CLI.js.map
|
package/dist/CLI.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.js","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"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"}
|
package/dist/Crypto.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto - AES-256-GCM encryption/decryption
|
|
3
|
+
*
|
|
4
|
+
* Uses Web Crypto API for encryption operations
|
|
5
|
+
*/
|
|
6
|
+
export interface EncryptedData {
|
|
7
|
+
iv: string;
|
|
8
|
+
ciphertext: string;
|
|
9
|
+
authTag: string;
|
|
10
|
+
}
|
|
11
|
+
export interface EncryptionResult {
|
|
12
|
+
encrypted: EncryptedData;
|
|
13
|
+
salt: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Derive encryption key from passphrase
|
|
17
|
+
*/
|
|
18
|
+
export declare function deriveKey(passphrase: string, salt: Uint8Array): Promise<CryptoKey>;
|
|
19
|
+
/**
|
|
20
|
+
* Encrypt data
|
|
21
|
+
*/
|
|
22
|
+
export declare function encrypt(plaintext: string, passphrase: string): Promise<EncryptionResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Decrypt data
|
|
25
|
+
*/
|
|
26
|
+
export declare function decrypt(encrypted: EncryptedData, salt: string, passphrase: string): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Vault error class
|
|
29
|
+
*/
|
|
30
|
+
export declare class VaultError extends Error {
|
|
31
|
+
code: string;
|
|
32
|
+
cause?: Error | undefined;
|
|
33
|
+
constructor(code: string, message: string, cause?: Error | undefined);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate passphrase format
|
|
37
|
+
*/
|
|
38
|
+
export declare function validatePassphrase(passphrase: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Generate random salt
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateSalt(): string;
|
|
43
|
+
//# sourceMappingURL=Crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,aAAa,CAAA;IACxB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,SAAS,CAAC,CAwBpB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CA+B3B;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,aAAa,EACxB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAE1B,IAAI,EAAE,MAAM;IAEZ,KAAK,CAAC,EAAE,KAAK;gBAFb,IAAI,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACR,KAAK,CAAC,EAAE,KAAK,YAAA;CAKvB;AAoCD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAO3D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
|
package/dist/Crypto.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto - AES-256-GCM encryption/decryption
|
|
3
|
+
*
|
|
4
|
+
* Uses Web Crypto API for encryption operations
|
|
5
|
+
*/
|
|
6
|
+
const ENCRYPTION_ALGO = 'AES-GCM';
|
|
7
|
+
const KEY_LENGTH = 256;
|
|
8
|
+
const IV_LENGTH = 12;
|
|
9
|
+
const SALT_LENGTH = 16;
|
|
10
|
+
const ITERATIONS = 100000;
|
|
11
|
+
/**
|
|
12
|
+
* Derive encryption key from passphrase
|
|
13
|
+
*/
|
|
14
|
+
export async function deriveKey(passphrase, salt) {
|
|
15
|
+
const encoder = new TextEncoder();
|
|
16
|
+
const passphraseBuffer = encoder.encode(passphrase);
|
|
17
|
+
const baseKey = await crypto.subtle.importKey('raw', passphraseBuffer, 'PBKDF2', false, ['deriveKey']);
|
|
18
|
+
return crypto.subtle.deriveKey({
|
|
19
|
+
name: 'PBKDF2',
|
|
20
|
+
salt: salt,
|
|
21
|
+
iterations: ITERATIONS,
|
|
22
|
+
hash: 'SHA-256',
|
|
23
|
+
}, baseKey, { name: ENCRYPTION_ALGO, length: KEY_LENGTH }, false, ['encrypt', 'decrypt']);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Encrypt data
|
|
27
|
+
*/
|
|
28
|
+
export async function encrypt(plaintext, passphrase) {
|
|
29
|
+
// Generate random salt and IV
|
|
30
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
|
|
31
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
|
|
32
|
+
// Derive key
|
|
33
|
+
const key = await deriveKey(passphrase, salt);
|
|
34
|
+
// Encrypt
|
|
35
|
+
const encoder = new TextEncoder();
|
|
36
|
+
const plaintextBuffer = encoder.encode(plaintext);
|
|
37
|
+
const ciphertext = await crypto.subtle.encrypt({ name: ENCRYPTION_ALGO, iv }, key, plaintextBuffer);
|
|
38
|
+
// Extract auth tag (GCM mode: last 16 bytes is the tag)
|
|
39
|
+
const ciphertextArray = new Uint8Array(ciphertext);
|
|
40
|
+
const authTag = ciphertextArray.slice(-16);
|
|
41
|
+
const actualCiphertext = ciphertextArray.slice(0, -16);
|
|
42
|
+
return {
|
|
43
|
+
encrypted: {
|
|
44
|
+
iv: bufferToHex(iv),
|
|
45
|
+
ciphertext: bufferToBase64(actualCiphertext),
|
|
46
|
+
authTag: bufferToHex(authTag),
|
|
47
|
+
},
|
|
48
|
+
salt: bufferToHex(salt),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decrypt data
|
|
53
|
+
*/
|
|
54
|
+
export async function decrypt(encrypted, salt, passphrase) {
|
|
55
|
+
try {
|
|
56
|
+
// Parse input
|
|
57
|
+
const iv = hexToBuffer(encrypted.iv);
|
|
58
|
+
const authTag = hexToBuffer(encrypted.authTag);
|
|
59
|
+
const ciphertext = base64ToBuffer(encrypted.ciphertext);
|
|
60
|
+
const saltBuffer = hexToBuffer(salt);
|
|
61
|
+
// Derive key
|
|
62
|
+
const key = await deriveKey(passphrase, saltBuffer);
|
|
63
|
+
// Reconstruct ciphertext (actual ciphertext + auth tag)
|
|
64
|
+
const combined = new Uint8Array(ciphertext.length + authTag.length);
|
|
65
|
+
combined.set(ciphertext);
|
|
66
|
+
combined.set(authTag, ciphertext.length);
|
|
67
|
+
// Decrypt
|
|
68
|
+
const decrypted = await crypto.subtle.decrypt({ name: ENCRYPTION_ALGO, iv }, key, combined);
|
|
69
|
+
const decoder = new TextDecoder();
|
|
70
|
+
return decoder.decode(decrypted);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
// Distinguish error types
|
|
74
|
+
if (error instanceof DOMException) {
|
|
75
|
+
if (error.name === 'OperationError') {
|
|
76
|
+
throw new VaultError('DECRYPTION_FAILED', 'Decryption failed: incorrect passphrase or corrupted data');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Vault error class
|
|
84
|
+
*/
|
|
85
|
+
export class VaultError extends Error {
|
|
86
|
+
code;
|
|
87
|
+
cause;
|
|
88
|
+
constructor(code, message, cause) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.code = code;
|
|
91
|
+
this.cause = cause;
|
|
92
|
+
this.name = 'VaultError';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Utility functions
|
|
97
|
+
// ============================================================================
|
|
98
|
+
function bufferToHex(buffer) {
|
|
99
|
+
return Array.from(buffer)
|
|
100
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
101
|
+
.join('');
|
|
102
|
+
}
|
|
103
|
+
function hexToBuffer(hex) {
|
|
104
|
+
const cleanHex = hex.replace(/[^0-9a-fA-F]/g, '');
|
|
105
|
+
if (cleanHex.length % 2 !== 0) {
|
|
106
|
+
throw new VaultError('INVALID_HEX', 'Invalid hex string');
|
|
107
|
+
}
|
|
108
|
+
const pairs = cleanHex.match(/.{1,2}/g) || [];
|
|
109
|
+
return new Uint8Array(pairs.map(p => parseInt(p, 16)));
|
|
110
|
+
}
|
|
111
|
+
function bufferToBase64(buffer) {
|
|
112
|
+
const binary = Array.from(buffer)
|
|
113
|
+
.map(b => String.fromCharCode(b))
|
|
114
|
+
.join('');
|
|
115
|
+
return btoa(binary);
|
|
116
|
+
}
|
|
117
|
+
function base64ToBuffer(base64) {
|
|
118
|
+
const binary = atob(base64);
|
|
119
|
+
return new Uint8Array(Array.from(binary).map(c => c.charCodeAt(0)));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validate passphrase format
|
|
123
|
+
*/
|
|
124
|
+
export function validatePassphrase(passphrase) {
|
|
125
|
+
if (!passphrase || passphrase.length < 8) {
|
|
126
|
+
throw new VaultError('INVALID_PASSPHRASE', 'Passphrase must be at least 8 characters');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Generate random salt
|
|
131
|
+
*/
|
|
132
|
+
export function generateSalt() {
|
|
133
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
|
|
134
|
+
return bufferToHex(salt);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=Crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crypto.js","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"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"}
|