Find a file
igor 4978590b01
Some checks are pending
Build and push Joplock image / build-and-push (push) Waiting to run
fix(rendered): checkbox Enter always adds item; rendered-mode auto-title
- TinyMCE Enter at end of a non-empty checkbox now always inserts a new
  checkbox item, regardless of what follows (paragraph, another checkbox,
  or nothing). Exiting the list is done via Enter on an empty item. This
  fixes being unable to add items to an existing checklist that is
  followed by other text; only bottom-of-note appends worked before.
- Restore rendered-mode title auto-fill broken by ffb7bd0: onEdit now
  calls a cheap DOM-only autoTitleFromTinyMCE() instead of relying on a
  per-edit synthetic textarea 'input' event.
- Tests: rewrite checkbox-enter-behavior.spec.js (end-of-note,
  followed-by-text, empty-item exit); remove checkbox-exit.spec.js
  (encoded old exit-on-following-paragraph behavior); add
  autotitle-rendered.spec.js and tinymceOnEditSync auto-title guards.
2026-07-31 16:12:28 +12:00
.github/workflows fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
app fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
cm-build add expander-based AI autocomplete triggers 2026-06-07 14:56:30 +12:00
hljs-build Add BASIC language syntax highlighting support 2026-05-18 12:17:14 +12:00
playwright-tests fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
public fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
scripts Add single-file HTML export, image/link inlining for exports, and visible table gridlines for PDF/DOCX 2026-07-15 14:34:11 +12:00
tests fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
vendor/turndown-lib fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
.dockerignore fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
.gitignore Add vault/notebook encryption: client-side AES-256-GCM E2EE with SVG lock icons, mobile vault support, startup resume gate, and re-entry guard 2026-04-28 22:25:46 +12:00
AGENT_GUIDE.md docs: update sharing model in AGENT_GUIDE, add share- prefix to teardown 2026-07-24 14:45:20 +12:00
AGENTS.md Document shell-mode cache + readonly and TinyMCE fast/debug onEdit split; add AGENTS.md pointer 2026-07-14 20:48:40 +12:00
docker-compose.example-full-build.yml feat(editor): dual-mode editor — CodeMirror 6 markdown + TinyMCE 8 rendered 2026-07-06 17:00:57 +12:00
docker-compose.example-full.yml feat(editor): dual-mode editor — CodeMirror 6 markdown + TinyMCE 8 rendered 2026-07-06 17:00:57 +12:00
docker-compose.yml feat(editor): dual-mode editor — CodeMirror 6 markdown + TinyMCE 8 rendered 2026-07-06 17:00:57 +12:00
Dockerfile fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00
package-lock.json feat(editor): dual-mode editor — CodeMirror 6 markdown + TinyMCE 8 rendered 2026-07-06 17:00:57 +12:00
package.json feat(editor): dual-mode editor — CodeMirror 6 markdown + TinyMCE 8 rendered 2026-07-06 17:00:57 +12:00
playwright.config.js chore: capture Playwright screenshots on every run 2026-07-20 15:58:53 +12:00
README.md docs: update AGENT_GUIDE and README with vault identity guard, restore, and feature list 2026-07-16 10:01:07 +12:00
server.js fix(rendered): checkbox Enter always adds item; rendered-mode auto-title 2026-07-31 16:12:28 +12:00

Joplock

A secure, fast web client for Joplin Server.

Joplock runs as a sidecar alongside an unmodified Joplin Server instance, sharing the same Postgres database, sessions, notes, folders, and resources. It gives you a lightweight browser-based interface to your Joplin notes without modifying Joplin Server itself. Keep using the other Joplin clients too, this won't interfere.

