Allow publishing a CommunityRule without signing in #69

Merged
an.di merged 1 commits from adilallo/feature/CR-125-guest-publish-without-email into main 2026-08-26 17:02:20 +00:00
Owner

Overview

Guests can Finalize without a magic-link wall. The published rule gets a real public URL, stays off the catalog until someone owns it, and can be attached to an account later by signing in on the same browser.

This also removes the login modal kebab that was acting as a second Close control.

Changes

  • POST /api/rules no longer requires a session. Guests create an unlisted row (userId null), rate-limited to one anonymous publish per IP per minute. Stakeholder invite emails in the body are ignored without a session.
  • Guest publish stores a hashed claim secret and sets httpOnly cr_rule_claim (30 days). Signing in (createSessionForUser) attaches matching ownerless rows to that account and clears the cookie.
  • GET /api/rules lists only owned rules. /rules/{id} still works for guest rows.
  • Completed: no Edit unless signed in; warning banner to sign in on this browser (or that stakeholder invites were skipped).
  • Login modal: more-options kebab hidden.
  • Cookies and privacy copy mention cr_rule_claim.
  • Prisma: nullable unique PublishedRule.claimTokenHash plus migration 20260826160000_add_published_rule_claim_token.

How to Test

Apply the new Prisma migration (npx prisma migrate deploy or npx prisma migrate dev) before a local run.

  1. Signed out, go through create and Finalize. Confirm there is no login wall, you land on completed, Share / Export / Exit work, and Edit is hidden.
  2. Confirm the completed warning about signing in on this same browser. If the draft had stakeholder emails, confirm the invites-skipped warning instead.
  3. Open the public /rules/{id} URL in another tab. Confirm it loads. Confirm the id is not in GET /api/rules.
  4. From this same browser, Log in via magic link. Confirm the rule appears on Profile as owner, GET /api/rules/{id} returns viewerIsOwner: true, completed shows Edit, and the id is in GET /api/rules.
  5. Repeat Finalize while signed in: rule is owned immediately, no claim banner, invites still send when emails are present.
  6. Open the login overlay (header Log in or /login). Confirm Close is present and there is no more-options kebab. Clicking the kebab must not dismiss the dialog (it should not render).
  7. Confirm /cookies mentions cr_rule_claim.

Notes

  • Claim is possession of cr_rule_claim, not knowledge of /rules/{id}. Another browser, or clearing this site’s cookies, cannot attach the rule. Cookie lasts 30 days.
  • Any sign-in on that browser silently claims matching ownerless rows. Shared computers can attach a guest rule to the next account that signs in.
  • Not in this PR: confirm-before-claim, or emailing a claim link for another device.
  • Staging/prod need the new migration before guest Finalize will succeed.
## Overview Guests can Finalize without a magic-link wall. The published rule gets a real public URL, stays off the catalog until someone owns it, and can be attached to an account later by signing in on the same browser. This also removes the login modal kebab that was acting as a second Close control. ## Changes - `POST /api/rules` no longer requires a session. Guests create an unlisted row (`userId` null), rate-limited to one anonymous publish per IP per minute. Stakeholder invite emails in the body are ignored without a session. - Guest publish stores a hashed claim secret and sets httpOnly `cr_rule_claim` (30 days). Signing in (`createSessionForUser`) attaches matching ownerless rows to that account and clears the cookie. - `GET /api/rules` lists only owned rules. `/rules/{id}` still works for guest rows. - Completed: no Edit unless signed in; warning banner to sign in on this browser (or that stakeholder invites were skipped). - Login modal: more-options kebab hidden. - Cookies and privacy copy mention `cr_rule_claim`. - Prisma: nullable unique `PublishedRule.claimTokenHash` plus migration `20260826160000_add_published_rule_claim_token`. ## How to Test Apply the new Prisma migration (`npx prisma migrate deploy` or `npx prisma migrate dev`) before a local run. 1. Signed out, go through create and Finalize. Confirm there is no login wall, you land on completed, Share / Export / Exit work, and Edit is hidden. 2. Confirm the completed warning about signing in on this same browser. If the draft had stakeholder emails, confirm the invites-skipped warning instead. 3. Open the public `/rules/{id}` URL in another tab. Confirm it loads. Confirm the id is **not** in `GET /api/rules`. 4. From this same browser, Log in via magic link. Confirm the rule appears on Profile as owner, `GET /api/rules/{id}` returns `viewerIsOwner: true`, completed shows Edit, and the id **is** in `GET /api/rules`. 5. Repeat Finalize while signed in: rule is owned immediately, no claim banner, invites still send when emails are present. 6. Open the login overlay (header Log in or `/login`). Confirm Close is present and there is no more-options kebab. Clicking the kebab must not dismiss the dialog (it should not render). 7. Confirm `/cookies` mentions `cr_rule_claim`. ## Notes - Claim is possession of `cr_rule_claim`, not knowledge of `/rules/{id}`. Another browser, or clearing this site’s cookies, cannot attach the rule. Cookie lasts 30 days. - Any sign-in on that browser silently claims matching ownerless rows. Shared computers can attach a guest rule to the next account that signs in. - Not in this PR: confirm-before-claim, or emailing a claim link for another device. - Staging/prod need the new migration before guest Finalize will succeed.
an.di added 1 commit 2026-08-26 17:02:03 +00:00
Finalize no longer requires a magic link. Guest rows stay off the catalog until sign-in on the same browser attaches ownership, and the login modal kebab no longer acts as a second close.

Co-authored-by: Cursor <cursoragent@cursor.com>
an.di self-assigned this 2026-08-26 17:02:08 +00:00
an.di merged commit 2e995cb5f7 into main 2026-08-26 17:02:20 +00:00
an.di deleted branch adilallo/feature/CR-125-guest-publish-without-email 2026-08-26 17:02:20 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: CommunityRule/community-rule#69