Skip to content

fileverse/collaboration-server

Repository files navigation

RTC Node (with Waku Support)

This repo covers how Real-Time Collaboration (RTC) with end-to-end encryption is achieved on is achieved via the Fileverse middleware on ddocs.new . Our approach offers both privacy and security via client-side encryption and by offering decentralized ways of enabling RTC on one's own documents. Tl;dr By default, RTC v0.2 on dDocs is facilitated by a stateless web-socket server (v0.1 was WebRTC) that deletes all the encrypted data it stores about a RTC session once the latest state of the document is pushed on IPFS and added to the document creator’s personal onchain content registry. All data touching the stateless web-socket server is stored only ephemerally and is first encrypted client-side.

Self-hosting and Decentralization:

  • Bring your own Server: RTC on ddocs.new can also work by self-hosting your own web-socket server and enabling your collaboration session through it.
  • Decentralisation explorations: People using dDocs can also turn on the Waku servers discovery feature, which lets them discover and connect to community-hosted servers for RTC via Waku. This feature is still in early Alpha and highly experimental ⚠️. Please use at your own risk. Thank you team Waku and Vàclav san for all the insights in helping us add this first version on dDocs! For the waku enabled version check this branch: feat/waku

This repo is currently being audited by Dedalo. Findings will be shared in a report here when completed.

Features

  • Real-time Collaboration: WebSocket-based communication for instant updates
  • Y.js Integration: CRDT-based conflict resolution for collaborative editing
  • Awareness Protocol: Real-time cursor and selection sharing
  • UCAN Authentication: Decentralized authentication using cryptographic capabilities
  • In-Memory Storage: Fast, ephemeral storage for development and testing
  • Room Management: Multi-user document rooms with role-based access
  • TypeScript: Full type safety and excellent developer experience

Quick Start

Installation

npm install

Development

# Start in development mode with auto-reload
npm run dev

Production

# Build the project
npm run build

# Start the production server
npm start

# Or use the convenient start script
./start.sh

# Or with PM2 for process management
pm2 start ecosystem.config.js --env production

Configuration

Copy env.example to .env and adjust the settings:

cp env.example .env

Environment Variables

  • PORT: Server port (default: 5000)
  • HOST: Server host (default: 0.0.0.0)
  • NODE_ENV: Environment mode (development/production)
  • CORS_ORIGINS: Comma-separated list of allowed origins
  • SERVER_DID: Server's DID for UCAN authentication
  • MONGODB_URI: MongoDB URI where you want your updates to be saved temporarily
  • RPC_URL: RPC URL to query onchain state and only allow people with relevant access to create rooms related to DDocs
  • WS_URL: Optional env vars if you want your node to participate in the waku discovery

Waku Support

For this you just need to start the server with WS_URL set as the wss url that is being provided for the running rtc server. Once the server is up and running you just need to go to settings and trigger waku enabled rtc server discover and let your frontend find this server. If there are multiple options frontend client selects one of the url at random from the avaiable community servers. You can always over ride that option and set it to your own server's wss endpoint.

API Endpoints

HTTP Endpoints

  • GET /health - Health check and server stats

WebSocket API

Connect to ws://${env.HOST}:{env.PORT}/ and send JSON messages:

Authentication

{
  "cmd": "/auth",
  "args": {
    "username": "user123",
    "token": "ucan_token_here",
    "documentId": "room123"
  },
  "seqId": "unique_id"
}

Document Updates

{
  "cmd": "/documents/update",
  "args": {
    "documentId": "room123",
    "data": "encrypted_yjs_update",
    "update_snapshot_ref": null
  },
  "seqId": "unique_id"
}

Create Commit

{
  "cmd": "/documents/commit",
  "args": {
    "documentId": "room123",
    "updates": ["update_id_1", "update_id_2"],
    "cid": "ipfs_hash",
    "data": "encrypted_document_state"
  },
  "seqId": "unique_id"
}

Get Room Members

{
  "cmd": "/documents/peers/list",
  "args": {
    "documentId": "room123"
  },
  "seqId": "unique_id"
}

Awareness Updates

{
  "cmd": "/documents/awareness",
  "args": {
    "documentId": "room123",
    "data": {
      "position": "encrypted_cursor_data"
    }
  },
  "seqId": "unique_id"
}

Usage with Sync Package

This server is designed to work with the @fileverse-dev/sync package. Here's how to configure the client:

import { useSyncMachine } from "@fileverse-dev/sync";

const { connect, disconnect, isConnected, ydoc, isReady } = useSyncMachine({
  roomId: "your-room-id",
  wsProvider: "ws://localhost:5000/",
  onError: (err) => console.error(err),
});

// Connect with username and room key
const roomKey = await crypto.subtle.importKey(/* ... */);
connect("username", roomKey);

Architecture

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Client App    │    │  Collaboration   │    │   Memory Store  │
│                 │    │     Server       │    │                 │
│  ┌───────────┐  │    │                  │    │  ┌───────────┐  │
│  │ Sync Pkg  │──┼────┼─► WebSocket      │    │  │ Documents │  │
│  └───────────┘  │    │   Manager        │    │  │ Updates   │  │
│                 │    │                  │    │  │ Commits   │  │
│  ┌───────────┐  │    │  ┌─────────────┐ │    │  │ Members   │  │
│  │  Y.js Doc │  │    │  │ Auth Service│ │    │  └───────────┘  │
│  └───────────┘  │    │  └─────────────┘ │    │                 │
└─────────────────┘    └──────────────────┘    └─────────────────┘

Development

Project Structure

src/
├── config/           # Configuration management
├── services/         # Core business logic
│   ├── auth.ts       # UCAN authentication
│   ├── memory-store.ts # In-memory data storage
│   └── websocket-manager.ts # WebSocket handling
├── types/            # TypeScript type definitions
└── index.ts          # Server entry point

Adding Features

  1. New WebSocket Commands: Add handlers in websocket-manager.ts
  2. Authentication: Modify auth.ts for custom auth logic
  3. Storage: Replace memory-store.ts with persistent storage
  4. Middleware: Add Express middleware in index.ts

Production Deployment

Environment Setup

  • Set NODE_ENV=production
  • Configure proper CORS origins
  • Set up monitoring and logging
  • Use a process manager like PM2 for production
  • Implement proper authentication key management
  • Consider using a reverse proxy (nginx) for SSL termination

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT License - see LICENSE file for details

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •