The first account can only be made in a 30-minute setup window
CI & Build / Python lint (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 4s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Android / Core and FFI clippy and tests (push) Skipped
Android / Kotlin + Rust (APK) (push) Skipped
Android / Build the server image (push) Skipped
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 11s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 38s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 4s
Android / Build, or is the channel already serving this? (push) Successful in 4s
Android / Core and FFI clippy and tests (push) Skipped
Android / Kotlin + Rust (APK) (push) Skipped
Android / Build the server image (push) Skipped
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 11s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 38s
Family idea #5105, practice 8 (Scribe #5113), the operator's choice of setup window over a setup code. Before this, whoever reached /register first on an empty server became its admin. On a fresh server at a public address, that could be a stranger, and a new DNS name is found within minutes. Now the first registration is refused once 30 minutes have passed since the server started (create_app records STARTED_AT). A restart opens the window again. It is a constant rather than a Setting, because there is no admin yet to change one. Once an account exists it no longer matters, so existing servers are unaffected. public-hosting.md says so, and two integration tests cover both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -958,6 +958,28 @@ async def _admin_with_invite(app_client, **body) -> str:
|
||||
return (await resp.get_json())["token"]
|
||||
|
||||
|
||||
async def test_the_first_account_is_refused_once_the_setup_window_has_closed(db):
|
||||
"""A fresh server on a public address must not belong to whoever finds it first
|
||||
(family idea #5105, practice 8). Past the window, nobody becomes admin."""
|
||||
from inkwell.auth import SETUP_WINDOW_S
|
||||
|
||||
ratelimit.reset_all()
|
||||
app = create_app()
|
||||
app.config["STARTED_AT"] -= SETUP_WINDOW_S + 1
|
||||
resp = await app.test_client().post(
|
||||
"/api/auth/register", json={"email": "late@example.test", "password": _PASSWORD}
|
||||
)
|
||||
assert resp.status_code == 403
|
||||
assert "setup window" in (await resp.get_json())["error"]
|
||||
assert await db.scalar(select(func.count()).select_from(User)) == 0
|
||||
|
||||
|
||||
async def test_the_first_account_is_allowed_inside_the_setup_window(app_client, db):
|
||||
resp = await app_client.post("/api/auth/register", json={"email": "prompt@example.test", "password": _PASSWORD})
|
||||
assert resp.status_code == 201
|
||||
assert (await resp.get_json())["is_admin"] is True
|
||||
|
||||
|
||||
async def _register(email: str, invite: str | None = None):
|
||||
"""Register from a separate client, so the admin's session stays where it is."""
|
||||
body = {"email": email, "password": _PASSWORD}
|
||||
|
||||
Reference in New Issue
Block a user