feat: full project sync - CI fixes, frontend, workspace API, and all changes

This commit is contained in:
Tomas Dvorak
2026-04-27 09:08:07 +02:00
parent a07fca997e
commit 89b9390c14
109 changed files with 21120 additions and 545 deletions
+169 -150
View File
@@ -1,182 +1,201 @@
# Excalidraw Full: Your Self-Hosted, Cloud-Ready Collaboration Platform
# Excalidraw FULL
[中文说明](./README_zh.md)
A self-hosted visual workspace for drawing, planning, mapping, charting, and lightweight project management built around a fast collaborative canvas.
Excalidraw Full has evolved. It's no longer just a simple wrapper for Excalidraw, but a powerful, self-hosted collaboration platform with a "Bring Your Own Cloud" (BYOC) philosophy. It provides user authentication, multi-canvas management, and the unique ability to connect directly to your own cloud storage from the frontend.
## What It Is
The core idea is to let the backend handle user identity while giving you, the user, full control over where your data is stored.
Excalidraw FULL is a production-grade visual workspace platform. It is no longer a simple drawing wrapper — it is a full product with backend-owned persistence, team collaboration, permissions, and structured file management.
## Core Differences from Official Excalidraw
- **Visual canvas first** — freeform drawing remains central
- **Backend-owned persistence only** — no browser/local save modes
- **Team collaboration native** — real-time editing with presence
- **File/folder/project management built in** — hierarchical organization via `/folder/:folderId/drawing/:drawingId`
- **Secure sharing and permissioning** — explicit grants with inheritance
- **Activity history and auditability** — every action is tracked
- **Templates and structured productivity** — system + team + personal templates
- **Rich linking between canvases** — embeds, references, knowledge graph
- **AI chat integration** — OpenAI proxy for diagram generation assistance
- **Command palette** — global `Cmd/Ctrl+K` for power users
- **Fulltext search** — find drawings from anywhere
- **Revision browser** — time-travel through drawing history with one-click restore
- **Dark mode** — persistent theme preference across sessions
- **Presenter notes** — add notes to any drawing for presentations
- **Responsive layout** — mobile sidebar toggle, adaptive grids
- **Accessibility** — ARIA labels, roles, keyboard navigation
- **Self-hosting** — single Docker image, healthchecks, volume mounts
- **Fully Self-Hosted Collaboration & Sharing**: Unlike the official version, all real-time collaboration and sharing features are handled by your own self-hosted backend, ensuring complete data privacy and control.
- **Advanced Multi-Canvas Management**: Seamlessly create, save, and manage multiple canvases. Store your work on the server's backend (e.g., SQLite, S3) or connect the frontend directly to your personal cloud storage (e.g., Cloudflare KV) for true data sovereignty.
- **Zero-Config AI Features**: Instantly access integrated OpenAI features like GPT-4 Vision after logging in—no complex client-side setup required. API keys are securely managed by the backend.
![Multi-Canvas Management](./img/PixPin_2025-07-06_16-07-27.png)
![Multi-Choice Storage](./img/PixPin_2025-07-06_16-08-29.png)
![Oauth2 Login](./img/PixPin_2025-07-06_16-09-24.png)
![AI Features](./img/PixPin_2025-07-06_16-09-55.png)
## Key Features
- **GitHub Authentication**: Secure sign-in using GitHub OAuth.
- **Multi-Canvas Management**: Users can create, save, and manage multiple drawing canvases.
- **Flexible Data Storage (BYOC)**:
- **Default Backend Storage**: Out-of-the-box support for saving canvases on the server's storage (SQLite, Filesystem, S3).
- **Direct Cloud Connection**: The frontend can connect directly to your own cloud services like **Cloudflare KV** or **Amazon S3** for ultimate data sovereignty. Your credentials never touch our server.
- **Real-time Collaboration**: The classic Excalidraw real-time collaboration is fully supported.
- **Secure OpenAI Proxy**: An optional backend proxy for using OpenAI's GPT-4 Vision features, keeping your API key safe.
- **All-in-One Binary**: The entire application, including the patched frontend and backend server, is compiled into a single Go binary for easy deployment.
## Frontend Canvas Storage Strategies
- **IndexedDB**: A fast, secure, and scalable key-value store. No need to configure anything. Not login required.
- **Backend Storage**: The backend can save the canvas to the server's storage (SQLite, Filesystem, S3). Synchronized in different devices.
- **Cloudflare KV**: A fast, secure, and scalable key-value store. This requires deploying a companion Worker to your Cloudflare account. See the [**Cloudflare Worker Deployment Guide**](./cloudflare-worker/README.md) for detailed instructions.
- **Amazon S3**: A reliable, scalable, and inexpensive object storage service.
## Installation & Running
One Click Docker run [Excalidraw-Full](https://github.com/BetterAndBetterII/excalidraw-full).
## Quick Start
```bash
# Example for Linux
git clone https://github.com/BetterAndBetterII/excalidraw-full.git
cd excalidraw-full
mv .env.example .env
touch ./excalidraw.db # IMPORTANT: Initialize the SQLite DB, OTHERWISE IT WILL NOT START
docker compose up -d
cp .env.example .env
# Edit .env and set JWT_SECRET (required)
# openssl rand -base64 32
make build # Build frontend + Go binary
make test # Run all tests
make docker-up # Or run via Docker Compose
```
The server will start, and you can access the application at `http://localhost:3002`.
The application will be available at `http://localhost:3002`.
## Requirements
<!-- Summary Folded -->
<details>
<summary>Use Simple Password Authentication(Dex OIDC)</summary>
```bash
# Example for Linux
git clone https://github.com/BetterAndBetterII/excalidraw-full.git
cd excalidraw-full
mv .env.example.dex .env
touch ./excalidraw.db # IMPORTANT: Initialize the SQLite DB, OTHERWISE IT WILL NOT START
docker compose -f docker-compose.dex.yml up -d
```
Change your password in `.env` file.
```bash
# apt install apache2-utils
# Generate the password hash
echo YOUR_NEW_PASSWORD | htpasswd -BinC 10 admin | cut -d: -f2 > .htpasswd
# Update your .env file
sed -i "s|ADMIN_PASSWORD_HASH=.*|ADMIN_PASSWORD_HASH='$(cat .htpasswd)'|" .env
```
</details>
- Go 1.25+
- Node.js 20+ (for frontend build)
- Make (optional, for convenience commands)
- Docker (optional, for containerized deployment)
## Configuration
Configuration is managed via environment variables. For a full template, see the `.env.example` section below.
All configuration is via environment variables. See `.env.example` for the full reference.
### 1. Backend Configuration (Required)
| Variable | Required | Description |
|----------|----------|-------------|
| `JWT_SECRET` | Yes | Secure random string for session signing (min 32 chars) |
| `STORAGE_TYPE` | No | `postgres` (default), `memory`, `filesystem`, `s3` |
| `DATABASE_URL` | Yes for Postgres | PostgreSQL connection string |
| `GITHUB_CLIENT_ID` | No* | GitHub OAuth app client ID |
| `GITHUB_CLIENT_SECRET` | No* | GitHub OAuth app client secret |
| `OIDC_ISSUER_URL` | No* | Generic OIDC issuer for SSO |
| `OIDC_CLIENT_ID` | No* | OIDC client ID |
| `OIDC_CLIENT_SECRET` | No* | OIDC client secret |
| `OPENAI_API_KEY` | No | Enables AI chat/completion proxy |
| `OPENAI_BASE_URL` | No | OpenAI-compatible API base URL |
| `ALLOWED_ORIGINS` | No | Comma-separated CORS origins |
| `LISTEN_ADDR` | No | Server bind address (default `:3002`) |
You must configure GitHub OAuth and a JWT secret for the application to function.
\* At least one external auth provider (GitHub OAuth or OIDC) OR use built-in password authentication. Password auth works out of the box.
- `GITHUB_CLIENT_ID`: Your GitHub OAuth App's Client ID.
- `GITHUB_CLIENT_SECRET`: Your GitHub OAuth App's Client Secret.
- `GITHUB_REDIRECT_URL`: The callback URL. For local testing, this is `http://localhost:3002/auth/callback`.
- `JWT_SECRET`: A strong, random string for signing session tokens. Generate one with `openssl rand -base64 32`.
- `OPENAI_API_KEY`: Your secret key from OpenAI.
- `OPENAI_BASE_URL`: (Optional) For using compatible APIs like Azure OpenAI.
## Architecture
### 2. Default Storage (Optional, but Recommended)
- **Backend**: Go 1.25, Chi router, PostgreSQL (pgx)
- **Frontend**: React 18, Vite, TypeScript, Zustand, react-router-dom, react-i18next
- **Real-time**: Socket.IO for collaborative canvas sync
- **Auth**: Session cookies (httpOnly, SameSite=Lax) + bcrypt password hashing + OAuth/OIDC
- **Storage**: PostgreSQL default, with legacy filesystem/S3 options for canvas storage
- **API spec**: OpenAPI 3.0 in `api/openapi.yaml`; TypeScript client via `make generate-api-client`
This configures the server's built-in storage, used by default.
## API
- `STORAGE_TYPE`: `memory` (default), `sqlite`, `filesystem`, or `s3`.
- `DATA_SOURCE_NAME`: Path for the SQLite DB (e.g., `excalidraw.db`).
- `LOCAL_STORAGE_PATH`: Directory for filesystem storage.
- `S3_BUCKET_NAME`, `AWS_REGION`, etc.: For S3 storage.
The workspace API is mounted at `/api` and requires session authentication. Key endpoints:
### 3. OpenAI Proxy (Optional)
- `POST /api/auth/signup` / `POST /api/auth/login` / `POST /api/auth/logout`
- `GET /api/auth/me` — current user
- `GET /api/teams`, `POST /api/teams`, `GET /api/teams/:id/members`
- `GET /api/drawings`, `POST /api/drawings`, `GET /api/drawings/:id`
- `PATCH /api/drawings/:id`, `DELETE /api/drawings/:id`
- `GET /api/drawings/:id/revisions`, `POST /api/drawings/:id/revisions`
- `GET /api/drawings/:id/permissions`, `POST /api/drawings/:id/permissions`
- `GET /api/drawings/:id/share-links`, `POST /api/drawings/:id/share-links`
- `GET /api/search?q=` — fulltext search
- `GET /api/folders`, `POST /api/folders`
- `GET /api/projects`, `POST /api/projects`
- `GET /api/templates` — system, team, and personal templates
- `GET /api/activity` — audit trail with actor hydration
- `GET /api/stats` — workspace statistics (counts + storage)
- `GET /api/health` — readiness probe
To enable AI features, set your OpenAI API key.
- `OPENAI_API_KEY`: Your secret key from OpenAI.
- `OPENAI_BASE_URL`: (Optional) For using compatible APIs like Azure OpenAI.
### 4. Frontend Configuration
Frontend storage adapters (like Cloudflare KV, S3) are configured directly in the application's UI settings after you log in. This is by design: your private cloud credentials are only ever stored in your browser's session and are never sent to the backend server.
### Example `.env.example`
Create a `.env` file in the project root and add the following, filling in your own values.
```env
# Backend Server Configuration
# Get from https://github.com/settings/developers
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_REDIRECT_URL=http://localhost:3002/auth/callback
# Generate with: openssl rand -base64 32
JWT_SECRET=your_super_secret_jwt_string
# Default Storage (SQLite)
STORAGE_TYPE=sqlite
DATA_SOURCE_NAME=excalidraw.db
# Optional OpenAI Proxy
OPENAI_API_KEY=sk-your_openai_api_key
```
## Building from Source
The process is similar to before, but now requires the Go backend to be built.
### Using Docker (Recommended)
## Development
```bash
# Clone the repository with submodules
git clone https://github.com/PatWie/excalidraw-complete.git --recursive
cd excalidraw-complete
# Terminal 1: Go backend with auto-reload (requires air)
make dev-backend
# Build the Docker image
# This handles the frontend build, patching, and Go backend compilation.
docker build -t excalidraw-complete -f excalidraw-complete.Dockerfile .
# Terminal 2: Vite dev server
make dev-frontend
# Run the container, providing the environment variables
docker run -p 3002:3002 \
-e GITHUB_CLIENT_ID="your_id" \
-e GITHUB_CLIENT_SECRET="your_secret" \
-e GITHUB_REDIRECT_URL="http://localhost:3002/auth/callback" \
-e JWT_SECRET="your_jwt_secret" \
-e STORAGE_TYPE="sqlite" \
-e DATA_SOURCE_NAME="excalidraw.db" \
-e OPENAI_API_KEY="your_openai_api_key" \
excalidraw-complete
# Or run both manually:
go run main.go # backend on :3002
cd frontend && npm run dev # frontend on :5173
```
### Manual Build
## Building
1. **Build Frontend**: Follow the steps in the original README to patch and build the Excalidraw frontend inside the `excalidraw/` submodule.
2. **Copy Frontend**: Ensure the built frontend from `excalidraw/excalidraw-app/build` is copied to the `frontend/` directory in the root.
3. **Build Go Backend**:
```bash
go build -o excalidraw-complete main.go
```
4. **Run**:
```bash
# Set environment variables first
./excalidraw-complete
```
---
```bash
make build # Full production build (frontend + Go binary)
make build-frontend # React build only
make build-backend # Go binary only
make build-docker # Docker image locally
make test # Run Go + frontend tests
make test-backend # Go unit tests
make test-frontend # Vitest unit tests
make test-e2e # Playwright E2E tests
make lint # Run all linters
make fmt # Format all code
make generate-api-client # TS client from openapi.yaml
make clean # Remove build artifacts
make docker-up # Docker Compose local run
make docker-down # Stop Docker Compose
make docker-logs # Tail Docker logs
make help # Show all targets
```
Excalidraw is a fantastic tool. This project aims to make a powerful, data-secure version of it accessible to everyone. Contributions are welcome!
## Project Structure
```
.
├── main.go # Go server entrypoint
├── workspace/ # Core domain: models, store, HTTP handlers, tests
│ ├── models.go
│ ├── store.go # PostgreSQL persistence + migrations
│ ├── store_sharing.go # Permissions, share links, embeds
│ ├── http.go # API route handlers
│ ├── http_extra.go # Search, stats, activity
│ ├── stats.go # Workspace statistics
│ ├── rate_limiter.go # Auth endpoint rate limiting
│ └── *_test.go # Go unit tests
├── middleware/ # Auth, security headers
├── handlers/ # Legacy firebase, kv, openai, auth
├── frontend/ # React + Vite frontend
│ ├── src/
│ │ ├── pages/ # Dashboard, Editor, Auth, Settings, etc.
│ │ ├── components/ # Reusable UI (Button, Card, CommandPalette, etc.)
│ │ ├── stores/ # Zustand state management
│ │ ├── services/ # API client + OpenAI proxy
│ │ ├── i18n/ # Translation files (en.json)
│ │ └── styles/ # Global SCSS + CSS variables
│ └── package.json
├── api/
│ └── openapi.yaml # Full OpenAPI 3.0 spec
├── excalidraw-full.Dockerfile # Multi-stage production build
├── docker-compose.yml # Local Docker Compose
├── Makefile # Build, test, dev automation
└── .env.example # Environment reference
```
## Security
- bcrypt(cost=12) password hashing
- httpOnly, SameSite=Lax session cookies
- CSRF-like same-origin mutation checks on state-changing requests
- URL sanitization for embeds (blocks file://, javascript:, private IPs)
- Content-Security-Policy headers with strict defaults
- Rate limiting on auth endpoints (10 req / 15 min per IP)
- Permission matrix with explicit grants + inheritance
- All mutations require authenticated session
## Internationalization
Frontend uses `react-i18next` with `i18next-browser-languagedetector`. All UI strings are externalized to `frontend/src/i18n/locales/en.json`. Add new keys there and reference via `t('key')`.
## Roadmap
See `plus-roadmap.md` for upcoming features. Shipped highlights:
- Archive (trash) instead of delete
- Activity feed with full audit trail
- Command palette for whole app (`Cmd/Ctrl+K`)
- Fulltext search
- Versioning with revision browser
- Public API (OpenAPI + TS client generation)
- Self-hosting via Docker
- Presenter notes
- Scene filtering and sorting
- Template gallery with apply flow
- Dark mode sync with canvas
- Mobile-responsive navigation
## License
MIT