2026-05-12 16:59:58 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 22:32:05 +00:00
2026-05-12 16:59:58 +00:00
2026-05-11 23:35:52 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 23:35:52 +00:00
2026-05-11 23:35:52 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 22:32:05 +00:00
2026-05-11 23:35:52 +00:00

Password Vault

An offline-first password manager that runs entirely in your browser. No server, no cloud, no tracking — your vault lives on your machine.

Features

  • AES-256-GCM encryption — All credentials encrypted with a key derived from your master password via PBKDF2 (100,000 iterations). The key exists only in memory.
  • Zero network calls — Works from file:// or localhost. No APIs, no analytics, no telemetry.
  • Group management — Organize entries into color-coded groups. Create, rename, delete.
  • Full-text search — Instant search across title, username, URL, and notes.
  • Password generator — Configurable length (464), character types, custom exclusions, strength indicator.
  • Copy to clipboard — One-click copy with 15-second auto-clear.
  • JSON import/export — Export your entire vault as encrypted JSON. Import with merge or replace mode.
  • Auto-lock — Vault locks automatically on tab switch, visibility change, or configurable inactivity timer.
  • Dark theme — Responsive layout that works on desktop and mobile.

Quick Start

npm install
npm run dev        # http://localhost:5173

Production Build

npm run build      # → dist/ (static files)
npm run preview    # test the production build locally

The dist/ folder contains fully static HTML/CSS/JS that works from:

  • file:// protocol (open dist/index.html directly)
  • Any static web server (nginx, Apache, GitHub Pages, etc.)

Architecture

src/
├── App.svelte                      # Root — toggles LockScreen ↔ MainLayout
├── main.js                         # Entry point
├── components/
│   ├── LockScreen.svelte           # Vault creation & password unlock
│   ├── MainLayout.svelte           # Dashboard shell (sidebar + content)
│   ├── Sidebar.svelte              # Group list, search, group CRUD
│   ├── EntryList.svelte            # Searchable/filterable entry table
│   ├── EntryDetail.svelte          # View single entry, copy, delete
│   ├── EntryForm.svelte            # Create/edit entry with validation
│   ├── PasswordGenerator.svelte    # Standalone generator panel
│   └── ImportExport.svelte         # JSON import/export modals
├── lib/
│   ├── crypto/crypto.js            # PBKDF2 key derivation, AES-GCM, generator
│   ├── models/schema.js            # Data factories, validation, ID generation
│   ├── storage/db.js               # IndexedDB wrapper (idb library)
│   └── stores/
│       ├── app.svelte.js           # Reactive app state (lock/unlock)
│       ├── search.svelte.js        # Shared search + filter state
│       └── security.svelte.js      # Auto-lock timer, visibility detection
└── styles/
    └── main.css                    # Dark theme, CSS variables, responsive

Encryption Flow

Master Password ──PBKDF2──→ 256-bit Key ──AES-GCM──→ Encrypted Credential
                  (100k iters)
                      │
                      └── Salt stored in IndexedDB (not encrypted)
  • The encryption key is never persisted — it lives only in JavaScript memory.
  • A test payload (random string) is encrypted on vault creation and stored alongside the salt. On unlock, the entered password is used to derive a key and decrypt the test payload — if decryption succeeds, the password is correct.
  • On tab close or auto-lock, the key is cleared from memory.

Storage Schema (IndexedDB)

Store Fields
entries id, title, username, password (encrypted), url, notes (encrypted), groupId, createdAt, updatedAt
groups id, name, color, createdAt
meta salt, testEncrypted, testPlaintext

Security Considerations

Threat Mitigation
Key persistence Key stored only in $state, cleared on lock/close
Weak passwords Strength indicator on generator; no minimum enforced (user's choice)
Clipboard leakage Auto-clear after 15 seconds
Tab left open Auto-lock on visibility change (tab switch)
Database tampering All sensitive data encrypted at rest with AES-256-GCM
Brute force PBKDF2 with 100,000 iterations slows offline attacks

Known limitations

  • No browser fingerprinting or anti-keylogger — This is a local tool, not a hardened security appliance.
  • IndexedDB can be inspected — Encrypted data is safe, but metadata (titles, usernames, URLs) may be visible if not encrypted. Currently only password and notes are encrypted; titles/usernames/URLs are stored in plaintext for searchability.
  • No automatic backups — Use the JSON export feature to back up your vault regularly.

Development

npm run dev          # Start dev server with HMR
npm run build        # Production build (zero warnings target)
npm run preview      # Preview production build

Stack

  • Svelte 5 — Runes-based reactivity ($state, $derived, $effect)
  • Vite 8 — Build tool and dev server
  • idb — Promise-based IndexedDB wrapper
  • Web Crypto API — Native browser cryptography (no external crypto libraries)
  • Vanilla CSS — Dark theme with CSS custom properties, no preprocessors

License

MIT

Description
No description provided
Readme 1.7 MiB
Languages
JavaScript 52.4%
Svelte 44.9%
CSS 2.5%
HTML 0.2%