BillTracker/README.md

362 lines
11 KiB
Markdown
Raw Normal View History

2026-05-04 13:38:19 -05:00
# BillTracker
2026-05-03 20:02:32 -05:00
<p align="center">
2026-05-15 22:52:28 -05:00
<img src="docs/images/logo_cut.png" alt="BillTracker logo">
2026-05-04 14:17:32 -05:00
</p>
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
BillTracker is a private, self-hosted bill planning app for households and small personal setups. It tracks recurring bills, payments, monthly cash buckets, due dates, categories, debt payoff, imports, exports, and backups from one local installation.
It runs as a Node/Express app with a React/Vite frontend and stores data in SQLite. It is designed for people who want their bill data under their own control instead of inside a third-party budgeting service.
2026-05-03 20:02:32 -05:00
2026-05-04 13:41:06 -05:00
<p align="center">
Demo Server: https://t1.scheller.ltd/<br>
Username: guest &middot; Password: guest123
2026-05-04 13:41:06 -05:00
</p>
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
## Highlights
- Private-by-design self-hosted bill tracking with local SQLite storage
- Month-by-month tracker grouped by `1st-14th` and `15th-31st`
- Period-aware remaining balance that switches between the 1st and 15th buckets
- Bills, categories, payments, notes, skipped months, history ranges, and inactive bill handling
- Debt snowball page with payoff projections, avalanche comparison, APR math, and amortization schedules
- Analytics, calendar, monthly summary, income, starting cash, and printable reports
- XLSX import, import by bill, user export/import, Excel export, import history, and admin backups
- Local username/password login with optional authentik/OIDC
- Admin panel for users, backups, cleanup, auth settings, system status, roadmap, and migrations
- Public About, Privacy, and Release Notes pages
2026-05-04 14:17:32 -05:00
## Screenshots
2026-05-15 22:52:28 -05:00
![Login screenshot](docs/images/login.png)
2026-05-04 14:17:32 -05:00
2026-05-15 22:52:28 -05:00
![Tracker screenshot](docs/images/tracker.png)
2026-05-04 14:17:32 -05:00
2026-05-04 13:38:19 -05:00
![Analytics screenshot](docs/images/Analytics.png)
2026-05-03 20:02:32 -05:00
2026-05-04 13:38:19 -05:00
![Calendar screenshot](docs/images/Calendar.png)
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
## Who This Is For
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
BillTracker is built for self-hosters who want a practical bill dashboard without sending personal finance data to an outside service.
Good fit:
- Home servers, NAS boxes, small VPS deployments, Portainer, or Docker Compose
- Single-user or multi-user households
- People who split monthly cash around the 1st and 15th
- Users who want import/export and database backup control
- Authentik/OIDC users who want optional SSO
Not a full replacement for:
- Double-entry accounting
- Bank syncing
- Investment tracking
- Tax software
## Quick Start With Docker
The included Compose file runs the published image on host port `3030` and stores all persistent app data under `/data` inside the container.
2026-05-03 20:02:32 -05:00
```bash
2026-05-15 22:52:28 -05:00
docker compose up -d
```
Open:
```text
http://localhost:3030
2026-05-03 20:02:32 -05:00
```
2026-05-15 22:52:28 -05:00
On first start, seed an admin account with:
```yaml
environment:
INIT_ADMIN_USER: admin
INIT_ADMIN_PASS: change-this-password
```
Optional regular user seed:
```yaml
environment:
INIT_REGULAR_USER: regularuser
INIT_REGULAR_PASS: changeme123
```
Passwords must be at least 8 characters. Remove or rotate first-run seed values after initial setup.
### Persistent Data
For Docker, keep `/data` mounted. The container defaults to:
```text
DB_PATH=/data/db/bills.db
BACKUP_PATH=/data/backups
```
Back up the mounted `/data` directory like you would any other sensitive financial data.
## Node Install
Install dependencies:
2026-05-03 20:02:32 -05:00
```bash
2026-05-15 22:52:28 -05:00
npm install
2026-05-03 20:02:32 -05:00
```
2026-05-15 22:52:28 -05:00
Run API and Vite UI for development:
2026-05-03 20:02:32 -05:00
```bash
2026-05-15 22:52:28 -05:00
npm run dev
2026-05-03 20:02:32 -05:00
```
2026-05-15 22:52:28 -05:00
Build and start production:
2026-05-03 20:02:32 -05:00
```bash
2026-05-15 22:52:28 -05:00
npm run build
2026-05-03 20:02:32 -05:00
npm start
```
2026-05-04 13:38:19 -05:00
The production server serves `dist/` and listens on `PORT`, defaulting to `3000`.
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
Useful scripts:
2026-05-03 20:02:32 -05:00
```bash
npm run dev:api
npm run dev:ui
npm run build
2026-05-15 22:52:28 -05:00
npm run check
2026-05-03 20:02:32 -05:00
npm start
```
2026-05-15 22:52:28 -05:00
`npm run check` runs backend CommonJS syntax checks and a Vite production build.
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
## Product Map
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
### Tracker
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
The Tracker is the main monthly view. It shows active bills for the selected month, grouped into:
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
- `1st-14th`
- `15th-31st`
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
You can record payments, quick-pay bills, skip a bill for the month, add monthly notes, override monthly amounts, and navigate between months. The summary cards show starting cash, total paid, active period balance, overdue amount, previous month paid, and trend.
2026-05-15 22:52:28 -05:00
### Bills
Bills store the recurring source data:
- name, expected amount, due day, category
- active/inactive state
- billing cycle
- autopay and 2FA markers
- notes and account details
- optional debt fields such as balance, APR, and minimum payment
- inactive bill history ranges
### Debt Snowball
The Snowball page focuses on debt payoff planning:
- snowball and avalanche ordering
- minimum-only baseline
- live payoff projections
- APR snapshots
- amortization schedules
- drag ordering and debt exclusion
### Calendar, Summary, And Analytics
- Calendar shows due dates, payments, and month progress.
- Summary handles income, starting amounts, and monthly planning.
- Analytics provides spending trends, category views, bill history, filters, heatmaps, and print output.
### Data Tools
BillTracker includes:
- XLSX spreadsheet import with preview
- import by bill
- user SQLite import/export
- Excel workbook export
- import history
- admin database backup, restore, download, cleanup, and retention tools
## Privacy Model
BillTracker is intended to run privately in your own environment.
- Bill data stays in your SQLite database.
- The app does not use third-party analytics, advertising, or telemetry.
- The public Privacy page explains the apps local-first behavior.
- Login device details shown in Profile are visible to that user in the app UI, not exposed through the Admin UI.
- Optional update checks are for software update availability, not bill-data collection.
2026-05-15 22:52:28 -05:00
Admins can manage users, reset passwords, configure authentication, and manage backups, but normal bill data is scoped to the signed-in user.
2026-05-15 22:52:28 -05:00
## Authentication
BillTracker supports local username/password login by default. Admins can create users, reset passwords, promote/demote users, and activate/deactivate accounts.
Optional authentik/OIDC login can be enabled from Admin. OIDC uses authorization code flow with PKCE, state and nonce validation, and `openid-client` token validation.
Important behavior:
- Admin role is never granted by default through OIDC.
- OIDC admin access requires a configured admin group.
- Local login cannot be disabled unless OIDC is configured, enabled, and mapped to an admin group.
- The default seeded admin is restricted to admin routes and cannot access personal tracker data.
See [Authentik-Integration.md](docs/Authentik-Integration.md) for setup details.
2026-05-03 20:02:32 -05:00
## Configuration
2026-05-15 22:52:28 -05:00
Most settings are configured in the web UI:
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
- User settings: Settings/Profile
- Server settings: Admin
- Authentication settings: Admin
- Backup and cleanup settings: Admin
Common environment variables:
2026-05-03 20:02:32 -05:00
```bash
PORT=3000
NODE_ENV=production
2026-05-04 13:38:19 -05:00
DB_PATH=/path/to/bills.db
BACKUP_PATH=/path/to/backups
INIT_ADMIN_USER=admin
INIT_ADMIN_PASS=change-this-password
INIT_REGULAR_USER=regularuser
INIT_REGULAR_PASS=changeme123
SESSION_CLEANUP_INTERVAL_MS=86400000
2026-05-03 20:02:32 -05:00
HTTPS=true
2026-05-04 13:38:19 -05:00
COOKIE_SECURE=true
2026-05-03 20:02:32 -05:00
CORS_ORIGIN=https://bills.example.com
2026-05-15 22:45:38 -05:00
CSRF_HTTP_ONLY=false
CSRF_SAME_SITE=strict
CSRF_SECURE=true
CSRF_COOKIE_NAME=bt_csrf_token
2026-05-03 20:02:32 -05:00
```
2026-05-15 22:52:28 -05:00
OIDC fallback environment variables are used when matching Admin database settings are blank:
2026-05-03 20:02:32 -05:00
```bash
2026-05-04 13:38:19 -05:00
OIDC_PROVIDER_NAME=authentik
2026-05-15 22:52:28 -05:00
OIDC_ISSUER_URL=https://auth.example.com/application/o/bills/.well-known/openid-configuration
2026-05-04 13:38:19 -05:00
OIDC_CLIENT_ID=<client-id>
OIDC_CLIENT_SECRET=<client-secret>
OIDC_TOKEN_AUTH_METHOD=client_secret_basic
2026-05-03 20:02:32 -05:00
OIDC_REDIRECT_URI=https://bills.example.com/api/auth/oidc/callback
OIDC_SCOPES="openid email profile groups"
OIDC_ADMIN_GROUP=bill-tracker-admins
OIDC_AUTO_PROVISION=true
```
2026-05-04 13:38:19 -05:00
Database-backed Admin settings take precedence over environment fallback values.
2026-05-15 22:52:28 -05:00
## Reverse Proxy And HTTPS
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
Run BillTracker behind HTTPS for normal use. If TLS terminates at a reverse proxy, forward:
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
```text
X-Forwarded-Proto: https
```
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
Recommended production posture:
2026-05-15 22:52:28 -05:00
```bash
HTTPS=true
COOKIE_SECURE=true
CSRF_SECURE=true
CSRF_SAME_SITE=strict
```
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
For plain HTTP development only, you may need:
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
```bash
CSRF_SECURE=false
COOKIE_SECURE=false
```
2026-05-09 13:03:36 -05:00
2026-05-15 22:52:28 -05:00
Leave `CORS_ORIGIN` unset for normal same-origin deployments. Set it only if the frontend and backend are intentionally served from different origins.
2026-05-09 13:03:36 -05:00
2026-05-15 22:52:28 -05:00
## Security Notes
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
- Auth is required for user data routes.
- Admin routes require an admin session.
- User-owned bill, category, payment, import, export, and settings routes derive ownership from the authenticated session.
- CSRF uses a double-submit cookie pattern. The SPA reads `bt_csrf_token` with `document.cookie` and sends it as `x-csrf-token` on mutating requests.
- Do not set `CSRF_HTTP_ONLY=true` for this SPA unless token delivery changes.
- Session cookies are HTTP-only and SameSite-protected.
- Password changes rotate the current session and invalidate other sessions.
- Rate limits protect local login, password changes, imports, exports, admin actions, and OIDC routes.
- Security headers include CSP nonces and standard hardening headers.
- Audit logging records security-sensitive events such as login, logout, password changes, role changes, CSRF failures, and migration operations.
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
Backups and exports can contain sensitive financial data. The app writes SQLite backup files with restrictive permissions, but backup/export encryption is not implemented. Protect downloaded files and mounted volumes yourself.
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
## Upgrading
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
For a Node install:
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
```bash
git pull
npm install
npm run build
npm start
2026-05-03 20:02:32 -05:00
```
2026-05-15 22:52:28 -05:00
Restart your process manager after building.
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
For Docker:
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
```bash
docker compose pull
docker compose up -d
```
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
If you build locally, rebuild the image and recreate the container.
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
The app initializes the schema and runs additive migrations on startup. The Docker entrypoint also runs `scripts/migrate-db.js` before starting unless:
2026-05-04 13:38:19 -05:00
2026-05-15 22:52:28 -05:00
```bash
RUN_DB_MIGRATIONS=false
```
2026-05-04 13:38:19 -05:00
## Project Structure
```text
client/ React app, pages, layout, UI components
db/ SQLite connection, schema, startup migrations
middleware/ auth checks, CSRF, rate limits, security headers
2026-05-04 13:38:19 -05:00
routes/ Express API routes
2026-05-15 22:52:28 -05:00
services/ auth, OIDC, backups, imports, cleanup, status, audit logic
workers/ background tasks
setup/ first-run admin setup
scripts/ migrations, seed data, smoke/import tests
docs/ technical references and integration guides
2026-05-04 13:38:19 -05:00
```
2026-05-15 22:52:28 -05:00
## Documentation
2026-05-03 20:02:32 -05:00
2026-05-15 22:52:28 -05:00
- [HISTORY.md](HISTORY.md): release history
- [CSRF-SPA-Setup.md](docs/CSRF-SPA-Setup.md): CSRF behavior for the SPA
- [Authentik-Integration.md](docs/Authentik-Integration.md): authentik/OIDC setup
- [Engineering_Reference_Manual.md](docs/Engineering_Reference_Manual.md): deeper implementation reference
2026-05-03 20:02:32 -05:00
2026-05-04 13:38:19 -05:00
## Known Limitations
2026-05-03 20:02:32 -05:00
2026-05-04 13:38:19 -05:00
- Admin backups and user exports are not encrypted by the app.
2026-05-15 22:52:28 -05:00
- Bank sync is not implemented.
2026-05-04 13:38:19 -05:00
- OIDC single logout is not implemented.
- Rate limiting is in-memory, so counters reset on restart and are not shared across multiple app instances.
2026-05-15 22:52:28 -05:00
- Multiple OIDC providers are not currently supported.
- The XLSX parser dependency has known upstream security advisories; import routes are authenticated, file-size limited, and parse spreadsheet cells as data.
2026-05-03 20:02:32 -05:00
## License
License: Not specified.