vaultwarden.js 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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +455 -0
  3. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Marki
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,455 @@
1
+ # Vaultwarden Client
2
+
3
+ A modern, type-safe, object-oriented TypeScript SDK for Vaultwarden/Bitwarden servers. Inspired by [discord.js](https://discord.js.org/) with a focus on developer experience and comprehensive type safety.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/vaultwarden-client.svg)](https://www.npmjs.com/package/vaultwarden-client)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3%2B-blue.svg)](https://www.typescriptlang.org/)
7
+ [![License](https://img.shields.io/npm/l/vaultwarden-client.svg)](LICENSE)
8
+
9
+ ## Features
10
+
11
+ - **Object-Oriented Architecture** - Manager/Structure pattern like discord.js
12
+ - **Full Type Safety** - Strict TypeScript with `exactOptionalPropertyTypes`
13
+ - **Event-Driven** - Typed EventEmitter for real-time updates
14
+ - **Smart Caching** - LRU cache with TTL support for all entities
15
+ - **Complete Encryption** - PBKDF2, AES-256-CBC, HKDF support
16
+ - **Well Tested** - Comprehensive test suite with Vitest
17
+ - **ESM + CJS** - Dual module support
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install vaultwarden-client
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import { VaultwardenClient } from 'vaultwarden-client';
29
+
30
+ const client = new VaultwardenClient({
31
+ baseUrl: 'https://vault.example.com',
32
+ deviceName: 'MyApp',
33
+ });
34
+
35
+ // Login
36
+ await client.login({
37
+ username: 'user@example.com',
38
+ password: 'masterpassword',
39
+ });
40
+
41
+ // Sync data from server
42
+ await client.sync();
43
+
44
+ // Access your vault
45
+ console.log(`You have ${client.ciphers.cache.size} items`);
46
+
47
+ // Find a specific login
48
+ const github = client.ciphers.cache.find(
49
+ (c) => c.name === 'GitHub'
50
+ );
51
+
52
+ if (github) {
53
+ console.log(`Username: ${github.username}`);
54
+ console.log(`Password: ${github.password}`);
55
+ }
56
+ ```
57
+
58
+ ## Authentication
59
+
60
+ ### Login with Password
61
+
62
+ ```typescript
63
+ await client.login({
64
+ username: 'user@example.com',
65
+ password: 'masterpassword',
66
+ });
67
+ ```
68
+
69
+ ### Login with 2FA
70
+
71
+ ```typescript
72
+ await client.login({
73
+ username: 'user@example.com',
74
+ password: 'masterpassword',
75
+ twoFactorCode: '123456',
76
+ twoFactorProvider: 0, // Authenticator app
77
+ });
78
+ ```
79
+
80
+ ### Available 2FA Methods
81
+
82
+ | Provider | Value | Description |
83
+ |----------|-------|-------------|
84
+ | `Authenticator` | `0` | TOTP (Google Authenticator, etc.) |
85
+ | `Email` | `1` | Email-based 2FA |
86
+ | `Duo` | `2` | Duo Security |
87
+ | `Yubikey` | `3` | YubiKey OTP |
88
+ | `FIDO2` | `4` | FIDO2 WebAuthn |
89
+
90
+ ## Core Concepts
91
+
92
+ ### Managers
93
+
94
+ Managers handle CRUD operations and maintain caches:
95
+
96
+ ```typescript
97
+ // Ciphers (passwords, cards, notes, identities)
98
+ client.ciphers
99
+
100
+ // Folders
101
+ client.folders
102
+
103
+ // Organizations
104
+ client.organizations
105
+
106
+ // Collections
107
+ client.collections
108
+ ```
109
+
110
+ ### Structures
111
+
112
+ Structures represent individual vault items:
113
+
114
+ ```typescript
115
+ // Cipher types
116
+ LoginCipher // Website passwords
117
+ CardCipher // Credit cards
118
+ SecureNoteCipher // Encrypted notes
119
+ IdentityCipher // Personal information
120
+
121
+ // Other structures
122
+ FolderStructure
123
+ CollectionStructure
124
+ OrganizationStructure
125
+ ```
126
+
127
+ ### Collections
128
+
129
+ Enhanced Map with utility methods:
130
+
131
+ ```typescript
132
+ // Get all login ciphers
133
+ const logins = client.ciphers.logins;
134
+
135
+ // Filter by predicate
136
+ const favorites = client.ciphers.cache.filter(
137
+ (c) => c.favorite
138
+ );
139
+
140
+ // Find by predicate
141
+ const github = client.ciphers.cache.find(
142
+ (c) => c.name === 'GitHub'
143
+ );
144
+
145
+ // Map to array
146
+ const names = client.ciphers.cache.map((c) => c.name);
147
+ ```
148
+
149
+ ## Working with Ciphers
150
+
151
+ ### Create a Login
152
+
153
+ ```typescript
154
+ const login = await client.ciphers.createLogin({
155
+ name: 'GitHub',
156
+ username: 'myuser',
157
+ password: 'securepassword123',
158
+ uri: 'https://github.com',
159
+ notes: 'My GitHub account',
160
+ favorite: true,
161
+ });
162
+
163
+ console.log(`Created: ${login.name} (${login.id})`);
164
+ ```
165
+
166
+ ### Create a Card
167
+
168
+ ```typescript
169
+ const card = await client.ciphers.createCard({
170
+ name: 'Personal Visa',
171
+ cardholderName: 'John Doe',
172
+ brand: 'Visa',
173
+ number: '4111111111111111',
174
+ expMonth: '12',
175
+ expYear: '2027',
176
+ code: '123',
177
+ });
178
+ ```
179
+
180
+ ### Create a Secure Note
181
+
182
+ ```typescript
183
+ const note = await client.ciphers.createSecureNote({
184
+ name: 'WiFi Password',
185
+ content: 'Network: HomeWiFi_5G\nPassword: SuperSecret!',
186
+ });
187
+ ```
188
+
189
+ ### Create an Identity
190
+
191
+ ```typescript
192
+ const identity = await client.ciphers.createIdentity({
193
+ name: 'Personal Identity',
194
+ title: 'Mr',
195
+ firstName: 'John',
196
+ lastName: 'Doe',
197
+ email: 'john@example.com',
198
+ address1: '123 Main St',
199
+ city: 'New York',
200
+ state: 'NY',
201
+ postalCode: '10001',
202
+ country: 'US',
203
+ });
204
+ ```
205
+
206
+ ### Update and Delete
207
+
208
+ ```typescript
209
+ // Update
210
+ await login.update({ name: 'GitHub (Personal)' });
211
+ await login.setFavorite(false);
212
+ await login.moveToFolder(folderId);
213
+
214
+ // Soft delete (move to trash)
215
+ await login.softDelete();
216
+
217
+ // Restore from trash
218
+ await login.restore();
219
+
220
+ // Permanent delete
221
+ await login.delete();
222
+ ```
223
+
224
+ ## Working with Folders
225
+
226
+ ```typescript
227
+ // Create a folder
228
+ const folder = await client.folders.create('Work Accounts');
229
+
230
+ // Update folder
231
+ await client.folders.update(folder.id, 'Work Accounts 2024');
232
+
233
+ // Delete folder
234
+ await client.folders.delete(folder.id);
235
+
236
+ // Get ciphers in folder
237
+ const workLogins = client.ciphers.cache.filter(
238
+ (c) => c.folderId === folder.id
239
+ );
240
+ ```
241
+
242
+ ## Searching
243
+
244
+ ```typescript
245
+ // Search by name/notes
246
+ const results = client.ciphers.search('github');
247
+
248
+ // Find by domain
249
+ const logins = client.ciphers.findByDomain('github.com');
250
+
251
+ // Find by folder
252
+ const folderCiphers = client.ciphers.findByFolder(folderId);
253
+
254
+ // Filtered accessors
255
+ const favorites = client.ciphers.favorites;
256
+ const trash = client.ciphers.trash;
257
+ ```
258
+
259
+ ## Password Generation
260
+ git remote add origin https://github.com/MarkIt-host/VaultWarden.js.git
261
+ ```typescript
262
+ import { generatePassword, generatePassphrase } from 'vaultwarden-client';
263
+
264
+ // Generate strong password
265
+ const { password, entropy } = generatePassword({
266
+ length: 20,
267
+ uppercase: true,
268
+ lowercase: true,
269
+ numbers: true,
270
+ special: true,
271
+ minNumbers: 2,
272
+ minSpecial: 1,
273
+ ambiguous: false, // Exclude 0, O, 1, l
274
+ });
275
+
276
+ // Generate memorable passphrase
277
+ const { passphrase, wordCount } = generatePassphrase({
278
+ numWords: 5,
279
+ wordSeparator: '-',
280
+ capitalize: true,
281
+ includeNumber: true,
282
+ });
283
+ // Result: "Blue-Tiger-Happy-Cloud-42"
284
+ ```
285
+
286
+ ## Events
287
+
288
+ Listen for real-time updates:
289
+
290
+ ```typescript
291
+ client.on('ready', () => {
292
+ console.log('Client is ready!');
293
+ });
294
+
295
+ client.on('sync', () => {
296
+ console.log('Data synced!');
297
+ });
298
+
299
+ client.on('cipherCreate', (cipher) => {
300
+ console.log(`Created: ${cipher.name}`);
301
+ });
302
+
303
+ client.on('cipherUpdate', (cipher) => {
304
+ console.log(`Updated: ${cipher.name}`);
305
+ });
306
+
307
+ client.on('cipherDelete', (id) => {
308
+ console.log(`Deleted cipher: ${id}`);
309
+ });
310
+
311
+ client.on('error', (error) => {
312
+ console.error('Client error:', error);
313
+ });
314
+ ```
315
+
316
+ ### Event Types
317
+
318
+ | Event | Payload | Description |
319
+ |-------|---------|-------------|
320
+ | `ready` | - | Client is authenticated and ready |
321
+ | `login` | `AuthTokenResponse` | Login successful |
322
+ | `logout` | - | Logged out |
323
+ | `sync` | - | Data synced from server |
324
+ | `cipherCreate` | `Cipher` | New cipher created |
325
+ | `cipherUpdate` | `Cipher` | Cipher updated |
326
+ | `cipherDelete` | `string` | Cipher deleted (ID) |
327
+ | `folderCreate` | `FolderStructure` | New folder created |
328
+ | `folderUpdate` | `FolderStructure` | Folder updated |
329
+ | `folderDelete` | `string` | Folder deleted (ID) |
330
+ | `error` | `Error` | Error occurred |
331
+
332
+ ## Error Handling
333
+
334
+ ```typescript
335
+ import {
336
+ VaultwardenError,
337
+ AuthenticationError,
338
+ NotFoundError,
339
+ RateLimitError,
340
+ } from 'vaultwarden-client';
341
+
342
+ try {
343
+ await client.login({ username, password });
344
+ } catch (error) {
345
+ if (error instanceof AuthenticationError) {
346
+ console.error('Invalid credentials');
347
+ } else if (error instanceof RateLimitError) {
348
+ console.error(`Rate limited. Retry after ${error.retryAfter}s`);
349
+ } else if (error instanceof VaultwardenError) {
350
+ console.error(`Error ${error.code}: ${error.message}`);
351
+ }
352
+ }
353
+ ```
354
+
355
+ ### Error Types
356
+
357
+ | Error | Description |
358
+ |-------|-------------|
359
+ | `VaultwardenError` | Base error class |
360
+ | `AuthenticationError` | Invalid credentials or 2FA needed |
361
+ | `APIError` | API request failed |
362
+ | `NotFoundError` | Resource not found |
363
+ | `ValidationError` | Invalid input data |
364
+ | `PermissionError` | Insufficient permissions |
365
+ | `RateLimitError` | Rate limit hit |
366
+ | `TimeoutError` | Request timed out |
367
+ | `CryptoError` | Encryption/decryption failed |
368
+ | `StateError` | Invalid client state |
369
+
370
+ ## Configuration Options
371
+
372
+ ```typescript
373
+ const client = new VaultwardenClient({
374
+ // Required
375
+ baseUrl: 'https://vault.example.com',
376
+
377
+ // Optional
378
+ deviceName: 'MyApp', // Default: 'vaultwarden-client'
379
+ deviceType: 8, // Default: 8 (Windows Desktop)
380
+ timeout: 30000, // Request timeout in ms
381
+ maxRetries: 3, // Max retry attempts
382
+ });
383
+ ```
384
+
385
+ ### Device Types
386
+
387
+ | Type | Value |
388
+ |------|-------|
389
+ | Android | 0 |
390
+ | iOS | 1 |
391
+ | Chrome Extension | 2 |
392
+ | Firefox Extension | 3 |
393
+ | Opera Extension | 4 |
394
+ | Edge Extension | 5 |
395
+ | Windows Desktop | 8 |
396
+ | macOS Desktop | 9 |
397
+ | Linux Desktop | 10 |
398
+ | Chrome | 11 |
399
+ | Safari | 12 |
400
+ | Firefox | 16 |
401
+
402
+ ## Testing Script
403
+
404
+ A CLI script is included for testing:
405
+
406
+ ```bash
407
+ # Login and show stats
408
+ npx tsx scripts/vault-tester.ts login \
409
+ --url https://vault.example.com \
410
+ --email user@example.com \
411
+ --password pass
412
+
413
+ # Fill vault with test data
414
+ npx tsx scripts/vault-tester.ts fill \
415
+ --url https://vault.example.com \
416
+ --email user@example.com \
417
+ --password pass \
418
+ --count 50 \
419
+ --folder "Test Items"
420
+
421
+ # List vault contents
422
+ npx tsx scripts/vault-tester.ts list \
423
+ --url https://vault.example.com \
424
+ --email user@example.com \
425
+ --password pass
426
+
427
+ # Delete all items
428
+ npx tsx scripts/vault-tester.ts delete \
429
+ --url https://vault.example.com \
430
+ --email user@example.com \
431
+ --password pass \
432
+ --all
433
+ ```
434
+
435
+ ## API Reference
436
+
437
+ See [API.md](./docs/API.md) for complete API documentation.
438
+
439
+ ## Examples
440
+
441
+ See [examples/](./examples/) directory for usage examples:
442
+
443
+ - [Basic Auth](./examples/basic-auth.ts)
444
+ - [Cipher CRUD](./examples/cipher-crud.ts)
445
+ - [Folder Management](./examples/folder-management.ts)
446
+ - [Organizations](./examples/organizations.ts)
447
+ - [Password Generator](./examples/password-generator.ts)
448
+
449
+ ## Migration from 2.x
450
+
451
+ See [MIGRATION.md](./docs/MIGRATION.md) for migration guide.
452
+
453
+ ## License
454
+
455
+ MIT © [Marki](https://marki.dev)
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "vaultwarden.js",
3
+ "version": "1.0.0",
4
+ "description": "A modern, object-oriented TypeScript SDK for Vaultwarden/Bitwarden servers",
5
+ "keywords": [
6
+ "vaultwarden",
7
+ "bitwarden",
8
+ "password-manager",
9
+ "vault",
10
+ "sdk",
11
+ "oop",
12
+ "discord.js-style"
13
+ ],
14
+ "author": "",
15
+ "license": "MIT",
16
+ "type": "module",
17
+ "main": "./dist/index.js",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "import": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/index.d.cts",
28
+ "default": "./dist/index.cjs"
29
+ }
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "scripts": {
42
+ "build": "tsup src/index.ts --format cjs,esm --dts --sourcemap --clean",
43
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "test:coverage": "vitest run --coverage",
47
+ "lint": "tsc --noEmit",
48
+ "typecheck": "tsc --noEmit",
49
+ "vault-tester": "tsx scripts/vault-tester.ts"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^20.0.0",
53
+ "@vitest/coverage-v8": "^1.0.0",
54
+ "tsup": "^8.0.0",
55
+ "tsx": "^4.22.3",
56
+ "typescript": "^5.3.0",
57
+ "vitest": "^1.0.0"
58
+ }
59
+ }