A simple Flask web application to track and record the books you've read.
Who is this app for?
- Primarily aimed at self-hosting book lovers who want a private, secure way to log their reading history without relying on third-party services. Should you self host this app please know it does not track you in any way, shape or form. No analytics, no ads, no tracking scripts. Just you and your books.
- β Add books you've read with title, author, and date
- π Auto-lookup book info from ISBN - Automatically fetch title, author, and genre using Open Library API
- πΌοΈ Book covers - Display cover images from Open Library with automatic ISBN lookup
- π Multiple formats - Track physical books, ebooks, and audiobooks
- β Rate books on a 1-5 star scale
- π·οΈ Genre/categories - Organize books by genre
- π Add personal notes and thoughts about each book
- βοΈ Edit book entries
- ποΈ Delete books from your collection
- π View all your books in a beautiful grid layout
- π To-Be-Read (TBR) tracking - Organize books into "To Read", "Currently Reading", and "Read" statuses
- π Password-less account recovery - Recover accounts using recovery codes (no email required)
- π Multi-Factor Authentication (MFA) - Optional TOTP-based 2FA for enhanced security
- βοΈ Account settings - Change email address with password verification
- π¨ Warm library aesthetic - Cosy, literary-inspired design with warm browns and serif typography
- βΏ Accessible design - WCAG AA/AAA compliant color contrast and responsive layouts
This application requires Docker and Docker Compose. All other setup is handled automatically by the container.
-
Clone the project:
git clone https://github.com/pagyP/booknook.git cd booknook -
Set environment variables:
cp .env.example .env # Edit .env and set SQLALCHEMY_DATABASE_URI and SECRET_KEY -
Start the application (builds from local Dockerfile):
docker compose up -d
-
Open your browser and navigate to
http://localhost:8000
-
Database Setup:
The application uses PostgreSQL. For local development, the easiest option is to use Docker:
docker compose up -d db
Or configure a local PostgreSQL instance and add to your
.env:SQLALCHEMY_DATABASE_URI=postgresql+psycopg://username:password@localhost:5432/booknook
Note: PostgreSQL is required for all environments. There is no SQLite fallback.
For users who want to run the pre-built image from GitHub Container Registry:
-
Create environment file:
# Create .env with your database configuration DB_USER=booknook DB_PASSWORD=<change-to-secure-password> DB_NAME=booknook SECRET_KEY=<generate-with-python> FLASK_ENV=production SESSION_COOKIE_SECURE=True
-
Start the application (uses pre-built image):
docker compose -f docker-compose.prod.yml up -d
-
Open your browser and navigate to:
http://localhost:8000Note: The development server runs on port 5000 by default. When using Docker (production), the app runs on port 8000 via Gunicorn.
-
Open your browser and navigate to
http://localhost:8000
Note: Database schema is created automatically on startup via init_db.py. If you're upgrading from a version created before the MFA feature, see DOCKER_DEPLOYMENT.md for schema migration instructions.
For detailed Docker and production deployment instructions, see DOCKER_DEPLOYMENT.md.
β
User Authentication - Create accounts with secure password hashing
β
Password Hashing - Passwords hashed using Argon2 (memory-hard, GPU-resistant)
β
Multi-Factor Authentication - Optional TOTP-based 2FA using authenticator apps (Google Authenticator, Authy, etc.)
β
Trusted Devices - Mark devices as trusted for 30 days to reduce MFA prompts
β
Account Recovery - Recover lost passwords using single-use recovery codes (no email required)
β
Session Management - Secure session handling with Flask-Login and 24-hour persistent timeout
β
CSRF Protection - All forms protected with CSRF tokens via Flask-WTF
β
Data Isolation - Users can only see and edit their own books
β
Environment Variables - Secret key stored in .env (not committed to git)
β
Form Validation - Email format and password confirmation validation
β
Rate Limiting - Login attempts limited to 5 per minute to prevent brute force; email changes limited to 10 per hour
β
Security Logging - All authentication events logged for audit trail
β
Email Security - Email display on signup prevents user lockout from typos; settings page allows secure email changes with password verification
β
Accessibility - WCAG AA/AAA color contrast standards for inclusive design (7:1+ contrast ratios)
booknook/
βββ app.py # Main Flask application and routes
βββ init_db.py # Database initialization script
βββ requirements.txt # Python dependencies
βββ README.md # This file
βββ .gitignore # Git ignore rules
βββ LICENSE # MIT License
βββ Dockerfile # Docker container definition
βββ docker-compose.yml # Docker Compose for development
βββ docker-compose.prod.yml # Docker Compose for production
βββ nginx.conf # Nginx configuration for production
βββ DOCKER_DEPLOYMENT.md # Docker and deployment guide
βββ RECOVERY_CODES.md # Password recovery documentation
βββ RECOVERY_CODE_SECURITY.md # Recovery code security details
βββ SECURITY_HARDENING.md # Security best practices
βββ OPEN_LIBRARY_INTEGRATION.md # ISBN lookup feature guide
βββ MFA_FEATURE_IMPLEMENTATION.md # Multi-factor authentication guide
βββ TBR_FEATURE_IMPLEMENTATION.md # To-Be-Read feature implementation
βββ QUICK_START_TBR.md # TBR quick start guide
βββ TEST_TBR_FEATURE.md # TBR testing guide
βββ TBR_TESTS_DOCUMENTATION.md # TBR test coverage
βββ static/
β βββ images/
β βββ cosy-library.jpg # Background image
βββ templates/
β βββ base.html # Base template with styling
β βββ index.html # Home page (book list)
β βββ login.html # Login page
β βββ register.html # Registration page
β βββ add_book.html # Form to add a new book
β βββ edit_book.html # Form to edit a book
β βββ settings.html # Account settings (email change)
β βββ mfa_setup.html # MFA setup page
β βββ mfa_verify.html # MFA verification page
β βββ disable_mfa.html # MFA disable page
β βββ trusted_devices.html # Trusted devices management
β βββ recovery_codes.html # Display recovery codes
β βββ forgot_password.html # Password recovery entry point
β βββ reset_password.html # Password reset form
β βββ isbn_lookup_script.html # ISBN lookup helper
βββ tests/
βββ conftest.py # Pytest configuration
βββ test_app.py # Comprehensive test suite (83 tests)
βββ test_mfa.py # MFA-specific tests (18 tests)
βββ test_genres.py # Genre filtering tests (1 test)
βββ __init__.py
- Click "Sign Up" in the top navigation
- Enter a username, email, and password
- Confirm your password and submit
- You'll be redirected to log in with your new account
- Click "Log In" on the home page
- Enter your email and password
- You'll be logged in and can start adding books
- Your session will persist for 24 hours even if you close your browser
- Click "Settings" in the top navigation (when logged in)
- View your registered email address
- To change your email: Enter your new email and confirm your password
- Email changes are rate-limited to 10 per hour for security
- Your new email will be used for future logins
- Click "Logout" in the top right navigation
- On the login page, click "Recover your account"
- Enter your email address and one of your recovery codes (saved during account creation)
- Set a new password
- Log in with your new password
- Click "+ Add Book" in the navigation
- Fill in the book details (title and author are required)
- Optionally add ISBN, genre, format, and rating
- Add notes about your thoughts on the book
- Click "Save Book"
- On the home page, click "Edit" on any book card
- Modify the details as needed
- Click "Update Book"
- On the home page, click "Delete" on any book card
- Confirm the deletion
Warm Library Aesthetic - The application features a cosy, literary-inspired design with:
- Warm color palette (cream, brown, gold) evoking a personal library
- Georgia serif typography for a literary feel
- Responsive grid layout for books
- Bookshelf background with adjustable opacity
Accessibility Standards - Meets WCAG AA/AAA compliance:
- 7:1+ color contrast ratios for text readability
- Responsive design that works on all device sizes
- Semantic HTML structure
- Form validation with clear error messages
- Rate limiting to prevent user frustration from failed attempts
- MFA_FEATURE_IMPLEMENTATION.md - Multi-factor authentication setup and usage
- RECOVERY_CODES.md - Complete guide to password recovery using recovery codes
- RECOVERY_CODE_SECURITY.md - Recovery code security enhancements
- SECURITY_HARDENING.md - Security implementation details and best practices
- OPEN_LIBRARY_INTEGRATION.md - ISBN lookup and auto-fill feature guide
- DOCKER_DEPLOYMENT.md - Docker and production deployment guide
- TBR_FEATURE_IMPLEMENTATION.md - To-Be-Read feature implementation details
- QUICK_START_TBR.md - Quick start guide for TBR feature
- TEST_TBR_FEATURE.md - Testing guide for TBR feature
- TBR_TESTS_DOCUMENTATION.md - TBR test coverage documentation
Consider adding:
- Reading progress tracking (percentage complete, pages read)
- Statistics and reading goals (yearly targets, reading streaks)
- Email notifications for security events
- Book recommendations based on reading history
- Export reading history (CSV, PDF)
- Social features (share lists, follow other readers)
- Book club features
- Date range filtering (by date_added)
- Backend: Flask 3.1.2 (Python web framework)
- Database: PostgreSQL 18.1 (required)
- ORM: SQLAlchemy 3.0.5
- Authentication: Flask-Login 0.6.3, Flask-WTF 1.2.1
- Password Hashing: Argon2-cffi 25.1.0 (memory-hard hashing)
- Rate Limiting: Flask-Limiter 4.1.1
- Frontend: HTML5, CSS3 (responsive design)
- Testing: Pytest 7.4.4 (102 tests: 83 in test_app.py, 18 in test_mfa.py, 1 in test_genres.py)
- Containerization: Docker & Docker Compose (required)
- Deployment: Gunicorn 22.0.0, Nginx
Feel free to use and modify this project!
