284 lines
9.4 KiB
Markdown
284 lines
9.4 KiB
Markdown
# Fileverse + rStack Integration Plan
|
||
|
||
## Key Architectural Decision: Y.js vs Automerge
|
||
|
||
rSpace already uses **both** Automerge and Y.js:
|
||
- **Automerge 2.2.8** — Document state, sync protocol, binary wire format
|
||
- **Y.js 13.6** — TipTap editor binding (`y-prosemirror`), IndexedDB persistence (`y-indexeddb`)
|
||
|
||
Fileverse uses **Y.js exclusively** for CRDTs.
|
||
|
||
### Assessment
|
||
|
||
rSpace's dual approach is actually well-positioned. The Y.js layer handles editor collaboration (which is what Fileverse's components need), while Automerge handles the broader document state management. We don't need to choose one — the integration points are at the Y.js/TipTap layer.
|
||
|
||
**Decision: Keep both. Integrate Fileverse at the Y.js/TipTap layer.**
|
||
|
||
The Automerge sync protocol handles state replication, while Y.js handles real-time editor cursors and awareness. Fileverse's ddoc component and collaboration-server plug into the Y.js side.
|
||
|
||
---
|
||
|
||
## Phase 1: Crypto Primitives Evaluation
|
||
|
||
**Status:** Not started
|
||
**Effort:** 1–2 days
|
||
**Target:** Determine whether to use `@fileverse/crypto` or build equivalent from MIT libs
|
||
|
||
### rSpace DocCrypto (existing)
|
||
- AES-256-GCM for document encryption
|
||
- HKDF key derivation: Master key → Space key → Doc key
|
||
- Key material from EncryptID passkey PRF
|
||
- Location: `rspace-online/shared/local-first/crypto.ts`
|
||
|
||
### @fileverse/crypto (Fileverse)
|
||
- ECIES (asymmetric encryption via elliptic curves)
|
||
- NaCl SecretBox (symmetric authenticated encryption via TweetNaCl)
|
||
- RSA envelope encryption for large messages
|
||
- HKDF key derivation
|
||
- Argon2id password hashing
|
||
|
||
### Comparison
|
||
|
||
| Feature | DocCrypto | @fileverse/crypto |
|
||
|---------|-----------|-------------------|
|
||
| Symmetric encryption | AES-256-GCM (Web Crypto) | NaCl SecretBox (TweetNaCl) |
|
||
| Asymmetric encryption | Not implemented | ECIES + RSA |
|
||
| Key derivation | HKDF (Web Crypto) | HKDF + Argon2id |
|
||
| Key hierarchy | Master → Space → Doc | Flat (per-operation) |
|
||
| Sharing keys between users | Not implemented | ECIES key exchange |
|
||
| Security audit | No | No |
|
||
| License | Proprietary (rStack) | AGPL-3.0 |
|
||
|
||
### Gap Analysis
|
||
|
||
rSpace's DocCrypto lacks:
|
||
1. **Asymmetric encryption** — needed to share document keys between collaborators without a central server
|
||
2. **Key exchange** — ECIES allows encrypting a doc key for a specific collaborator's public key
|
||
3. **Password-derived keys** — Argon2id enables password-protected notes (useful for shared links)
|
||
|
||
### MIT Alternatives
|
||
|
||
The underlying primitives in `@fileverse/crypto` are all MIT-licensed:
|
||
- **Noble curves** (`@noble/curves`) — ECIES elliptic curve operations
|
||
- **StableLib** (`@stablelib/x25519`, `@stablelib/hkdf`) — Key exchange and derivation
|
||
- **TweetNaCl** (`tweetnacl`) — SecretBox symmetric encryption
|
||
- **argon2-browser** — Argon2id in WASM
|
||
|
||
**Recommendation:** Build a thin wrapper around MIT libs, matching `@fileverse/crypto`'s API where useful. This avoids AGPL while gaining all the cryptographic capabilities.
|
||
|
||
### Tasks
|
||
- [ ] Benchmark NaCl SecretBox vs AES-256-GCM (performance + bundle size)
|
||
- [ ] Implement ECIES key exchange using Noble curves
|
||
- [ ] Add Argon2id for password-protected notes
|
||
- [ ] Test interop: can we decrypt Fileverse-encrypted content?
|
||
|
||
---
|
||
|
||
## Phase 2: IPFS File Storage
|
||
|
||
**Status:** Not started
|
||
**Effort:** 3–5 days
|
||
**Target:** Replace centralized file uploads with IPFS-backed storage
|
||
**Resolves:** rNotes TASK-4 (file/image upload)
|
||
|
||
### Architecture
|
||
|
||
```
|
||
Client Server/IPFS
|
||
│ │
|
||
├─ Pick file │
|
||
├─ Encrypt (SecretBox) │
|
||
├─ Upload encrypted blob ───────►│ Store on IPFS
|
||
│◄──────── Return CID ──────────┤
|
||
├─ Store CID + key in │
|
||
│ document metadata │
|
||
│ │
|
||
├─ To view: fetch CID ─────────►│ Return encrypted blob
|
||
│◄──────────────────────────────┤
|
||
├─ Decrypt locally │
|
||
└─ Display │
|
||
```
|
||
|
||
### Options
|
||
|
||
#### A. Use Fileverse's storage service
|
||
- Requires UCAN tokens for authorization
|
||
- Depends on Fileverse infrastructure
|
||
- No self-hosting option documented
|
||
|
||
#### B. Self-host IPFS node on Netcup
|
||
- Full control over storage
|
||
- `kubo` (go-ipfs) or `helia` (JS)
|
||
- Pin encrypted blobs, serve via gateway
|
||
- CIDs stored in Automerge documents
|
||
|
||
#### C. Use Pinata/web3.storage
|
||
- Managed IPFS pinning
|
||
- Free tiers available
|
||
- Less operational overhead
|
||
|
||
**Recommendation:** Start with option C (managed pinning) for POC, migrate to B (self-hosted) for production.
|
||
|
||
### Tasks
|
||
- [ ] Set up Pinata account and API keys (store in Infisical)
|
||
- [ ] Build upload service: encrypt → pin → return CID
|
||
- [ ] Build retrieval service: fetch CID → decrypt → serve
|
||
- [ ] Add TipTap image extension that uses IPFS CIDs
|
||
- [ ] Test with rNotes note editor
|
||
|
||
---
|
||
|
||
## Phase 3: Collaboration Server
|
||
|
||
**Status:** Not started
|
||
**Effort:** 3–5 days
|
||
**Target:** Self-host Fileverse's collaboration-server on Netcup
|
||
|
||
### Requirements
|
||
- Node.js runtime
|
||
- MongoDB (temporary update storage)
|
||
- Redis (session management)
|
||
- WebSocket support via Traefik
|
||
|
||
### Deployment Plan
|
||
|
||
```yaml
|
||
# docker-compose.yml on Netcup
|
||
services:
|
||
collab-server:
|
||
image: node:20-slim
|
||
# Build from github.com/fileverse/collaboration-server
|
||
environment:
|
||
PORT: 5000
|
||
MONGODB_URI: mongodb://collab-mongo:27017/collab
|
||
CORS_ORIGINS: "https://rnotes.jeffemmett.com,https://rspace.jeffemmett.com"
|
||
labels:
|
||
- "traefik.enable=true"
|
||
- "traefik.http.routers.collab.rule=Host(`collab.jeffemmett.com`)"
|
||
- "traefik.http.routers.collab.tls.certresolver=letsencrypt"
|
||
depends_on:
|
||
- collab-mongo
|
||
- collab-redis
|
||
|
||
collab-mongo:
|
||
image: mongo:7
|
||
volumes:
|
||
- collab-mongo-data:/data/db
|
||
|
||
collab-redis:
|
||
image: redis:7-alpine
|
||
volumes:
|
||
- collab-redis-data:/data
|
||
```
|
||
|
||
### Integration with rSpace
|
||
|
||
The collaboration-server uses Y.js sync protocol. rSpace already has Y.js for TipTap. Integration points:
|
||
1. Connect TipTap's `y-prosemirror` binding to collab-server WebSocket
|
||
2. Use collab-server's awareness protocol for cursor presence
|
||
3. Automerge sync continues separately for document state
|
||
|
||
### UCAN Auth Integration
|
||
|
||
Fileverse's collab-server uses UCAN tokens. Options:
|
||
1. **Adapt:** Generate UCANs from EncryptID DIDs (preferred)
|
||
2. **Bypass:** Fork server, replace UCAN auth with EncryptID JWT
|
||
3. **Bridge:** Proxy auth through an adapter service
|
||
|
||
### Tasks
|
||
- [ ] Fork collaboration-server, evaluate auth integration
|
||
- [ ] Create Docker Compose config for Netcup
|
||
- [ ] Deploy with Traefik routing
|
||
- [ ] Connect rSpace TipTap editor to collab-server
|
||
- [ ] Test real-time collaboration between two clients
|
||
|
||
---
|
||
|
||
## Phase 4: dSheet as rSheet Module
|
||
|
||
**Status:** Not started
|
||
**Effort:** 5–7 days
|
||
**Target:** Integrate `@fileverse-dev/dsheet` as a new rStack module
|
||
|
||
### Architecture
|
||
|
||
```
|
||
rstack-online/
|
||
└── modules/
|
||
└── rsheet/ # New module
|
||
├── schemas.ts # Automerge schemas for spreadsheet metadata
|
||
├── components/
|
||
│ └── folk-sheet-app.ts # LitElement wrapper around dSheet
|
||
├── local-first-client.ts # Sync integration
|
||
└── converters/
|
||
├── csv.ts # CSV import/export
|
||
└── xlsx.ts # Excel import/export
|
||
```
|
||
|
||
### dSheet Component Props
|
||
|
||
```typescript
|
||
<DSheet
|
||
isAuthorized={true}
|
||
dsheetId="room-id" // Collaboration room
|
||
enableWebrtc={true} // P2P sync
|
||
enableIndexeddbSync={true} // Offline persistence
|
||
isCollaborative={true} // Multi-user
|
||
onChange={handleChange} // Data callback
|
||
/>
|
||
```
|
||
|
||
### Integration Points
|
||
- Use rSpace's EncryptID auth for `isAuthorized`
|
||
- Generate `dsheetId` from Automerge document ID
|
||
- Route WebRTC signaling through self-hosted collab-server
|
||
- Store spreadsheet metadata in Automerge (title, permissions, CID)
|
||
- Store spreadsheet data in IndexedDB (via dSheet's built-in support)
|
||
|
||
### Use Cases for rStack
|
||
- DAO treasury tracking (live blockchain data queries)
|
||
- Token allocation spreadsheets
|
||
- Budget planning with E2E encryption
|
||
- Research data tables alongside rNotes
|
||
|
||
### Tasks
|
||
- [ ] Create rSheet module scaffold in rspace-online
|
||
- [ ] Wrap dSheet React component in LitElement
|
||
- [ ] Wire auth and collaboration
|
||
- [ ] Add CSV/XLSX import/export converters
|
||
- [ ] Deploy and test
|
||
|
||
---
|
||
|
||
## Phase 5: Advanced — UCAN + Decentralized Identity
|
||
|
||
**Status:** Future
|
||
**Effort:** 5+ days
|
||
|
||
### Goals
|
||
- Complement EncryptID with UCAN capability tokens
|
||
- Decentralized authorization without central server
|
||
- Fine-grained permissions: read, write, share, admin per document
|
||
|
||
### UCAN Flow
|
||
```
|
||
User (EncryptID DID) → Mint UCAN → Delegate to collaborator
|
||
↓
|
||
Collaborator presents UCAN to:
|
||
- Collaboration server (real-time sync)
|
||
- Storage server (file uploads)
|
||
- IPFS gateway (content retrieval)
|
||
```
|
||
|
||
---
|
||
|
||
## Timeline
|
||
|
||
| Phase | Duration | Dependencies |
|
||
|-------|----------|-------------|
|
||
| 1. Crypto evaluation | 1–2 days | None |
|
||
| 2. IPFS storage | 3–5 days | Phase 1 |
|
||
| 3. Collab server | 3–5 days | None (parallel with Phase 2) |
|
||
| 4. dSheet module | 5–7 days | Phase 3 |
|
||
| 5. UCAN auth | 5+ days | Phases 2, 3 |
|