@benzid.wael/secure-vault 0.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/LICENSE +21 -0
- package/README.md +268 -0
- package/bin/cli.js +83 -0
- package/bin/commands/env.js +807 -0
- package/package.json +167 -0
- package/src/electron/models/EnvironmentVault.js +251 -0
- package/src/electron/models/Vault.js +87 -0
- package/src/electron/services/CryptographyService.js +54 -0
- package/src/electron/services/EnvironmentVaultService.js +564 -0
- package/src/electron/services/ImportExportService.js +126 -0
- package/src/electron/services/MenuService.js +110 -0
- package/src/electron/services/SecurityManager.js +109 -0
- package/src/electron/services/VaultFileService.js +137 -0
- package/src/electron/services/VaultRecoveryService.js +134 -0
- package/src/electron/services/VaultService.js +578 -0
- package/src/electron/services/VaultSettingsService.js +78 -0
- package/src/electron/services/WindowManager.js +266 -0
- package/src/electron/services/recovery/IRecoveryMethod.js +88 -0
- package/src/electron/services/recovery/KeyRecoveryService.js +245 -0
- package/src/electron/services/recovery/PasswordRecoveryService.js +128 -0
- package/src/electron/services/recovery/SecretQuestionRecoveryService.js +267 -0
- package/src/electron/services/recovery/UsbRecoveryService.js +244 -0
- package/src/electron/utils/appPaths.js +50 -0
- package/src/electron/utils/passwordValidation.js +29 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wael BEN ZID EL GUEBSI
|
|
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,268 @@
|
|
|
1
|
+
# Secure Password Manager
|
|
2
|
+
|
|
3
|
+
A modern, secure password management application built with Electron and React, featuring strong encryption and a beautiful user interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **🔐 Strong Encryption**: All vaults are encrypted using AES-256-GCM with PBKDF2 key derivation
|
|
8
|
+
- **🏠 Multiple Vaults**: Create and manage multiple password vaults
|
|
9
|
+
- **🎨 Modern UI**: Beautiful dark theme with Material-UI components
|
|
10
|
+
- **🔒 Secure Storage**: Passwords are never stored in plain text
|
|
11
|
+
- **📱 Cross-Platform**: Works on Windows, macOS, and Linux
|
|
12
|
+
- **🔑 Password Generation**: Built-in secure password generator
|
|
13
|
+
- **📋 Copy to Clipboard**: Easy copying of usernames, passwords, and URLs
|
|
14
|
+
- **🔍 Search**: Quick search through your password entries
|
|
15
|
+
|
|
16
|
+
## Security Features
|
|
17
|
+
|
|
18
|
+
- **Zero-Knowledge Architecture**: Your master password is never stored
|
|
19
|
+
- **Strong Key Derivation**: PBKDF2 with 100,000 iterations
|
|
20
|
+
- **Authenticated Encryption**: AES-256-GCM prevents tampering
|
|
21
|
+
- **Secure Context**: Runs in isolated Electron context with CSP
|
|
22
|
+
- **Memory Protection**: Sensitive data cleared from memory when possible
|
|
23
|
+
|
|
24
|
+
## Download & Install
|
|
25
|
+
|
|
26
|
+
Grab the latest build for your platform from the
|
|
27
|
+
[**Releases page**](https://github.com/benzid-wael/secure-vault/releases/latest).
|
|
28
|
+
No need to clone the repo or install Node.
|
|
29
|
+
|
|
30
|
+
### Desktop app (GUI)
|
|
31
|
+
|
|
32
|
+
| OS | Download |
|
|
33
|
+
| ----------- | ----------------------------------------- |
|
|
34
|
+
| **macOS** | `.dmg` (installer) or `.zip` (portable) |
|
|
35
|
+
| **Windows** | `*-Setup.exe` (installer) or portable `.exe` |
|
|
36
|
+
| **Linux** | `.AppImage` (portable) or `.deb` (Debian/Ubuntu) |
|
|
37
|
+
|
|
38
|
+
> **Unsigned builds.** The app is not yet code-signed, so your OS will warn that
|
|
39
|
+
> the developer is unidentified. This is expected:
|
|
40
|
+
>
|
|
41
|
+
> - **macOS**: right-click the app → **Open** → **Open** (only needed the first
|
|
42
|
+
> time). Or run `xattr -dr com.apple.quarantine "/Applications/Secure Password Manager.app"`.
|
|
43
|
+
> - **Windows**: on the SmartScreen prompt click **More info** → **Run anyway**.
|
|
44
|
+
> - **Linux (AppImage)**: `chmod +x Secure*.AppImage` then run it.
|
|
45
|
+
|
|
46
|
+
### Command-line tool (`vault`)
|
|
47
|
+
|
|
48
|
+
**Option A — standalone binary** (no Node required). Download the file for your
|
|
49
|
+
platform from the Releases page, then:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# macOS / Linux
|
|
53
|
+
chmod +x vault-macos-arm64 # or vault-linux-x64, etc.
|
|
54
|
+
sudo mv vault-macos-arm64 /usr/local/bin/vault
|
|
55
|
+
vault info
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```powershell
|
|
59
|
+
# Windows: rename vault-windows-x64.exe to vault.exe and add its folder to PATH
|
|
60
|
+
vault info
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
On macOS the binary is also unsigned — if it's blocked, run
|
|
64
|
+
`xattr -d com.apple.quarantine vault` once.
|
|
65
|
+
|
|
66
|
+
**Option B — via npm** (requires Node.js 20.10+):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install -g @benzid.wael/secure-vault
|
|
70
|
+
vault info
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The CLI and the desktop app share the same encrypted vaults on disk.
|
|
74
|
+
|
|
75
|
+
## Building from source
|
|
76
|
+
|
|
77
|
+
### Prerequisites
|
|
78
|
+
|
|
79
|
+
- Node.js 20.10.0 or higher
|
|
80
|
+
- npm 9.0.0 or higher
|
|
81
|
+
- Git
|
|
82
|
+
|
|
83
|
+
### Setup
|
|
84
|
+
|
|
85
|
+
1. Clone the repository:
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/benzid-wael/secure-vault.git
|
|
88
|
+
cd secure-vault
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
2. Install dependencies:
|
|
92
|
+
```bash
|
|
93
|
+
npm install
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
See [`docs/RELEASING.md`](docs/RELEASING.md) for how releases are built and published.
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
### Start Development Server
|
|
101
|
+
|
|
102
|
+
To run the application in development mode with hot-reload:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Start both renderer and main processes in development mode
|
|
106
|
+
npm run dev:electron
|
|
107
|
+
|
|
108
|
+
# Or start them separately in different terminals
|
|
109
|
+
# Terminal 1 - Start React development server
|
|
110
|
+
npm run dev:renderer
|
|
111
|
+
|
|
112
|
+
# Terminal 2 - Start Electron main process
|
|
113
|
+
npm run dev:main
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Building
|
|
117
|
+
|
|
118
|
+
### Development Build
|
|
119
|
+
|
|
120
|
+
Create an unoptimized development build:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm run build:all
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Production Build
|
|
127
|
+
|
|
128
|
+
Create an optimized production build:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Build both renderer and main processes
|
|
132
|
+
npm run build:all
|
|
133
|
+
|
|
134
|
+
# Verify the build
|
|
135
|
+
npm run verify-build
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Packaging
|
|
139
|
+
|
|
140
|
+
Package the application for distribution:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Package for current platform
|
|
144
|
+
npm run package
|
|
145
|
+
|
|
146
|
+
# Package for specific platforms
|
|
147
|
+
npm run package:mac # macOS
|
|
148
|
+
npm run package:win # Windows
|
|
149
|
+
npm run package:linux # Linux
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Running Production Build
|
|
153
|
+
|
|
154
|
+
To run the production build:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Build the application first
|
|
158
|
+
npm run build:all
|
|
159
|
+
|
|
160
|
+
# Then run the production build
|
|
161
|
+
npm run start:prod
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Usage
|
|
165
|
+
|
|
166
|
+
### First Time Setup
|
|
167
|
+
|
|
168
|
+
1. Launch the application
|
|
169
|
+
2. You'll see the vault selector with a default vault
|
|
170
|
+
3. The default vault password is `changeme123` (change this immediately for security)
|
|
171
|
+
4. Or create a new vault with a strong master password
|
|
172
|
+
|
|
173
|
+
### Creating a New Vault
|
|
174
|
+
|
|
175
|
+
1. Click "Create New Vault" from the main screen
|
|
176
|
+
2. Enter a unique vault name
|
|
177
|
+
3. Create a strong master password (the app will show password strength)
|
|
178
|
+
4. Confirm your password
|
|
179
|
+
5. Click "Create Vault"
|
|
180
|
+
|
|
181
|
+
### Adding Passwords
|
|
182
|
+
|
|
183
|
+
1. Unlock your vault
|
|
184
|
+
2. Click the "+" floating action button
|
|
185
|
+
3. Fill in the password details:
|
|
186
|
+
- Title (required)
|
|
187
|
+
- Username/Email (required)
|
|
188
|
+
- Password (required) - use the generate button for strong passwords
|
|
189
|
+
- URL (optional)
|
|
190
|
+
- Notes (optional)
|
|
191
|
+
4. Click "Add"
|
|
192
|
+
|
|
193
|
+
### Managing Passwords
|
|
194
|
+
|
|
195
|
+
- **Search**: Use the search bar to quickly find passwords
|
|
196
|
+
- **Copy**: Click the copy icon next to any field to copy it to clipboard
|
|
197
|
+
- **View**: Click the eye icon to show/hide passwords
|
|
198
|
+
- **Edit**: Click the menu (⋮) and select "Edit"
|
|
199
|
+
- **Delete**: Click the menu (⋮) and select "Delete"
|
|
200
|
+
|
|
201
|
+
## Security Best Practices
|
|
202
|
+
|
|
203
|
+
1. **Use a Strong Master Password**: Your master password should be long, unique, and memorable
|
|
204
|
+
2. **Regular Backups**: Export your vault data regularly (feature coming soon)
|
|
205
|
+
3. **Keep Software Updated**: Always use the latest version
|
|
206
|
+
4. **Secure Your Device**: Use device encryption and lock screens
|
|
207
|
+
5. **Don't Share Master Passwords**: Each user should have their own vault
|
|
208
|
+
|
|
209
|
+
## File Structure
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
secure-password-manager/
|
|
213
|
+
├── public/
|
|
214
|
+
│ ├── electron.js # Electron main process
|
|
215
|
+
│ ├── preload.js # Secure IPC bridge
|
|
216
|
+
│ └── index.html # HTML template
|
|
217
|
+
├── src/
|
|
218
|
+
│ ├── components/ # React components
|
|
219
|
+
│ │ ├── VaultSelector.js
|
|
220
|
+
│ │ ├── VaultLogin.js
|
|
221
|
+
│ │ ├── CreateVault.js
|
|
222
|
+
│ │ └── PasswordManager.js
|
|
223
|
+
│ ├── App.js # Main React app
|
|
224
|
+
│ └── index.js # React entry point
|
|
225
|
+
└── package.json # Dependencies and scripts
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Technical Details
|
|
229
|
+
|
|
230
|
+
### Encryption
|
|
231
|
+
|
|
232
|
+
- **Algorithm**: AES-256-GCM (Galois/Counter Mode)
|
|
233
|
+
- **Key Derivation**: PBKDF2 with SHA-512, 100,000 iterations
|
|
234
|
+
- **Salt**: 32-byte random salt per vault
|
|
235
|
+
- **Authentication**: Built-in authentication tag prevents tampering
|
|
236
|
+
|
|
237
|
+
### Storage
|
|
238
|
+
|
|
239
|
+
- Vaults are stored in the user's application data directory
|
|
240
|
+
- Each vault is a separate encrypted JSON file
|
|
241
|
+
- No sensitive data is stored in plain text
|
|
242
|
+
|
|
243
|
+
### Security Architecture
|
|
244
|
+
|
|
245
|
+
- Electron main process handles all file operations
|
|
246
|
+
- Renderer process has no direct file system access
|
|
247
|
+
- Context isolation prevents code injection
|
|
248
|
+
- Content Security Policy (CSP) prevents XSS attacks
|
|
249
|
+
|
|
250
|
+
## Contributing
|
|
251
|
+
|
|
252
|
+
1. Fork the repository
|
|
253
|
+
2. Create a feature branch
|
|
254
|
+
3. Make your changes
|
|
255
|
+
4. Add tests if applicable
|
|
256
|
+
5. Submit a pull request
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
|
|
260
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
261
|
+
|
|
262
|
+
## Support
|
|
263
|
+
|
|
264
|
+
If you encounter any issues or have questions, please open an issue on the GitHub repository.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
**⚠️ Important Security Note**: This application stores your passwords locally on your device. While we use strong encryption, you are responsible for keeping your master password secure and backing up your vault files. The developers are not responsible for lost passwords or data.
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import figlet from 'figlet';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import password from '@inquirer/password';
|
|
6
|
+
|
|
7
|
+
import { program } from 'commander';
|
|
8
|
+
import standardFont from 'figlet/importable-fonts/Standard.js';
|
|
9
|
+
import secureVault from '../package.json' with { type: 'json' };
|
|
10
|
+
|
|
11
|
+
// Register the font explicitly so the banner survives bundling into a
|
|
12
|
+
// standalone binary, where figlet cannot read .flf font files from disk.
|
|
13
|
+
figlet.parseFont('Standard', standardFont);
|
|
14
|
+
|
|
15
|
+
function banner(text) {
|
|
16
|
+
try {
|
|
17
|
+
return figlet.textSync(text, {
|
|
18
|
+
font: 'Standard',
|
|
19
|
+
horizontalLayout: 'full',
|
|
20
|
+
});
|
|
21
|
+
} catch {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
import { VaultFileService } from '../src/electron/services/VaultFileService.js';
|
|
27
|
+
import { VaultService } from '../src/electron/services/VaultService.js';
|
|
28
|
+
import { VaultRecoveryService } from '../src/electron/services/VaultRecoveryService.js';
|
|
29
|
+
import { getVaultsDir } from '../src/electron/utils/appPaths.js';
|
|
30
|
+
import { registerEnvCommand } from './commands/env.js';
|
|
31
|
+
|
|
32
|
+
program
|
|
33
|
+
.name('SecureVault')
|
|
34
|
+
.version(secureVault.version)
|
|
35
|
+
.description('SecureVault CLI');
|
|
36
|
+
|
|
37
|
+
program.command('info').action((options) => {
|
|
38
|
+
const vaultDir = getVaultsDir();
|
|
39
|
+
console.log(chalk.yellow(banner('SecureVault CLI')));
|
|
40
|
+
console.log();
|
|
41
|
+
console.log('Version: ', secureVault.version);
|
|
42
|
+
console.log('Vault directory: ', vaultDir);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
program
|
|
46
|
+
.command('recover')
|
|
47
|
+
.option('-n, --name <vaultName>', 'Vault name')
|
|
48
|
+
.action(async (options) => {
|
|
49
|
+
let spinner = ora(`Recovering vault: ${options.name}`).start();
|
|
50
|
+
|
|
51
|
+
const vaultDir = getVaultsDir();
|
|
52
|
+
const vfs = new VaultFileService(vaultDir);
|
|
53
|
+
if (!vfs.vaultExists(options.name)) {
|
|
54
|
+
spinner.failed(chalk.green('Vault not found!'));
|
|
55
|
+
}
|
|
56
|
+
spinner.succeed(chalk.green('Vault exists!'));
|
|
57
|
+
|
|
58
|
+
const vs = new VaultService(vaultDir);
|
|
59
|
+
let masterPassword = '';
|
|
60
|
+
let is_valid = false;
|
|
61
|
+
while (!is_valid) {
|
|
62
|
+
masterPassword = await password({
|
|
63
|
+
message: 'Enter your password: ',
|
|
64
|
+
mask: true,
|
|
65
|
+
});
|
|
66
|
+
const result = await vs.verifyPassword(options.name, masterPassword);
|
|
67
|
+
is_valid = result.success;
|
|
68
|
+
}
|
|
69
|
+
ora().start().succeed('Valid master password!');
|
|
70
|
+
|
|
71
|
+
spinner = ora('Recovering vault').start();
|
|
72
|
+
const recoveryService = new VaultRecoveryService(vaultDir);
|
|
73
|
+
const recovered = recoveryService.recover(options.name, masterPassword);
|
|
74
|
+
if (recovered) {
|
|
75
|
+
spinner.succeed('Vault recovered successfully!');
|
|
76
|
+
} else {
|
|
77
|
+
spinner.failed('Failed to recover vault!');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
registerEnvCommand(program);
|
|
82
|
+
|
|
83
|
+
program.parse(process.argv);
|