Implements Notion-style sync blocks: a Tiptap node whose content is shared across N pages. Editing via the Hocuspocus overlay propagates to all instances via Yjs collab + SSE broadcast (EventEmitter2 bus). Server: DB migration, NestJS module (CRUD + BFS cycle detection + broadcast), Hocuspocus persistence extension extended for sync-block-* docs, 3 new RBAC permissions (sync_blocks:create/edit/delete), seeded to Admin/Editor/Member. Client: SyncBlockExtension (Tiptap node), SyncBlockNodeView (NodeView + Mantine Modal overlay + SSE hook), /sync-block slash command, service client. Tests: 32 server Jest + 18 client Vitest, all green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
2.2 KiB
Markdown
75 lines
2.2 KiB
Markdown
# DocAdenice Web Clipper Extension
|
|
|
|
Browser extension (Chrome + Firefox, Manifest V3) that clips web pages into DocAdenice.
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 20+
|
|
- pnpm 10.4.0 (`npx --yes pnpm@10.4.0`)
|
|
- A running DocAdenice instance
|
|
|
|
## Install & dev build
|
|
|
|
```bash
|
|
# From repo root
|
|
npx --yes pnpm@10.4.0 install
|
|
|
|
# Start extension dev mode (hot-reload via @crxjs/vite-plugin)
|
|
npx --yes pnpm@10.4.0 --filter @docadenice/extension-clipper dev
|
|
```
|
|
|
|
The `dist/` folder is auto-created and refreshed.
|
|
|
|
## Load in Chrome (dev)
|
|
|
|
1. Open `chrome://extensions`
|
|
2. Enable "Developer mode" (top right)
|
|
3. Click "Load unpacked" -> select `apps/extension-clipper/dist/`
|
|
|
|
## Load in Firefox (dev)
|
|
|
|
1. Open `about:debugging#/runtime/this-firefox`
|
|
2. Click "Load Temporary Add-on"
|
|
3. Select `apps/extension-clipper/dist/manifest.json`
|
|
|
|
## Production zip for Chrome Web Store
|
|
|
|
```bash
|
|
npx --yes pnpm@10.4.0 --filter @docadenice/extension-clipper build
|
|
cd apps/extension-clipper/dist
|
|
zip -r ../docadenice-clipper.zip .
|
|
```
|
|
|
|
Submit `docadenice-clipper.zip` in the Chrome Web Store dashboard.
|
|
|
|
## Generate a clipper token
|
|
|
|
1. Log into your DocAdenice workspace.
|
|
2. Go to **Settings > Clipper tokens**.
|
|
3. Click **Generate token**, set a label and expiry.
|
|
4. Copy the token — it is shown only once.
|
|
5. Open the extension popup -> **Settings** tab.
|
|
6. Fill in:
|
|
- **DocAdenice URL**: e.g. `https://your-docadenice.example.com`
|
|
- **Clipper token**: paste the token from step 4
|
|
- **Default workspace ID**: UUID of your workspace
|
|
- **Default space ID**: UUID of the target space
|
|
7. Click **Save**.
|
|
|
|
## Usage
|
|
|
|
- Click the extension icon on any page -> fill in title + optional parent page -> **Clip page**.
|
|
- Right-click on a page or selection -> **Clip to DocAdenice**.
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
npx --yes pnpm@10.4.0 --filter @docadenice/extension-clipper test
|
|
```
|
|
|
|
## Security design
|
|
|
|
- HTML selections are sanitized by DOMPurify in the content script before leaving the page.
|
|
- The server applies a second sanitization pass via the Tiptap pipeline.
|
|
- Tokens are stored as bcrypt hashes in the database; the plaintext is returned only at
|
|
creation time and is not persisted or written to application logs by the ClipperTokenService.
|