Files
bookhoard/README.md
T
john-okeefe b5d57f5c8a docs(readme): update security features documentation
- Document password complexity requirements
- Document account lockout mechanism (5 attempts, 15 min)
- Update JWT expiration to 1 hour
- Add refresh token documentation (7-day expiration)
- Add token management endpoints
- Enhance security features section
- Document standardized error responses
2026-01-29 09:23:34 -05:00

440 lines
16 KiB
Markdown

# 📚 Bookmann
A modern self-hosted media library system built with Go, PostgreSQL, HTMX, and Tailwind CSS featuring multiple library support, beautiful dark themes, and comprehensive media management.
## ✨ Features
### 🏗 Multi-Library System
- **Multiple Media Types**: Support for Ebooks, Comics, and Manga with modular architecture
- **Per-Library Folders**: Each library can have multiple scanning folders for flexible organization
- **Library Visibility Control**: Admins can control which libraries are visible to each user
- **Type-Specific File Extensions**:
- **Ebooks**: `.epub`, `.pdf`, `.mobi`, `.azw`, `.azw3`, `.txt`, `.rtf`, `.doc`, `.docx`, `.lit`, `.fb2`, `.pdb`
- **Comics**: `.cbz`, `.cbr`, `.cb7`, `.cbt`, `.pdf`
- **Manga**: `.cbz`, `.cbr`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.bmp`, `.webp`
- **Easy Extension**: Designed to add new media types in the future
### 🔒 Authentication & Security
- **Multi-User Support**: Complete user registration and authentication system
- **JWT-Based Sessions**: Secure token-based authentication with 1-hour expiration and refresh token support
- **Role-Based Access**: Admin and user roles with granular permission control
- **Password Security**: bcrypt hashing with complex password requirements:
- Minimum 8 characters
- At least one uppercase letter (A-Z)
- At least one lowercase letter (a-z)
- At least one number (0-9)
- At least one special character (!@#$%^&*()_+-=[]{}|;':\",./<>?)
- **Account Lockout**: Automatic account lockout after 5 failed login attempts (15-minute lockout period)
- **Rate Limiting**: Built-in rate limiting on auth endpoints (10 requests/minute) to prevent brute force attacks
- **Refresh Tokens**: Secure refresh token mechanism (7-day expiration) for seamless token renewal
- **Input Validation**: Comprehensive validation including username whitespace checks, email format validation
- **Pagination Protection**: Maximum pagination limits (1000 items) to prevent DoS attacks
- **Path Validation**: Library folder paths are validated for existence and accessibility
- **Case-Insensitive Roles**: Role values automatically normalized to lowercase
- **Database Transactions**: Multi-step database operations use transaction support for data consistency
- **Standardized Error Responses**: Consistent error format across all API endpoints
### 🎨 Beautiful UI
- **11 Dark Themes**: Tokyo Night, Dracula, Nord, Solarized Dark, Monokai, One Dark Pro, Material Dark, Catppuccin variants
- **Theme Persistence**: User theme preferences saved to database
- **Mobile-First Design**: Fully responsive interface for all devices
- **HTMX Integration**: Dynamic interactions without page reloads
### 📱 Media Management
- **Universal Media Support**: Single system for all media types with unified interface
- **Rich Metadata**: Automatic extraction of title, author, series, publisher, ISBN, tags
- **Advanced Rating**: 5-star system with half-star precision (1-10 scale)
- **Reading Progress**: User-specific progress tracking with current page and total pages
- **Notes & Highlights**: Personal annotations and text highlighting with color customization
- **Highlight Notes**: Link highlights to detailed notes for comprehensive annotations
- **Library Statistics**: Media count and usage statistics per library
## 🚀 Quick Start
### Prerequisites
- Docker and Docker Compose
- PostgreSQL database (handled by Docker)
### Environment Setup
1. **Create .env file**:
```bash
cp .env.example .env
```
2. **Edit .env** with your secure values:
```bash
JWT_SECRET="your-secure-jwt-secret-key-here"
DBPASS="your-secure-database-password-here"
```
### Running the Application
```bash
# Option 1: Using .env file
docker-compose up --build
# Option 2: Direct environment variables
export JWT_SECRET="your-secure-jwt-secret-key-here"
export DBPASS="your-secure-database-password-here"
docker-compose up --build
```
Access the application at: **http://localhost:8765**
## 👤 User Management
### Role System
- **Admin Users**: Can create/manage libraries, add/delete media items, manage users
- **Regular Users**: Can view permitted libraries, rate items, track reading progress
### First Admin Setup
The first user who registers automatically becomes an admin. For additional admins:
```sql
-- Connect to database
docker exec -it bookmann_db psql -U postgres -d bookmann
-- Promote user to admin
UPDATE users SET role = 'admin' WHERE email = 'user@example.com';
```
## 🏛 Library Management
### Creating Libraries
1. **Admin Access**: Only administrators can create libraries
2. **Library Types**: Choose from Ebooks, Comics, or Manga
3. **Multi-Folder Support**: Add multiple scanning folders per library
4. **Folder Organization**: Organize your media collection across multiple paths
### Library Visibility Control
- **Admin Dashboard**: Complete interface for managing library access
- **User-Specific Control**: Admins can show/hide libraries per user
- **Personal Preferences**: Admins can also hide libraries from their own view
- **Simple Toggles**: Checkbox-based interface for easy management
### API Endpoints
#### Notes & Highlights (All Authenticated Users)
```bash
# Media Notes
GET /api/media-items/{id}/notes # Get user's notes for media
POST /api/media-items/{id}/notes # Create new note
GET /api/media-items/{id}/notes/{noteId} # Get specific note
PUT /api/media-items/{id}/notes/{noteId} # Update note
DELETE /api/media-items/{id}/notes/{noteId} # Delete note
# Media Highlights
GET /api/media-items/{id}/highlights # Get user's highlights for media
POST /api/media-items/{id}/highlights # Create new highlight
GET /api/media-items/{id}/highlights/{highlightId} # Get specific highlight
PUT /api/media-items/{id}/highlights/{highlightId} # Update highlight
DELETE /api/media-items/{id}/highlights/{highlightId} # Delete highlight
# Ebook Compatibility (Backward Compatible)
GET /api/ebooks/{id}/notes # Get user's notes for ebook
POST /api/ebooks/{id}/notes # Create new ebook note
PUT /api/ebooks/{id}/notes/{noteId} # Update ebook note
DELETE /api/ebooks/{id}/notes/{noteId} # Delete ebook note
GET /api/ebooks/{id}/highlights # Get user's highlights for ebook
POST /api/ebooks/{id}/highlights # Create new ebook highlight
PUT /api/ebooks/{id}/highlights/{highlightId} # Update ebook highlight
DELETE /api/ebooks/{id}/highlights/{highlightId} # Delete ebook highlight
```
#### Library Management (Admin Only)
```bash
# Create new library
POST /api/libraries
{
"name": "My Comic Collection",
"description": "Digital comics and graphic novels",
"type": "comics"
}
# List all libraries
GET /api/libraries
# Add folder to library
POST /api/libraries/{library_id}/folders
{
"folder_path": "/path/to/comics"
}
# Set library visibility for user
POST /api/libraries/visibility
{
"library_id": "library-uuid",
"is_visible": true
}
```
#### User Access
```bash
# Get user's visible libraries
GET /api/libraries/visible
# Browse media in library
GET /api/media-items?library_id={library_id}&limit=20&offset=0
# Media Progress & Ratings
GET /api/media-items/{id}/progress # Get reading progress
PUT /api/media-items/{id}/progress # Update reading progress
GET /api/media-items/{id}/rating # Get user rating
POST /api/media-items/{id}/rating # Create/update rating
PUT /api/media-items/{id}/rating # Update rating
DELETE /api/media-items/{id}/rating # Delete rating
# Token Management
POST /api/auth/refresh # Refresh access token
POST /api/auth/logout # Logout (revokes refresh token)
```
## 📖 Media Support
### Ebooks
- **Formats**: EPUB (full metadata), PDF, MOBI, AZW, TXT, DOC, FB2
- **Metadata**: Automatic extraction from EPUB files with Calibre support
- **Reading**: Built-in web reader for EPUB files
### Comics
- **Formats**: CBZ, CBR, CB7, CBT, PDF
- **Structure**: Archive-based organization with chapter support
- **Viewing**: Image extraction and web-based comic reader
### Manga
- **Formats**: CBZ, CBR (archives), PNG, JPG (image folders)
- **Structure**: Archive support with folder-based image organization
- **Viewing**: Chapter-by-chapter viewing with page navigation
## 🎨 Development
### Local Development
```bash
# Backend development
go mod tidy
go run cmd/server/main.go
# Frontend development
npm run dev
# Templates automatically recompile on changes
```
### Environment
- **Backend**: Go 1.25+ with pgx v5 for database operations
- **Frontend**: Tailwind CSS with HTMX for dynamic interactions
- **Database**: PostgreSQL 15+ with pgx v5 driver
- **Authentication**: JWT tokens with bcrypt password hashing
## 🐳 Deployment
### Docker Configuration
```yaml
# docker-compose.yml
services:
bookmann:
build: .
ports:
- "8765:8765"
environment:
- JWT_SECRET=${JWT_SECRET}
- DBHOST=db
depends_on:
- db
```
### Database Schema
- **Multi-Library Architecture**: Libraries, library types, folders, visibility tables
- **Annotations System**: Notes, highlights with position tracking and color customization
- **Backward Compatibility**: Views maintain existing API contracts for ebooks
- **Type Safety**: pgx v5 with proper error handling
- **Migration Ready**: Schema designed for easy future extensions
## 🧪 API Documentation
### Bruno Testing Collection
Complete API testing collection in `bruno/` directory:
```
bruno/
├── user/ # Authentication & profile endpoints
├── admin/ # Admin-only operations
├── library/ # Library management
├── media-items/ # Media content browsing
├── notes/ # Notes API testing
├── highlights/ # Highlights API testing
└── collection.bru # Main dashboard
```
### Authentication Flow
1. **Register**: `POST /api/auth/register` → JWT token
2. **Login**: `POST /api/auth/login` → JWT token
3. **Protected Routes**: Use `Authorization: Bearer {token}` header
### Error Handling
All API endpoints return standardized error responses:
```json
{
"error": "Error message",
"message": "Detailed error information (if available)",
"code": "Error code (if applicable)"
}
```
HTTP Status Codes:
- **400**: Bad request (validation errors)
- **401**: Unauthorized (invalid/missing token)
- **403**: Forbidden (insufficient permissions)
- **404**: Resource not found
- **429**: Too many requests (rate limit exceeded)
- **500**: Internal server error
## 🛡 Security Features
### Authentication & Authorization
- **JWT Tokens**:
- Short-lived access tokens (1-hour expiration)
- Refresh tokens (7-day expiration) for seamless session renewal
- Secure token storage and transmission
- **Password Security**:
- bcrypt hashing with cost factor 12
- Complex password requirements enforced
- Password validation on registration and updates
- **Account Protection**:
- Automatic lockout after 5 failed login attempts
- 15-minute lockout period with countdown
- IP-based and username-based attempt tracking
- **Rate Limiting**: 10 requests per minute on authentication endpoints
- **Input Validation**: Comprehensive server-side validation for all inputs
- **CSRF Protection**: Built-in with HTMX
- **Role-Based Access Control**: Admin and user roles enforced on all endpoints
### Authorization
- **Role-Based Access**: Admin vs user permissions
- **Library Visibility**: Per-user library access control
- **Admin Middleware**: Protected routes for admin operations
- **Content Security**: XSS protection and secure headers
### Database Security
- **Parameterized Queries**: SQL injection prevention with pgx v5
- **Connection Pooling**: Efficient database connection management
- **Transaction Support**: Multi-step operations wrapped in transactions
- **Environment Variables**: Secure secret management
- **Row-Level Security**: User data isolation
- **Secure Refresh Token Storage**: Encrypted token storage in database
- **Automatic Token Cleanup**: Expired tokens cleaned up periodically
## 🔧 Configuration
### Environment Variables
```bash
# Required
JWT_SECRET= # JWT signing secret (64-byte random string)
DBHOST=db # PostgreSQL database host
# Optional
SERVER_PORT=8765 # Application port
NODE_ENV=development # Environment mode
```
### Database Configuration
```sql
-- Library types are automatically seeded
INSERT INTO library_types (name, description, allowed_extensions) VALUES
('ebooks', 'Ebook files including EPUB, PDF, MOBI, etc.',
ARRAY['.epub', '.pdf', '.mobi', '.azw', '.azw3', '.txt', '.rtf', '.doc', '.docx', '.lit', '.fb2', '.pdb']),
('comics', 'Comic book archives and image formats',
ARRAY['.cbz', '.cbr', '.cb7', '.cbt', '.pdf']),
('manga', 'Manga files including archives and image folders',
ARRAY['.cbz', '.cbr', '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp']);
```
## 🧪 Testing
### API Testing
```bash
# Install Bruno
npm install -g @usebruno/cli
# Run tests
bruno run
```
### Unit Tests
```bash
go test ./...
```
## 📊 Architecture
### Backend
```
cmd/server/main.go # Application entry point
├── internal/
│ ├── config/ # Configuration management
│ ├── database/ # Database operations (SQLC generated)
│ │ ├── queries/ # SQL queries
│ │ └── models.go # Generated models
│ ├── handlers/ # HTTP handlers
│ │ ├── auth.go # Authentication & users
│ │ ├── library.go # Library management
│ │ └── ebook.go # Media operations
│ └── services/ # Business logic
│ └── library_service.go # Library service
templates/ # HTML templates with HTMX
```
### Database
```sql
libraries # Library definitions
library_types # Media type definitions (ebooks, comics, manga)
library_folders # Folders per library
library_visibility # User library access control
media_items # All media content (replaces ebooks table)
media_ratings # User ratings for media items
media_notes # User notes on media items
media_highlights # User highlights with optional note links
reading_progress # User reading progress
users # User accounts and profiles
# Backward Compatibility Views
ebook_notes # Notes view for ebook API compatibility
ebook_highlights # Highlights view for ebook API compatibility
```
## 🎯 Future Roadmap
### Media Type Extensions
- **Audiobooks**: Audio file support with chapter tracking
- **Podcasts**: RSS feed integration and automatic downloading
- **Video**: Movie/TV series management with metadata
- **Music**: Album and track management with artwork
### Advanced Features
- **Mobile App**: React Native mobile application
- **API v2**: GraphQL API for efficient data fetching
- **Webhooks**: External service integrations
- **Analytics**: Usage statistics and reporting
- **Backup/Restore**: Library backup and migration tools
## 📝 Contributing
### Development Guidelines
- Follow Go best practices and effective Go
- Use pgx v5 for all database operations
- Implement proper error handling with pgx.ErrNoRows
- Write comprehensive tests for new features
- Update documentation for API changes
### Code Style
- Follow existing code formatting
- Use meaningful variable and function names
- Add comments for complex business logic
- Ensure type safety with proper error handling
## 📄 License
GPL-3.0 - See [LICENSE](LICENSE) file for details.
---
**Built with ❤️ using Go, PostgreSQL, HTMX, and Tailwind CSS**