2025-12-29 21:24:24 +00:00
2025-12-29 21:24:24 +00:00

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

# Clone the repository
git clone <repository-url>
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

# 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 <username>

Removes user and their associated calendar data.

List Users

list

Shows all registered users with their public IDs.

Reset Password

resetpassword <username> [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:

curl -u username:password \
  -T calendar.ics \
  http://localhost:8000/webdav/calendar.ics

Download via WebDAV:

curl -u username:password \
  http://localhost:8000/webdav/calendar.ics

Public Calendar Access (No Authentication)

Endpoint: /<user-id>/calendar.ics
Authentication: None (security via obscure UUID)
Method: GET

Access public calendar:

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:

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

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

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

# Clone repository
git clone <repository-url>
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.

Description
Upload a calendar via WebDAV, access over HTTP(S)
Readme 44 KiB
Languages
Go 95.8%
Dockerfile 4.2%