SkillAgentSearch skills...

Billmanager

A vibe-coded app to track your monthly bills and subscriptions

Install / Use

/learn @brdweb/Billmanager
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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.

BillManager Screenshot


🎉 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 bootstrap creates .venv, installs backend Python dependencies, and runs npm ci in apps/web and apps/mobile
  • make dev-up builds and starts the local Docker stack from docker-compose.dev.yml
  • make test runs backend, web, and mobile tests
  • make verify runs 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

  1. Create a docker-compose.yml file 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:
    
  2. Run the application:

    docker compose up -d
    
  3. 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:

  1. 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;
    
  2. 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
    
  3. 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:

  1. ALLOWED_ORIGINS - Explicit comma-separated list (e.g., https://app1.com,https://app2.com)
  2. APP_URL - Single origin for typical deployments
  3. 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, and WEBAUTHN_ORIGIN.
  • For Apple sign-in, OAUTH_APPLE_PRIVATE_KEY may be provided as a single line with \n escapes.
  • 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

View on GitHub
GitHub Stars54
CategoryDevelopment
Updated1d ago
Forks7

Languages

TypeScript

Security Score

80/100

Audited on Mar 30, 2026

No findings