Files
chess/doc/development.md

7.6 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

# Test real-time game updates via long-polling
./test/test-longpoll.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)
  • Long-poll timeout: 25 seconds (internal/service/waiter.go)
  • Long-poll channel buffer: 1 (internal/service/waiter.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)
  • Long-polling limited to 25 seconds per request
  • REST API only