Release 0.3.0: private-beta gate + anonymous read mode
Adds an email allowlist (toggleable per deployment) that restricts OAuth sign-in to listed emails while keeping read paths public. Anonymous visitors now see the full app shell in read-only mode instead of the §14.1 landing wall. Empty allowlist = gate off, so deployments that don't enable it behave exactly as 0.2.3. Also fixes single-finger scroll on /philosophy and other .chrome-pane views on iOS Safari (.app: 100vh → 100dvh). Renames deploy/nginx/rfc.wiggleverse.org.conf → ohm.wiggleverse.org.conf to match the deployed-domain rename (rfc.wiggleverse.org deprovisioned 2026-05-27). See CHANGELOG.md for full details + upgrade steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,81 @@ skip versions are the composition of each intervening adjacent
|
||||
release's steps in order — no A-to-B path is pre-computed beyond
|
||||
that.
|
||||
|
||||
## 0.3.0 — 2026-05-27
|
||||
|
||||
**Minor — operator action required if a deployment wants to enable the
|
||||
private-beta gate; no action required to stay open.** This release adds
|
||||
an email allowlist that, when populated, restricts OAuth sign-in to the
|
||||
listed emails while keeping all read paths public. Anonymous visitors
|
||||
now see the full app (catalog, RFC bodies, public branch conversations)
|
||||
in read-only mode instead of the §14.1 landing-page wall.
|
||||
|
||||
### Added
|
||||
|
||||
- **`allowed_emails` table** (`backend/migrations/011_allowlist.sql`).
|
||||
Empty list = gate off (any successful OAuth provisions a user, as
|
||||
before). Any rows present = gate on (only listed emails, plus
|
||||
users already grandfathered by `gitea_id`, may sign in).
|
||||
- **Admin → Allowlist tab** at `/admin/allowlist`. Add/remove emails,
|
||||
see who added each row and when. Status banner shows whether the
|
||||
gate is currently active.
|
||||
- **`/beta-pending` page** shown after a rejected OAuth callback. Free-
|
||||
text invite-contact line is configurable via the new
|
||||
`VITE_BETA_CONTACT` env var (optional; falls back to a generic line).
|
||||
- **Beta chips** next to the Discuss/Contribute mode toggle, the Sign
|
||||
in link, and the header Sign-in button so anonymous viewers see
|
||||
immediately what is gated.
|
||||
- **Anonymous read mode** in the React app: the §14.1 Landing page is
|
||||
preserved at `/welcome` for deployments that want to link to it, but
|
||||
the default route now renders the full app shell with write
|
||||
affordances hidden behind a sign-in CTA.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`/auth/callback`** now consults `auth.is_allowed_sign_in()` after
|
||||
fetching the Gitea profile. Rejected sign-ins clear the OAuth state
|
||||
and redirect to `/beta-pending`; the session is not populated.
|
||||
- **`Catalog`** receives a `viewer` prop. Anonymous viewers see "Sign
|
||||
in to propose (Beta)" instead of "+ Propose New RFC".
|
||||
- **`PhilosophyWithSidebar`** now reads `authenticated` from the
|
||||
current viewer instead of hardcoded `true`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Single-finger scroll on the `/philosophy` page** (and any other
|
||||
`.chrome-pane`-hosted view: `/admin/*`, `/settings/notifications`)
|
||||
was broken on iOS Safari. The `.app` container used `height: 100vh`,
|
||||
which on iOS measures the URL-bar-hidden ("largest") viewport — so
|
||||
`.app` overflowed what's actually visible. Combined with the
|
||||
`body { overflow: hidden }` in `index.css`, this meant single-finger
|
||||
touches on the visible area were consumed by the (blocked) page-
|
||||
level scroll attempt rather than reaching the nested `.chrome-pane`
|
||||
scroll. Two-finger touches bypassed the page-level layer and
|
||||
one-finger then worked once the URL bar had collapsed. Switched
|
||||
`.app` to `height: 100dvh` (dynamic viewport — adjusts as the URL
|
||||
bar shows/hides), with `100vh` retained as a fallback for browsers
|
||||
predating iOS 15.4 / Chrome 108.
|
||||
|
||||
### Upgrade steps (from 0.2.3)
|
||||
|
||||
1. The deployment **MUST** rebuild the frontend with the new
|
||||
`VITE_BETA_CONTACT` env var optionally set in `frontend/.env` (it
|
||||
is OK to leave it blank — the `/beta-pending` page falls back to
|
||||
a generic line).
|
||||
2. The deployment **MUST** restart the backend so migration
|
||||
`011_allowlist.sql` runs. No data loss; the new table starts
|
||||
empty, which keeps the gate off and preserves existing behavior.
|
||||
3. To **enable** the private-beta gate, the deployment operator
|
||||
**SHOULD** sign in once (so their `users` row exists and they
|
||||
grandfather in by `gitea_id`), then open `/admin/allowlist` and
|
||||
add the first invited email. The first row added turns the gate
|
||||
on for any user not yet in `users`.
|
||||
4. To **stay open**, do nothing — leave `allowed_emails` empty and
|
||||
the deployment behaves exactly as 0.2.3.
|
||||
5. The deployment **MAY** customise its `/beta-pending` contact line
|
||||
by setting `VITE_BETA_CONTACT` (an email, a URL, or a short
|
||||
instruction) before the frontend build. Unset is fine.
|
||||
|
||||
## 0.2.3 — 2026-05-26
|
||||
|
||||
**Patch — no operator action required.** Rebuild and restart per the
|
||||
|
||||
Reference in New Issue
Block a user