/// // PocketBase's declarative API rules act as row-level filters for the // "list"/"search" action: an unsatisfiable listRule (e.g. requiring auth) // still returns 200 with an empty result set rather than an error, because // the rule is just a SQL WHERE clause under the hood. See // https://github.com/pocketbase/pocketbase/discussions/6492 // // Bookshelf is a private, two-person library — no anonymous caller should // ever get a 200 back from these endpoints, even an empty one, since some // HTTP/JS clients treat "200 with []" as a successful, allowed request. // This hook makes that explicit: anonymous list/search requests against the // app collections are rejected with 403, matching create/update/ // view/delete (which already 400/404 for unauthenticated callers via the // declarative rules alone). // // "users" is in this list as of 2026-09-12. It was omitted originally, when // the server was only reachable on localhost; the server is now exposed to // the internet, so an anonymous GET of /api/collections/users/records was // answering 200 with an empty array. Nothing leaked — the declarative // listRule filters every row out, so no account, email or id was ever // visible — but it is the same wrong signal this hook exists to remove, and // the accounts collection is the last place to leave it. // // This blocks only UNAUTHENTICATED list/search. Logging in is unaffected: // auth-with-password is not a list request, and it is the only users // endpoint the app calls at all. onRecordsListRequest((e) => { if (!e.auth) { throw new ForbiddenError("Authentication required."); } e.next(); }, "bookcases", "shelves", "books", "users");