Billmanager
A vibe-coded app to track your monthly bills and subscriptions
Install / Use
/learn @brdweb/BillmanagerREADME
BillManager - Financial Tracker
A secure multi-user web application for tracking recurring expenses and income with complete data separation. Built with React + Mantine frontend and Flask + PostgreSQL backend.

🎉 What's New in v4.0.2
Social Login & Two-Factor Authentication - Sign in with Google, Apple, Microsoft, or your own OIDC provider. Protect your account with email OTP or passkey-based two-factor authentication.
Highlights
- Social Login (OIDC) - Connect Google, Apple, Microsoft, or custom OIDC providers for one-click sign-in
- Two-Factor Authentication - Email OTP and passkey (WebAuthn) support for account security
- Recovery Codes - Backup access codes in case you lose your 2FA device
- Linked Accounts - Manage connected OAuth providers from your Security Settings
- Security Hardened - ID token signature verification, state replay protection, cryptographic OTP generation
Features
- Income & Expense Tracking: Track both recurring bills and deposits to forecast cash flow
- Account Management: Organize transactions by account with intelligent filtering
- Payment Analytics: Visual charts and comprehensive payment history across all transactions
- Multi-Tenant Architecture: Row-level data isolation with granular user permissions
- Enhanced Frequencies: Weekly, bi-weekly, monthly (including 1st & 15th), quarterly, yearly, and custom schedules
- Auto-Payments: Automatic payment processing for recurring transactions
- Modern UI: Responsive design with dark/light mode, 70+ custom icons, and visual calendar
- Mobile App: Native iOS and Android apps with offline support and push notifications
- Email Invitations: Invite users via email with configurable roles and access control
- Bill Groups: Organize finances into separate groups (personal, business, family, etc.)
- Bill Sharing: Share bills with other users and split costs by percentage, fixed amount, or equally
License
This project is licensed under the O'Saasy License - a modified MIT license that permits broad use while restricting SaaS commercialization by third parties.
Learn more at osaasy.dev
Quick Start
Prerequisites
- Docker and Docker Compose installed
- Web browser
Developer Workflow
For local development in WSL or Linux, the repo now includes a small task runner:
make bootstrap
make dev-up
make test
What these commands do:
make bootstrapcreates.venv, installs backend Python dependencies, and runsnpm ciinapps/webandapps/mobilemake dev-upbuilds and starts the local Docker stack fromdocker-compose.dev.ymlmake testruns backend, web, and mobile testsmake verifyruns the full test suite plus backend security checks
Useful day-to-day commands:
make dev-ps
make dev-logs
make dev-down
make test-db-up
make test-db-down
Run the Application
-
Create a
docker-compose.ymlfile with the following content:services: bills-app: image: ghcr.io/brdweb/billmanager:latest container_name: billmanager ports: - "5000:5000" restart: unless-stopped environment: - DATABASE_URL=postgresql://billsuser:billspass@db:5432/billsdb - FLASK_SECRET_KEY=change-this-to-a-secure-random-string depends_on: - db db: image: postgres:16-alpine container_name: bills-db restart: unless-stopped environment: - POSTGRES_USER=billsuser - POSTGRES_PASSWORD=billspass - POSTGRES_DB=billsdb volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data: -
Run the application:
docker compose up -d -
Open your browser and visit: http://localhost:5000
Using Your Own PostgreSQL Database
If you already have a PostgreSQL server or prefer to use a managed database service (AWS RDS, DigitalOcean, Supabase, etc.), you can run just the application container:
-
Create your database on your PostgreSQL server:
CREATE DATABASE billsdb; CREATE USER billsuser WITH ENCRYPTED PASSWORD 'your-secure-password'; GRANT ALL PRIVILEGES ON DATABASE billsdb TO billsuser; -
Create a simplified
docker-compose.yml:services: bills-app: image: ghcr.io/brdweb/billmanager:latest container_name: billmanager ports: - "5000:5000" restart: unless-stopped environment: - DATABASE_URL=postgresql://billsuser:your-secure-password@your-db-host:5432/billsdb - FLASK_SECRET_KEY=change-this-to-a-secure-random-string -
Or run with Docker directly:
docker run -d \ --name billmanager \ -p 5000:5000 \ -e DATABASE_URL=postgresql://billsuser:your-secure-password@your-db-host:5432/billsdb \ -e FLASK_SECRET_KEY=change-this-to-a-secure-random-string \ ghcr.io/brdweb/billmanager:latest
Database URL Format:
postgresql://USERNAME:PASSWORD@HOST:PORT/DATABASE
| Component | Example | Description |
|-----------|---------|-------------|
| USERNAME | billsuser | PostgreSQL username |
| PASSWORD | secretpass | PostgreSQL password (URL-encode special characters) |
| HOST | db.example.com | Database server hostname or IP |
| PORT | 5432 | PostgreSQL port (default: 5432) |
| DATABASE | billsdb | Database name |
Examples:
- Local:
postgresql://billsuser:pass@localhost:5432/billsdb - Remote:
postgresql://billsuser:pass@db.example.com:5432/billsdb - AWS RDS:
postgresql://billsuser:pass@mydb.abc123.us-east-1.rds.amazonaws.com:5432/billsdb - Supabase:
postgresql://postgres:pass@db.xxxx.supabase.co:5432/postgres
Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| DATABASE_URL | PostgreSQL connection string | postgresql://billsuser:billspass@db:5432/billsdb |
| FLASK_SECRET_KEY | Secret key for session encryption | Required in production |
| JWT_SECRET_KEY | Secret key for mobile API tokens | Falls back to FLASK_SECRET_KEY |
| RESEND_API_KEY | Email provider API key (enables invitations) | None |
| FROM_EMAIL | Sender email address | None |
| APP_URL | Application URL for email links | http://localhost:5000 |
| ALLOWED_ORIGINS | Comma-separated list of allowed CORS origins | Uses APP_URL or localhost |
| DEPLOYMENT_MODE | self-hosted or saas | self-hosted |
| ENABLE_2FA | Enable two-factor authentication flows | false |
| ENABLE_PASSKEYS | Enable passkey (WebAuthn) support | false |
| WEBAUTHN_RP_ID | WebAuthn relying party ID (domain only) | Derived from APP_URL |
| WEBAUTHN_RP_NAME | WebAuthn relying party display name | BillManager |
| WEBAUTHN_ORIGIN | WebAuthn origin (must match app origin) | APP_URL |
| OAUTH_AUTO_REGISTER | Auto-create users during social sign-in | false |
| OAUTH_GOOGLE_ENABLED | Enable Google sign-in | false |
| OAUTH_GOOGLE_CLIENT_ID | Google OAuth client ID | None |
| OAUTH_GOOGLE_CLIENT_SECRET | Google OAuth client secret | None |
| OAUTH_APPLE_ENABLED | Enable Apple sign-in | false |
| OAUTH_APPLE_CLIENT_ID | Apple Services ID (client ID) | None |
| OAUTH_APPLE_TEAM_ID | Apple Developer Team ID | None |
| OAUTH_APPLE_KEY_ID | Apple Sign in with Apple key ID | None |
| OAUTH_APPLE_PRIVATE_KEY | Apple private key (.p8, multiline or \n escaped) | None |
| OAUTH_MICROSOFT_ENABLED | Enable Microsoft sign-in | false |
| OAUTH_MICROSOFT_CLIENT_ID | Microsoft OAuth client ID (Azure AD app registration) | None |
| OAUTH_MICROSOFT_CLIENT_SECRET | Microsoft OAuth client secret | None |
| OAUTH_MICROSOFT_TENANT_ID | Azure AD tenant ID (common for multi-tenant, or specific tenant GUID) | common |
| OAUTH_OIDC_ENABLED | Enable generic OIDC sign-in (for Authentik, Authelia, Keycloak, etc.) | false |
| OAUTH_OIDC_CLIENT_ID | OIDC provider client ID | None |
| OAUTH_OIDC_CLIENT_SECRET | OIDC provider client secret | None |
| OAUTH_OIDC_DISCOVERY_URL | OIDC provider discovery URL (.well-known/openid-configuration) | None |
| OAUTH_OIDC_DISPLAY_NAME | Display name shown on login button | SSO |
| OAUTH_OIDC_ICON | Icon name for login button (Tabler icon without Icon prefix) | lock |
| OAUTH_OIDC_SCOPES | OAuth scopes to request | openid email profile |
| OAUTH_OIDC_EMAIL_CLAIM | Claim name for user's email address | email |
| OAUTH_OIDC_USERNAME_CLAIM | Claim name for username | preferred_username |
| OAUTH_OIDC_NAME_CLAIM | Claim name for display name | name |
| OAUTH_OIDC_SKIP_EMAIL_VERIFICATION | Skip email verification check (for providers that don't include email_verified) | false |
Security Note: In production, JWT_SECRET_KEY or FLASK_SECRET_KEY must be explicitly set. The application will refuse to start without it. Generate secure keys with: openssl rand -hex 32
CORS Configuration
BillManager uses a three-tier priority system for CORS origins:
ALLOWED_ORIGINS- Explicit comma-separated list (e.g.,https://app1.com,https://app2.com)APP_URL- Single origin for typical deployments- Localhost defaults - For development without configuration
This ensures secure self-hosted deployments while remaining flexible for development.
2FA and Social Login Notes
- For passkeys in production, set
ENABLE_2FA=true,ENABLE_PASSKEYS=true,WEBAUTHN_RP_ID, andWEBAUTHN_ORIGIN. - For Apple sign-in,
OAUTH_APPLE_PRIVATE_KEYmay be provided as a single line with\nescapes. - OAuth callback URL for Google/Apple should be:
https://<your-domain>/auth/callback. - For Microsoft sign-in, register an app in Azure AD and set redirect URI to:
https://<your-domain>/auth/callback - For generic OIDC, set `
Related Skills
node-connect
343.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
92.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
343.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
343.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
