derekc 59f9685e2b Move JWT from localStorage to HttpOnly cookie; fix CSRF
- JWT stored in HttpOnly, Secure, SameSite=Strict cookie — JS cannot
  read the token at all; SameSite=Strict prevents CSRF without tokens
- Non-sensitive user payload returned in response body and stored in
  localStorage for UI purposes only (not usable for auth)
- Add POST /api/auth/logout endpoint that clears the cookie server-side
- Add SECURE_COOKIES env var (default true) for local HTTP testing
- Extract login.html inline script to login.js (CSP compliance)
- Remove Authorization: Bearer header from API calls; add credentials:
  include so cookies are sent automatically
- CSP script-src includes unsafe-inline to support existing onclick
  handlers throughout the app

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:57:22 -07:00
2026-02-26 22:27:58 -08:00

🥚 Yolkbook

A self-hosted, multi-user web app for backyard chicken keepers to track egg production, flock size, feed costs, and egg economics over time.

Features

  • Dashboard — at-a-glance stats: total eggs, 7/30-day totals, averages (green), flock size (orange), cost per egg and per dozen
  • Daily log — record egg collections with one entry per day; includes full collection history with date filtering, edit, and delete below the form
  • Flock management — track changes to your flock size over time so per-hen averages stay accurate
  • Feed tracking — log feed purchases (bags + price per bag)
  • Budget — cost per egg and cost per dozen, all-time and over the last 30 days
  • Monthly summary — month-by-month breakdown of production, averages, feed cost, and cost per egg
  • Multi-user — each user has their own isolated data; self-registration on the login page
  • Admin panel — view all users, reset passwords, disable/enable accounts, delete accounts, and log in as any user
  • Timezone support — each user sets their own timezone so dates and stat windows are always accurate

Tech Stack

Layer Technology
Frontend Vanilla HTML/CSS/JS
Backend FastAPI (Python)
Database MySQL 8.0
Server Nginx (static + proxy)
Runtime Docker Compose

Getting Started

Prerequisites

  • Docker and Docker Compose

Setup

  1. Clone the repo:

    git clone https://git.chns.tech/CooperandGoodman/yolkbook.git
    cd yolkbook
    
  2. Create a .env file in the project root:

    # MySQL
    MYSQL_ROOT_PASSWORD=your_root_password
    MYSQL_DATABASE=eggtracker
    MYSQL_USER=eggtracker
    MYSQL_PASSWORD=your_db_password
    
    # Super admin account (created/synced automatically on every startup)
    ADMIN_USERNAME=admin
    ADMIN_PASSWORD=your_admin_password
    
    # JWT signing secret — generate with: openssl rand -hex 32
    JWT_SECRET=your_long_random_secret
    
  3. Start the stack:

    docker compose up -d --build
    
  4. Open your browser at http://localhost:8056/login and sign in with the admin credentials you set in .env.

The database schema is applied automatically on first start via mysql/init.sql. The admin user is created (or synced) automatically every time the API starts.

Authentication

  • Login / Register — the landing page (/login) has both a sign-in form and a self-registration link so users can create their own accounts.
  • JWT tokens — stored in localStorage, valid for 30 days.
  • Admin password — always sourced from the ADMIN_PASSWORD env var. Changing it in .env and restarting will update the admin's password.

Admin Panel

Accessible at /admin for admin accounts. Features:

Action Description
Reset password Set a new password for any user
Disable / Enable Block or restore a user's access
Delete Permanently remove a user and all their data
Login As Impersonate a user to view or edit their data directly

When impersonating a user, an amber banner appears in the nav with a Return to Admin button.

User Settings

The gear icon (⚙) in the top-right nav opens the Settings panel:

  • Timezone — choose from a full list of IANA timezones or click Detect automatically. Affects what "today" is when pre-filling date fields and the 30-day/7-day windows on the dashboard and budget pages.
  • Change Password — update your own password (requires current password).

Migrating an Existing Install (pre-multi-user)

If you have an existing single-user install, run the migration script before rebuilding:

# 1. Run the migration while the database is still running
docker compose exec db mysql -u root -p"${MYSQL_ROOT_PASSWORD}" eggtracker < mysql/migrate_v2.sql

# 2. Rebuild and restart
docker compose up -d --build

All existing data will be automatically assigned to the admin account on first startup.

API

The FastAPI backend is available at /api. Interactive docs (Swagger UI) are at /api/docs.

Prefix Description
/api/auth Login, register, change password, timezone
/api/admin User management (admin only)
/api/eggs Egg collection records
/api/flock Flock size history
/api/feed Feed purchase records
/api/other Other purchases (bedding, snacks, etc.)
/api/stats Dashboard, budget, and monthly summary

All data endpoints require a valid JWT (Authorization: Bearer <token>). Data is always scoped to the authenticated user.

Project Structure

yolkbook/
├── backend/
│   ├── main.py           # FastAPI app entry point + startup seeding
│   ├── auth.py           # JWT utilities, password hashing, auth dependencies
│   ├── models.py         # SQLAlchemy models
│   ├── schemas.py        # Pydantic schemas
│   ├── database.py       # DB connection
│   ├── routers/
│   │   ├── auth_router.py  # /api/auth — login, register, settings
│   │   ├── admin.py        # /api/admin — user management
│   │   ├── eggs.py
│   │   ├── flock.py
│   │   ├── feed.py
│   │   ├── other.py
│   │   └── stats.py
│   ├── requirements.txt
│   └── Dockerfile
├── nginx/
│   ├── html/             # Frontend (HTML, CSS, JS)
│   │   ├── login.html
│   │   ├── admin.html
│   │   ├── index.html    # Dashboard
│   │   ├── log.html      # Log Eggs + full collection history
│   │   ├── js/
│   │   │   ├── api.js      # Shared fetch helpers
│   │   │   ├── auth.js     # Auth utilities, nav, settings modal
│   │   │   ├── history.js  # Collection history table (used on log page)
│   │   │   └── dashboard.js
│   │   └── css/style.css
│   └── nginx.conf
├── mysql/
│   ├── init.sql          # Schema for fresh installs
│   └── migrate_v2.sql    # Migration for pre-multi-user installs
├── docker-compose.yml
└── .env                  # Secrets — not committed
Description
A self-hosted web app for backyard chicken keepers to track egg production, flock size, feed costs, and egg economics over time.
Readme 320 KiB
Languages
JavaScript 38.9%
Python 33.9%
HTML 18.1%
CSS 8.9%
Dockerfile 0.2%