The smokesignal.events web application
Rust 53.1%
CSS 28.9%
HTML 14.6%
Jinja 1.8%
JavaScript 1.5%
Dockerfile 0.1%
Shell 0.1%
Fluent 0.1%
189 1 3

Clone this repository

https://tangled.org/smokesignal.events/smokesignal
git@tangled.org:smokesignal.events/smokesignal

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Smokesignal#

A decentralized event and RSVP management application built for the AT Protocol ecosystem. Smokesignal enables users to create, discover, and RSVP to events using their AT Protocol identity. Features include email notifications, RSVP acceptance workflows, private event content, profile caching, and flexible content storage.

Features#

  • Decentralized Identity: Full AT Protocol OAuth integration with support for both PDS and AIP backends
  • Event Management: Create, edit, and manage calendar events with timezone and location support
  • RSVP System: Attendees can respond to events with status updates and validation workflows
  • RSVP Acceptance: Ticket-based acceptance system for validating RSVP attendance
  • Private Event Content: Conditional content display based on RSVP status and validation
  • Email Notifications: Configurable email alerts for RSVPs, event changes, and daily summaries
  • Real-time Updates: Jetstream consumer for live event ingestion from the AT Protocol firehose
  • Search: Full-text event search powered by OpenSearch
  • Webhooks: Configurable notifications for event and RSVP actions
  • Profile Caching: Efficient AT Protocol profile storage and retrieval
  • Internationalization: Multi-language support with Fluent
  • Flexible Storage: Support for filesystem and S3-compatible object storage
  • Image Processing: Automatic resizing and optimization for avatars and uploaded content
  • Rate Limiting: Redis-backed throttling for API protection
  • Service Identity: did:web support for federated interactions

Tech Stack#

  • Language: Rust (edition 2024, minimum version 1.90)
  • Web Framework: Axum with async/await
  • Database: PostgreSQL with SQLx migrations
  • Caching: Redis/Valkey for sessions, tokens, and profiles
  • Search: OpenSearch for full-text event search
  • Frontend: HTMX + Bulma CSS + FontAwesome
  • Templates: MiniJinja with server-side rendering
  • Email: Lettre for SMTP-based notifications
  • Image Processing: Image resizing and optimization
  • Authentication: AT Protocol OAuth with JOSE/JWT (P-256 ECDSA)

Quick Start#

  1. Install Visual Studio Code and the Dev Containers extension
  2. Clone this repository
  3. Open in VS Code and click "Reopen in Container" when prompted
  4. The devcontainer will set up PostgreSQL, Redis, and all dependencies

Manual Setup#

Prerequisites#

  • Rust toolchain (1.90 or newer)
  • PostgreSQL
  • Redis or Valkey
  • OpenSearch (optional, for search functionality)
  • SMTP server (optional, for email notifications)
  • SQLx CLI: cargo install sqlx-cli --no-default-features --features postgres

Building#

# Development build with template reloading
cargo build --bin smokesignal

# Production build with embedded templates
cargo build --bin smokesignal --no-default-features -F embed

# Run tests
cargo test

# Run linting
cargo clippy

Database Setup#

# Run migrations
sqlx migrate run

# Reset database (warning: deletes all data)
sqlx database reset

Configuration#

Required Environment Variables#

# Core configuration
HTTP_COOKIE_KEY=<64-character hex key for session encryption>
DATABASE_URL=postgres://user:pass@localhost/smokesignal
REDIS_URL=redis://localhost:6379
EXTERNAL_BASE=https://your-domain.com
PLC_HOSTNAME=plc.directory
ADMIN_DIDS=did:plc:admin1,did:plc:admin2

# Service identity
SERVICE_KEY=<service identity key for did:web>

# Storage backend (filesystem path or S3 URL)
CONTENT_STORAGE=/path/to/storage
# or
CONTENT_STORAGE=s3://bucket-name/prefix?region=us-east-1

OAuth Backend Configuration#

For PDS OAuth (default):#

OAUTH_BACKEND=pds
SIGNING_KEYS=did:key:foobarbaz

For AIP OAuth:#

OAUTH_BACKEND=aip
AIP_HOSTNAME=oauth.provider.com
AIP_CLIENT_ID=your-client-id
AIP_CLIENT_SECRET=your-client-secret

Optional Features#

# Jetstream (real-time events)
ENABLE_JETSTREAM=true

# Webhooks
ENABLE_WEBHOOKS=true
ENABLE_TASK_WEBHOOKS=true

# Search
ENABLE_OPENSEARCH=true
ENABLE_TASK_OPENSEARCH=true
OPENSEARCH_ENDPOINT=https://localhost:9200

# Email notifications
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=user@example.com
SMTP_PASSWORD=your-password
SMTP_FROM=noreply@your-domain.com

# Server configuration
PORT=3000
BIND_ADDR=0.0.0.0
RUST_LOG=info

Generating Keys#

Use the included crypto utility to generate required keys:

# Generate HTTP cookie key
$ cargo run --bin crypto -- key

# Generate a private key OAuth signing
$ goat key generate -t p256
Key Type: P-256 / secp256r1 / ES256 private key
Secret Key (Multibase Syntax): save this securely (eg, add to password manager)
        z42tmsxs...

export SIGNING_KEYS=did:key:z42tmsxs...

Running the Application#

# Start the server
cargo run --bin smokesignal

# With debug logging
RUST_LOG=debug cargo run --bin smokesignal

The application will be available at http://localhost:3000

AT Protocol Integration#

Smokesignal integrates deeply with the AT Protocol ecosystem:

  • Lexicons: Supports standard community schemas
    • community.lexicon.calendar.event - Event records
    • community.lexicon.calendar.rsvp - RSVP responses
    • events.smokesignal.profile - User profiles
    • events.smokesignal.calendar.acceptance - RSVP acceptance records
    • community.lexicon.location - Location data
  • XRPC: Provides server endpoints for search and service operations
  • Jetstream: Consumes real-time events from the firehose
  • Identity: Full DID resolution and verification with caching
  • Attestation: Support for verified claims via AT Protocol attestations

Development#

See BUILD.md for detailed development setup instructions.

Project Structure#

src/
├── atproto/         # AT Protocol integration
│   └── lexicon/     # Lexicon definitions (profile, acceptance)
├── bin/             # Executables (smokesignal, crypto)
├── http/            # Web handlers and middleware
│   ├── handle_*.rs  # Route handlers
│   └── errors/      # HTTP error handling
├── storage/         # Data access layer
│   ├── event.rs     # Event storage
│   ├── acceptance.rs # RSVP acceptance storage
│   ├── profile.rs   # Profile caching
│   ├── notification.rs # Email preferences
│   └── private_event_content.rs # Conditional content
├── consumer.rs      # Jetstream event consumer
├── processor.rs     # Event content fetcher
├── service.rs       # Service identity
├── emailer.rs       # Email sending
├── email_templates.rs # Email rendering
├── identity_cache.rs # Identity/profile caching
├── image.rs         # Image processing
├── throttle_redis.rs # Rate limiting
└── task_*.rs        # Background tasks

License#

This project is licensed under the MIT License - see the LICENSE file for details.