/// // Registration is closed: `users` can only be created by a superuser. // // WHY: the instance was gated by a single shared invite code in // AMBER_INVITE_CODE, checked in a hook. That is a bearer secret — one string for // everyone, forever, no record of who used it, and known to every family member // who ever onboarded, so it leaked by design. An email whitelist was the obvious // replacement and was rejected: it binds to a person only if the address is // verified, and every account on this instance is `verified = false`. For a // household of five, the owner creating each account in the admin UI is stronger // than either and has nothing to leak at all. // // The hook in pb_hooks/onboarding.pb.js refuses the same thing with a readable // Czech sentence. **Both exist deliberately**: a hook can be edited or fail to // load, so the rule is the structural guarantee; the rule alone would return a // bare 403 that tells a family member nothing. // // `nsfwEnabled` stays out of createRule's reach exactly as before — it was // already `@request.body.nsfwEnabled:isset = false`, and with creation limited to // superusers that condition is now redundant but harmless. Keeping it means the // down migration restores the previous rule verbatim. // // Existing accounts are untouched: this changes creation only. Sign-in, sync and // every other rule are unaffected. migrate( (app) => { const users = app.findCollectionByNameOrId("users") users.createRule = null // superuser only app.save(users) }, (app) => { const users = app.findCollectionByNameOrId("users") users.createRule = "@request.body.nsfwEnabled:isset = false" app.save(users) }, )