# CalSpot A lightweight, self-hosted calendar server providing WebDAV access for calendar management and public HTTP endpoints for sharing calendars. Built with Go and SQLite. ## Features - **WebDAV Interface**: Upload and sync `.ics` calendar files using any CalDAV-compatible client - **Public Calendar Sharing**: Share calendars via simple HTTP URLs with security-through-obscurity - **Authentication**: HTTP Basic Auth protection for WebDAV endpoints - **User Management**: Interactive REPL for managing users - **Secure Storage**: bcrypt password hashing and SQLite backend - **Lightweight**: Single binary with no external dependencies - **Docker Support**: Production-ready containerized deployment ## Architecture - **Language**: Go 1.25.5 - **Database**: SQLite3 (file-based) - **Authentication**: HTTP Basic Auth with bcrypt password hashing - **Calendar Format**: iCalendar (`.ics`) files - **Storage**: Single calendar per user with automatic versioning ## Quick Start ### Local Development ```bash # Clone the repository git clone cd calspot # Build the server go build -o calspot main.go # Run the server ./calspot ``` The server will start on port 8000 with an interactive REPL for user management. ### Docker Deployment ```bash # Build the Docker image docker build -t calspot . # Run the container docker run -it -p 8000:8000 -v $(pwd)/data:/home/appuser/data calspot ``` ## User Management (REPL) The server includes an interactive command-line interface for managing users: ### Commands #### Add User ``` add [username] [password] ``` - If no username provided: generates a UUID username - If no password provided: generates a secure 16-character password - Displays the public calendar ID (UUID) for sharing Example: ``` > add alice MySecurePass123 User alice created. Public ID: 01933b2c-8f5e-7890-a234-567890abcdef ``` #### Delete User ``` del ``` Removes user and their associated calendar data. #### List Users ``` list ``` Shows all registered users with their public IDs. #### Reset Password ``` resetpassword [newpassword] ``` Updates user password. Generates secure password if not provided. ## API Endpoints ### WebDAV (Authenticated) **Endpoint**: `/webdav/` **Authentication**: HTTP Basic Auth **Methods**: `GET`, `PUT`, `DELETE`, `PROPFIND`, etc. Upload a calendar: ```bash curl -u username:password \ -T calendar.ics \ http://localhost:8000/webdav/calendar.ics ``` Download via WebDAV: ```bash curl -u username:password \ http://localhost:8000/webdav/calendar.ics ``` ### Public Calendar Access (No Authentication) **Endpoint**: `//calendar.ics` **Authentication**: None (security via obscure UUID) **Method**: `GET` Access public calendar: ```bash curl http://localhost:8000/01933b2c-8f5e-7890-a234-567890abcdef/calendar.ics ``` Subscribe in calendar apps: ``` http://localhost:8000/01933b2c-8f5e-7890-a234-567890abcdef/calendar.ics ``` ## Configuration ### Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `DB_PATH` | `./data/cal.db` | Path to SQLite database file | Example: ```bash DB_PATH=/var/lib/calspot/calendar.db ./calspot ``` ### Reverse Proxy Setup CalSpot is designed to run behind a reverse proxy (Nginx, Caddy, Traefik) for HTTPS termination. #### Nginx Example ```nginx server { listen 443 ssl http2; server_name calendar.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Important for WebDAV proxy_set_header Depth $http_depth; proxy_set_header Destination $http_destination; } } ``` ## CalDAV Client Setup ### Thunderbird 1. Go to Calendar → New Calendar → On the Network → CalDAV 2. Location: `https://calendar.example.com/webdav/calendar.ics` 3. Username: your username 4. Password: your password ### iOS/macOS 1. Settings → Calendar → Accounts → Add Account → Other → CalDAV 2. Server: `calendar.example.com` 3. Username: your username 4. Password: your password 5. Path: `/webdav/calendar.ics` ### Android (DAVx⁵) 1. Install DAVx⁵ from F-Droid or Play Store 2. Add account → Login with URL and username 3. Base URL: `https://calendar.example.com/webdav/` 4. Username and password ## Security Considerations ### Implemented Security Features - ✅ Bcrypt password hashing (cost factor 10) - ✅ HTTP Basic Auth for WebDAV endpoints - ✅ Cryptographically secure password generation - ✅ UUID-based public calendar URLs (security through obscurity) - ✅ File size limits (10MB per calendar) - ✅ Input validation on usernames - ✅ Security headers (X-Content-Type-Options, X-Frame-Options, etc.) - ✅ Non-root container execution ### Production Recommendations - **Always use HTTPS**: Deploy behind a reverse proxy with TLS - **Secure public IDs**: Treat user IDs as secrets for calendar access - **Regular backups**: Backup the SQLite database regularly - **Monitor access**: Use reverse proxy logs to monitor unusual activity - **Network isolation**: Run in a private network or with firewall rules ## Limitations - **Single calendar per user**: Each user can store one `.ics` file - **No calendar merging**: Multiple calendars must be managed at the client level - **No collaborative features**: Designed for personal use, not team sharing - **Flat file structure**: No folder organization support ## Technical Details ### Database Schema ```sql CREATE TABLE users ( id TEXT PRIMARY KEY, -- UUIDv7 for public calendar access username TEXT UNIQUE, -- Login username password_hash TEXT -- bcrypt hash ); CREATE TABLE calendars ( user_id TEXT PRIMARY KEY, -- Foreign key to users.id filename TEXT, -- Original filename (e.g., calendar.ics) content BLOB, -- iCalendar file content mod_time DATETIME -- Last modification time ); ``` ### Dependencies - `github.com/google/uuid` - UUID generation (v1.6.0) - `github.com/mattn/go-sqlite3` - SQLite driver (v1.14.32) - `golang.org/x/crypto` - bcrypt hashing (v0.46.0) - `golang.org/x/net/webdav` - WebDAV implementation (v0.48.0) ## Building from Source ```bash # Clone repository git clone cd calspot # Install dependencies go mod download # Build go build -o calspot main.go # Run ./calspot ``` ### Build Requirements - Go 1.25.5 or later - GCC (for CGO/SQLite3 compilation) ## License [Specify your license here] ## Contributing [Contribution guidelines if applicable] ## Support For issues, questions, or feature requests, please [open an issue](link-to-issues).