Skip to content

feat(locks): publishing — create lock post (#2002) - #2046

Draft
Taewa wants to merge 4 commits into
devfrom
feat/2002-locks-publishing-create-lock-post
Draft

feat(locks): publishing — create lock post (#2002)#2046
Taewa wants to merge 4 commits into
devfrom
feat/2002-locks-publishing-create-lock-post

Conversation

@Taewa

@Taewa Taewa commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

WIP — integration branch for #2002 (epic #1998). Sub-issue PRs stack onto this (e.g. #2045 for #2025).

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

URL: https://pubky-app-pr-2046-fzxmjul7ya-oa.a.run.app

pubky-app-pr-20463e3bcaa

…2025, #2001) (#2186)

* feat(locks): add lock-content UI to post composer

* fix(locks): label lock dialog tabpanel for screen readers

* feat(locks): creator auth + lock-service config (#2001)

Locks creator auth backed by the lock-sdk, mirroring the homeserver session:
- 3-step auth modal (intro → iframe /connect + postMessage → success)
- LocksAuthService / Application / Controller + persisted locks-auth-store
- restore session on load; tear it down with the unified Pubky logout
- background lock-service-config write after auth (setLockServicePointer)

* feat(locks): create lock content from the post composer (#2026)

Part of #2002. Includes follow-ups to #2001 and #2025.

- Lock switch: the written body is set aside to be locked, then the
composer is reused to write the public teaser (#2026)
- Turning the switch on asks for Lock Server sign-in if needed (#2001),
then a password dialog; Apply only saves the choice (#2025) — Post
publishes (#2026)
- Post uploads the guarded files, creates the lock, then publishes the
public announcement pointing at it (#2026)
- The pubky.app account and the Lock Server account can be different;
the announcement and all file links each use the right one (#2026)
- Cancel at any step turns the draft back into a normal post (#2026)
- Unit tests for every layer, plus composer tests for the main rule:
the to-be-locked body is never published as a public post (#2026)

* test(locks): add composer lock-flow integration tests (#2026)

- Cover the full creator journey with real composer UI: switch on →
sign-in → password → teaser → publish, per content kind
- Cover cancel paths, mixed-media locks, per-file content types, and
the guard rails (no Lock Server configured, weak password, double
submit, expired session, links never point at the pubky.app account)
- Fix the composer test's Button mock, broken by the ButtonVariant enum

* fix(locks): confirm before discarding a captured lock draft on dialog close (#2026)

* refactor(locks): resolve Lock Server pubky via runtime-config, not NEXT_PUBLIC_* (#2026)

* feat(locks): disable the lock switch until the composer has content (#2026)

* docs(adr): add ADR 0019 — Locks creator-side publishing (#2026)

* feat(locks): initialize the SDK's web-target wasm before use (#2026)

ensureLocksSdkReady() runs the web build's init() once at the service
entry points; no-op for self-initializing builds and test mocks. Restore
chain becomes async to await it. Also bump pubky-app-specs to 0.6.0 for
the post lock field.

* refactor(locks): merge locksAuth + locksContent into a single locks domain per layer (#2026)

* refactor(locks): read session/config at the service boundary, drop param threading, remove the auth test harness (#2026)

* refactor(locks): cache the SDK client and inline the wasm init into LocksService (#2026)

* refactor(locks): move the postMessage bridge to useLocksAuthFlow.utils, dissolving libs/locks (#2026)

* refactor(locks): move the content-lock publish workflow into LocksApplication (#2026)

* refactor(locks): promote HTTP 401 to a typed auth error on all session-backed calls (#2026)

* docs(locks): document the Lock/Locks naming convention in ADR 0019 (#2026)

* fix(deps): sync package-lock.json with pubky-app-specs 0.6.0 (#2026)

* refactor(locks): extract client/session/error helpers from LocksService into locks.utils

* refactor(locks): resolve configured server inside initLockClient, drop the param (#2026)

* feat(locks): gate the auth modal on Lock Server /readyz and drop the initLockClient server param (#2026)

* fix(locks): correct Lock Server env var name, type the missing-config error (#2026)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(locks): keep the Locks session when the homeserver rejects the announcement (#2026)

Auth errors from the announcement publish were treated as Lock Server session rejections; the orphaned
lock they leave behind stays with #2181.

* docs(locks): mark where editing an announcement drops its lock and shows raw JSON (#2312)

* fix(locks): keep the lock announcement within the post length limit (#2026)

Only the raw teaser was capped, so the JSON envelope and the uncapped title could push the announcement
past the spec limit — and the lock is created first, leaving it orphaned.

- Budget the teaser like an article: reserve the title and the 41-char envelope
- Cap the lock title input
- Measure the serialized envelope before creating the lock, catching JSON escaping
- Publish through one producer, so the measured string is the shipped string

* fix(locks): keep the composer open while a lock is in progress (#2026)

* fix(locks): ignore an outdated Lock Server check that answers late (#2026)

* fix(locks): bound the Lock Server signout so logout always clears the device (#2026)

* refactor(locks): drop useCallback from useLocksAuthFlow, the compiler already memoizes it (#2026)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Taewa Taewa added the locks Locks feature (content access control) label Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

locks Locks feature (content access control)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant