A modern, secure, and self-hosted password manager built with React, Node.js, and MongoDB
-
🔒 Military-grade AES-256-GCM encryption (native Node.js crypto)
-
🔑 Master password protection with bcrypt + JWT sessions
-
⏱️ Auto-lock after inactivity
-
🔍 Search by website, username, or tags
-
🐳 Docker-ready with Nginx and Compose
-
🎨 Clean, responsive UI
# Clone the repository
git clone https://github.com/Transyltooniaa/PasswordManager.git
cd PasswordManager
# Bring up the full stack (Mongo, backend, frontend)
docker compose up --build
# App
# Frontend: http://localhost:5173
# Backend: http://localhost:3000/health- Docker 20.10+
- Docker Compose v2+
- Node.js v20+
- MongoDB v6+
- Copy env and generate keys
cp backend/.env.example backend/.env
cd backend
npm install
node generate-keys.js
# copy ENCRYPTION_KEY and AUTH_SECRET from the output into backend/.env
# generate bcrypt hash for your master password
node -e "console.log(require('bcryptjs').hashSync('YourMasterPassword', 12))"
# paste it into AUTH_PASSWORD_HASH in backend/.env- Start services
cd .. # back to repo root
docker compose up --build- Open the app
- Frontend: http://localhost:5173
- Backend API: http://localhost:3000
- Mongo Express (optional): http://localhost:8081 (admin/admin)
- Start MongoDB
# macOS (Homebrew)
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community- Backend setup
cd backend
npm install
cp .env.example .env
node generate-keys.js
node -e "console.log(require('bcryptjs').hashSync('YourMasterPassword', 12))"
# paste values into .env
npm run dev- Frontend setup (new terminal)
cd .. # project root
npm install
npm run devVite dev server proxies /api/* to the backend at :3000.
Backend (backend/.env):
# Database
MONGO_URL=mongodb://localhost:27017 # or mongodb://mongo:27017 in Docker
DB_NAME=passop
# Encryption
ENCRYPTION_KEY=base64-32-byte-key # generated by generate-keys.js
# Auth
AUTH_SECRET=your-jwt-secret # generated by generate-keys.js
AUTH_PASSWORD_HASH=$2b$12$... # bcrypt hash of your master password
# Server
PORT=3000Frontend:
# Optional: defaults to '/'
VITE_API_BASE=/- Start the app (Docker or local dev)
- Log in with your master password (the one that produced AUTH_PASSWORD_HASH)
- Add and manage credentials; use tags and search filters
- Auto-lock will sign you out after inactivity
PassOP-Mongo-Version/
├── backend/
│ ├── src/
│ │ ├── app.js # Express app wiring
│ │ ├── config/db.js # Mongo connection
│ │ ├── controllers/passwordController.js
│ │ ├── middleware/auth.js # JWT + bcrypt login
│ │ ├── routes/passwordRoutes.js
│ │ ├── services/passwordService.js
│ │ └── utils/crypto.js # AES-256-GCM + PBKDF2
│ ├── server.js # Entrypoint
│ ├── generate-keys.js # Key generator helper
│ ├── verify-env.js # Env sanity check
│ ├── test-encryption.js # Crypto tests
│ └── Dockerfile
├── src/
│ ├── App.jsx # Auth context + idle auto-lock
│ ├── components/
│ │ ├── Lock.jsx # Sign-in screen
│ │ ├── Manager.jsx # CRUD UI
│ │ └── Navbar.jsx
│ └── lib/apiBase.js # API base helper
├── docker-compose.yml # Mongo + backend + web + mongo-express
├── Dockerfile # Frontend build (Nginx)
├── nginx.conf # SPA + /api proxy
├── SECURITY.md
├── ENCRYPTION-EXPLAINED.md
└── docs/Project-Report.md
- Port already in use: stop the conflicting service or edit ports in
docker-compose.yml. - Invalid ENCRYPTION_KEY: must decode to exactly 32 bytes (base64). Run
npm run verify:envin backend. - Mongo connection errors: ensure Mongo is running (Docker service
mongoor local daemon). - 401 Unauthorized: clear localStorage and log in again.
Helpful checks:
cd backend
npm test # crypto tests
npm run verify:env # env validation + quick encrypt/decrypt- Read the full security overview in SECURITY.md
- Deep dive into hashing, salts, and AES-GCM in ENCRYPTION-EXPLAINED.md