A full-stack banking system website with a customer portal and a separate admin panel — accounts, deposits, withdrawals, inter-account transfers by account number, transaction history, and an account-application workflow with admin approval.
Built as a self-contained demo project: no external services required, everything runs locally with seeded demo data.
| Layer | Technology | Purpose |
|---|---|---|
| Runtime | Node.js | JavaScript server runtime |
| Framework | Express | REST API + static file serving |
| Database | SQLite via better-sqlite3 | Persistent, file-based storage (data/bank.db) — survives restarts |
| Auth | express-session + Node crypto.scrypt |
Cookie sessions, salted password hashing, role-based access |
| Frontend | Vanilla HTML / CSS / JavaScript | Zero build step — pages served directly by Express |
| Mobile | React Native + Expo | Android customer app (android-app/) — same REST API, web-matching theme, cloud/LAN server picker |
| Mobile build | Gradle + Android SDK (expo prebuild) |
Signed release APK, distributed via the server and GitHub Releases |
| Process manager | pm2 | Keeps the server running on the VPS across restarts |
| Rate limiting | express-rate-limit | Brute-force protection on login endpoints (10 attempts / 15 min / IP) |
- Separate login panel for customers (admins have their own panel at
/admin) - Dashboard with account cards, balances, and recent activity
- Deposits & withdrawals via modal dialogs, with validation (positive amounts, no overdraft, ₹1,00,000 single-deposit cap)
- Transfers by account number — send money to any BlueRock account; atomic SQL transaction so money never vanishes mid-transfer
- Account applications — customers apply for new savings/checking accounts; nothing is created until an admin approves
- Application status tracking (pending / approved / rejected with reason)
- Paginated, filterable transaction history
- Dark "staff access only" login, separate from the customer portal
- Overview stats: customers, accounts, pending applications, total deposits/withdrawals/transfers, bank-wide balance
- Applications tab — approve (creates the account) or reject (with reason) customer applications; pending count badge
- Customer management — list all customers with account counts and total balances; create new customers (auto-opens their first account)
- All accounts and all bank-wide transactions with pagination
- Role-based route guards (
requireLogin,requireAdmin) on every API endpoint - Per-account ownership checks — users can only access their own accounts
- scrypt password hashing with per-user salts
- Transfers validated: sufficient funds, destination exists, no self-transfers
# 1. Install dependencies
npm install
# 2. Seed the database with demo users, accounts and transactions
npm run seed
# 3. Start the server
npm startThen open:
- Customer portal: http://localhost:3000
- Admin panel: http://localhost:3000/admin
| Role | Username | Password | Panel |
|---|---|---|---|
| Admin | admin |
admin123 |
/admin |
| Customer | john |
john123 |
/ |
| Customer | alice |
alice123 |
/ |
| Customer | raj |
raj123 |
/ |
Customer credentials are rejected on the admin panel and vice-versa.
The server is deployed on a VPS under pm2 (restart-safe) and reachable at:
- Customer portal: http://169.58.66.151:3000
- Admin panel: http://169.58.66.151:3000/admin
The same instance serves LAN clients too — it binds all interfaces, so any device on the server's local network can use http://<LAN-IP>:3000. Login endpoints are rate-limited (10 attempts / 15 min / IP). Plain HTTP by decision — HTTPS requires a domain (tracked in UPDATES.md).
A React Native (Expo) customer app with full feature parity to the web portal — see android-app/ for details.
Install: download the signed APK straight from the server — http://169.58.66.151:3000/downloads/BlueRockBank.apk — then open it on the phone and allow "install unknown apps".
The app offers two server options (login screen → ⚙ Server): ☁ Cloud (VPS), default, or 🏠 LAN with an editable URL — switchable without a rebuild. Its theme mirrors the web portal exactly (same palette, navy-gradient account cards, badges).
Since v1.2.0 the app ships with a custom BlueRock-branded launcher icon — an adaptive icon with foreground/background layers plus a themed monochrome variant (Android 13+ themed icons), matching the web palette.
banking-system/
├── src/
│ ├── server.js # Express app — all API routes + static serving
│ ├── db.js # SQLite connection + schema (users, accounts, transactions, applications)
│ ├── auth.js # Password hashing, account numbers, atomic transfer logic
│ └── seed.js # Demo data seeder
├── public/
│ ├── index.html # Customer login
│ ├── admin-login.html # Admin login (separate panel)
│ ├── dashboard.html # Customer dashboard + deposit/withdraw modals
│ ├── transfer.html # Transfer by account number
│ ├── transactions.html # Customer transaction history
│ ├── admin.html # Admin panel (overview/customers/accounts/transactions/applications)
│ ├── css/style.css # Shared styles
│ └── js/app.js # Shared helpers (api fetch, auth guards, navbar, formatting)
├── test-browser.js # Headless-Chrome end-to-end tests (puppeteer-core)
├── android-app/ # React Native (Expo) customer app + APK build (see android-app/README.md)
├── data/bank.db # SQLite database (gitignored, created by `npm run seed`)
└── package.json
| Method & Path | Auth | Purpose |
|---|---|---|
POST /api/login |
— | Customer login (customers only) |
POST /api/admin/login |
— | Admin login (admins only) |
POST /api/logout / GET /api/me |
session | Logout / current user |
GET /api/accounts |
customer | List own accounts |
POST /api/accounts/:id/deposit | /withdraw |
customer | Deposit / withdraw |
POST /api/transfer |
customer | Transfer by destination account number |
GET /api/accounts/:id/transactions |
customer | Paginated history |
POST /api/applications / GET /api/applications |
customer | Apply for / list own account applications |
GET /api/admin/stats | /customers | /accounts | /transactions | /applications |
admin | Admin data |
POST /api/admin/customers |
admin | Create customer (auto-opens first account) |
POST /api/admin/applications/:id/approve | /reject |
admin | Approve / reject applications |
node test-browser.js # headless Chrome E2E: login, deposit, withdraw, apply, admin approveMIT License — Copyright (c) 2026 Hrishikesh Thombare.