7.4 KiB
7.4 KiB
Development Guide
Prerequisites
- Go 1.24+
- Stockfish in PATH
- SQLite3
- Git
- curl, jq (for testing)
Building
#git clone https://git.lixen.com/lixen/chess # Mirror
git clone https://github.com/lixenwraith/chess
cd chess
go build ./cmd/chessd
Running
Flags
-api-host: API server host (default: localhost)-api-port: API server port (default: 8080)-serve: Enable embedded web UI server-web-host: Web UI server host (default: localhost)-web-port: Web UI server port (default: 9090)-dev: Development mode with relaxed rate limits and fixed JWT secret-storage-path: SQLite database file path (enables persistence and authentication)-pid: PID file path for process tracking-pid-lock: Enable exclusive locking (requires -pid)
Modes
# In-memory only (no persistence or auth)
./chessd
# With persistence and authentication
./chessd -storage-path ./db/chess.db
# Development with all features
./chessd -dev -storage-path chess.db -pid /tmp/chessd.pid -serve
# Initialize database with user tables
./chessd db init -path chess.db
Database Management
Schema Initialization
# Create all tables (users, games, moves)
./chessd db init -path chess.db
User Management CLI
# Add user with password
./chessd db user add -path chess.db -username alice -password SecurePass123
# Add user with email
./chessd db user add -path chess.db -username bob -email bob@example.com -password BobPass456
# Interactive password input
./chessd db user add -path chess.db -username charlie -interactive
# List all users
./chessd db user list -path chess.db
# Update password
./chessd db user set-password -path chess.db -username alice -password NewPass789
# Update email
./chessd db user set-email -path chess.db -username alice -email newemail@example.com
# Update username
./chessd db user set-username -path chess.db -current alice -new alice2
# Import with existing Argon2 hash
./chessd db user set-hash -path chess.db -username alice -hash '$argon2id$v=19$m=65536,t=3,p=2$...'
# Delete user
./chessd db user delete -path chess.db -username alice
Game Query CLI
# Query all games
./chessd db query -path chess.db -gameId "*"
# Query games for specific user
./chessd db query -path chess.db -playerId "550e8400-e29b-41d4-a716-446655440000"
# Query specific game
./chessd db query -path chess.db -gameId "a1b2c3d4-e5f6-7890-1234-567890abcdef"
# Delete database (destructive)
./chessd db delete -path chess.db
Authentication Configuration
JWT Secret Management
- Production: Cryptographically secure 32-byte secret generated on startup
- Development (
-dev): Fixed secret for testing consistency - Sessions: Valid for 7 days, renewed on each login
Password Requirements
- Minimum 8 characters
- At least one letter and one number
- Argon2id hashing with secure defaults
User Account Features
- Case-insensitive username and email matching
- Optional email addresses
- Last login tracking
- Unique constraint enforcement with transaction isolation
Project Structure
chess/
├── cmd/chessd/
│ ├── main.go # Entry point with auth initialization
│ ├── pid.go # PID file management
│ └── cli/ # Database and user CLI
├── internal/
│ ├── board/ # FEN/ASCII operations
│ ├── core/ # Shared types and API models
│ ├── engine/ # Stockfish UCI wrapper
│ ├── game/ # Game state with player associations
│ ├── http/ # Fiber handlers and auth endpoints
│ │ ├── handler.go # Game endpoints
│ │ ├── auth.go # Authentication endpoints
│ │ └── middleware.go # JWT validation
│ ├── processor/ # Command processing with user context
│ ├── service/ # State and user management
│ │ ├── service.go # Core service
│ │ ├── game.go # Game operations
│ │ └── user.go # User and auth operations
│ └── storage/ # SQLite persistence
│ ├── storage.go # Async writer for games
│ ├── game.go # Game persistence
│ ├── user.go # User persistence (synchronous)
│ └── schema.go # Database schema
└── test/ # Test scripts
Testing
See test documentation for comprehensive test suites covering API, authentication, and database operations.
Quick Test Commands
# API functionality tests
./test/test-api.sh
# User authentication and database tests
./test/test-db.sh
# Run test server with sample users
./test/test-db-server.sh
Configuration
Fixed Values
- Engine path:
"stockfish"(internal/engine/engine.go) - Worker count: 2 (internal/processor/processor.go)
- Queue capacity: 100 (internal/processor/queue.go)
- Min search time: 100ms (internal/processor/processor.go)
- Write queue: 1000 operations (internal/storage/storage.go)
- DB connections: 25 max, 5 idle (internal/storage/storage.go)
- JWT expiration: 7 days (internal/service/user.go)
Authentication Configuration
- Password minimum: 8 characters with letter and number
- Username format: 1-40 characters, alphanumeric and underscore
- Email validation: Standard RFC 5322 format
- Hash algorithm: Argon2id (memory-hard, side-channel resistant)
Storage Configuration
- WAL mode enabled in development for concurrency
- Foreign key constraints enforced
- Async write pattern for games with 2-second drain on shutdown
- Synchronous writes for user operations (data consistency)
- Degradation to memory-only on write failures
- Case-insensitive collation for usernames and emails
Rate Limiting Configuration
- General endpoints: 10 req/s (20 in dev mode)
- User registration: 5 req/min
- User login: 10 req/min
- Rate limit key: IP address from X-Forwarded-For or connection
PID Management
- Singleton enforcement requires same PID file path
- Stale PID detection via signal 0 checking
- Exclusive file locking with LOCK_EX|LOCK_NB
- Automatic cleanup on graceful shutdown
Validation Rules
- Player type: 1 (human) or 2 (computer)
- Skill level: 0-20
- Search time: 100-10000ms
- UCI moves: 4-5 characters ([a-h][1-8][a-h][1-8][qrbn]?)
- Undo count: 1-300
- Username: 1-40 characters, [a-zA-Z0-9_]
- Password: 8-128 characters, requires letter and number
Security Considerations
Authentication Security
- Passwords hashed with Argon2id before storage
- JWT tokens signed with HS256
- Constant-time password comparison
- Case-insensitive matching prevents user enumeration
- Rate limiting on auth endpoints prevents brute force
Input Validation
- All user inputs validated and sanitized
- SQL injection prevented via parameterized queries
- UCI command injection blocked via character validation
- FEN strings validated against strict regex pattern
Session Management
- JWT tokens expire after 7 days
- No token refresh mechanism (re-login required)
- Tokens include minimal claims (user ID, username, email)
- Secret rotates on server restart (except dev mode)
Limitations
- JWT tokens don't support refresh (must re-login after expiry)
- User deletion doesn't cascade to games (games remain with player IDs)
- No password recovery mechanism
- No email verification for registration
- Fixed worker pool size for engine calculations
- No real-time game updates (polling required)