Key Features

  • Full Joplin compatibility -- desktop, mobile, CLI, and Joplock all work with the same account and data simultaneously
  • Low Resource usage -- minimal memory usage on the client, fast and responsive
  • Security-first design -- no private data stored on the client; sessions are cleaned up on logout; per-user settings and admin controls for user management
  • Client-side encrypted vaults -- turn any notebook into a vault; notes inside are AES-GCM encrypted in the browser with a PBKDF2-derived key. The server never sees vault passwords. Ciphertext is bound to a specific vault and note id, and the server rejects any write that would land a vault-encrypted body in the wrong note or the wrong vault
  • Dual-mode editor -- CodeMirror 6 for markdown editing and TinyMCE 8 for rich rendered mode, switchable per note; mobile opens in a read-only rendered view with an edit toggle
  • Tables, code blocks, and lightbox -- full-screen code editor modal with language picker, TinyMCE tables with markdown round-trip, and a lightbox for images and attachments
  • Note export -- export any note as Markdown, single-file HTML (images and links inlined), DOCX (server-side via pandoc with reference styles), or PDF, with visible table gridlines in PDF/DOCX output
  • AI autocomplete -- optional prose completion via user-configured provider profiles (OpenRouter and others), triggered by Ctrl/Cmd-Space or configurable Expander triggers; per-user text expanders for snippets
  • Concurrent-edit detection -- detects when another client (or another browser tab) has updated the same note and offers Overwrite / Create copy so edits are never silently lost
  • Multiple themes -- Grey, Fruit, Dark Fruit, Earth, Swamp Thing, Fireball, and more, all as CSS custom-property sets; per-user theme picker in the status bar and settings page
  • User creation from Joplock UI -- create and modify users directly from Joplock settings page
  • Full database backup and restore -- create and restore complete Postgres backups for both Joplin and Joplock data
  • Multi-factor authentication -- optional TOTP-based MFA on top of standard Joplin sessions
  • Fast search -- searches titles and note bodies directly in Postgres; optional live-as-you-type search
  • Near-instant autosave -- debounced saves with conflict detection, hash-based deduplication, and an undo ring buffer with full note history snapshots. Restoring a snapshot updates the open editor immediately without a page refresh
  • PWA support -- installable as a home screen app on mobile and desktop with splash screens, offline indicator, and service worker shell
  • Server-side rendering -- SSR with htmx for minimal client-side JavaScript

Runtime Model

Joplock:

  • reads Joplin data directly from the shared Postgres database
  • validates the same sessionId cookie used by Joplin Server
  • writes notes, folders, and resources through stock Joplin Server APIs

That keeps desktop, mobile, CLI, and Joplock compatible with the same account and data.

Requirements

  • docker
  • an existng Joplin Server instance, or run the fullstack option

Environment

All configuration is done directly in the compose files via inline environment variables with comments. No .env file is needed -- just edit the values in docker-compose.yml or docker-compose.example-full.yml before starting.

Backup and recovery configuration:

  • JOPLOCK_BACKUP_DIR enables server-side full database backups
  • JOPLOCK_BACKUP_COMPRESSION controls the pg_dump compression method, for example zstd:19 or gzip:9
  • JOPLOCK_BACKUP_COMPRESSION_LEVEL=0-9 controls pg_dump compression for backup files
  • JOPLOCK_RECOVERY_ENABLED=true enables the break-glass recovery page at /recovery
  • JOPLOCK_RECOVERY_PASSWORD protects that recovery page

Important:

  • Backups are only durable if JOPLOCK_BACKUP_DIR is mounted to persistent storage.
  • Default backup compression is zstd:19, which is usually smaller than gzip:9.
  • JOPLOCK_BACKUP_COMPRESSION takes precedence over JOPLOCK_BACKUP_COMPRESSION_LEVEL.
  • Higher compression produces smaller backup files but may take longer to create.
  • Recovery mode is for backup and restore only, not regular note usage.
  • Restore replaces the entire shared Postgres database, including Joplock-owned tables.

Docker

Published container image:

  • ghcr.io/abort-retry-ignore/joplock:latest

Sidecar Install

Use this when you already have Joplin Server and Postgres running elsewhere. Edit the environment values in docker-compose.yml to point at your existing setup, or copy into your existing compose. Then:

docker compose up -d

This pulls the pre-built image from GitHub Container Registry. To build from source instead:

docker compose -f docker-compose-build.yml up -d --build

On Linux, the compose files map host.docker.internal to the host gateway so Joplock can reach host services by default.

Backup And Restore

Normal workflow:

  1. Sign in as the configured Joplock admin.
  2. Open Settings -> Admin -> Backup & Restore.
  3. Create a backup or restore an existing server-side backup.

Break-glass workflow when normal Joplin login is unavailable:

  1. Enable JOPLOCK_RECOVERY_ENABLED=true and set JOPLOCK_RECOVERY_PASSWORD.
  2. Open /recovery.
  3. Sign in with the recovery password.
  4. Create or restore full database backups from there.

Before restoring:

  1. Stop or quiesce Joplin Server if possible.
  2. Stop active sync clients.
  3. Expect the entire shared Postgres database to be replaced.

Full Example Stack

Use this as a reference/demo stack with Postgres, Joplin Server, and Joplock together. Edit the values in docker-compose.example-full.yml as needed, then:

docker compose -f docker-compose.example-full.yml up -d

The full example uses the public joplin/server:latest image. Joplock is exposed on http://localhost:5444 by default. Joplin Server is internal-only unless you add a port mapping.

The full example is meant as a working reference compose file. Adjust it for your real deployment.