Fix purple

This commit is contained in:
Andras Schmelczer 2026-07-16 07:55:55 +01:00
parent 362b96b8ee
commit 4cc588cac4
2 changed files with 62 additions and 5 deletions

View file

@ -56,8 +56,11 @@ export function useClickedListings() {
.filter((url): url is string => typeof url === 'string');
setClickedUrls(new Set(urls));
})
.catch(() => {
// Visited history is a convenience; a failed load just starts the session empty.
.catch((error) => {
// Visited history is a convenience; a failed load just starts the session empty. Still
// worth surfacing: a silent failure here is indistinguishable from "user visited nothing",
// which is how a proxy 404 on this collection went unnoticed for weeks.
console.warn('Failed to load visited listings:', error);
});
return () => {
cancelled = true;
@ -74,9 +77,12 @@ export function useClickedListings() {
if (!uid) return; // anonymous: recolour for the session, nothing to persist
pb.collection(CLICKED_LISTINGS_COLLECTION)
.create({ user: uid, url })
.catch(() => {
// Ignore duplicate-index conflicts and transient failures; local state already
// reflects the click, and a missed write only means it won't persist to the next visit.
.catch((error: unknown) => {
// A 400 is the idx_clicked_listings_user_url unique index rejecting a re-click that raced
// another tab: local state already reflects it, so it is expected and not worth reporting.
// Anything else means the click will not survive a reload, which the user does notice.
if ((error as { status?: number })?.status === 400) return;
console.warn('Failed to persist visited listing:', error);
});
}, []);

View file

@ -27,6 +27,7 @@ fn is_allowed_pb_path(path: &str) -> bool {
const ALLOWED_PREFIXES: &[&str] = &[
"/api/collections/users/",
"/api/collections/saved_searches/",
"/api/collections/clicked_listings/",
"/api/files/",
];
ALLOWED_PREFIXES
@ -146,3 +147,53 @@ pub async fn proxy_to_pocketbase(
}
}
}
#[cfg(test)]
mod tests {
use super::*;
/// Every collection the frontend reads or writes directly must be reachable. Adding a
/// user-owned collection in pocketbase.rs without an entry here fails silently: the proxy
/// 404s before PocketBase is reached, and the SDK error surfaces as "the feature just
/// doesn't persist". clicked_listings shipped that way and never stored a row.
#[test]
fn frontend_used_collections_are_reachable() {
for collection in ["users", "saved_searches", "clicked_listings"] {
let records = format!("/api/collections/{collection}/records");
assert!(
is_allowed_pb_path(&records),
"{collection} records must be proxy-reachable"
);
}
}
#[test]
fn privileged_and_unknown_paths_are_rejected() {
for path in [
"/api/collections/checkout_sessions/records",
"/api/collections/invites/records",
"/api/admins",
"/api/settings",
"/api/backups",
"/_/",
] {
assert!(!is_allowed_pb_path(path), "{path} must not be proxied");
}
}
/// The trailing slash on each prefix withholds the schema endpoint while allowing the
/// records below it. Dropping it would expose every collection's field definitions.
#[test]
fn collection_schema_endpoints_are_withheld() {
assert!(!is_allowed_pb_path("/api/collections/users"));
assert!(!is_allowed_pb_path("/api/collections/clicked_listings"));
}
#[test]
fn exact_paths_still_allowed() {
assert!(is_allowed_pb_path("/api/health"));
assert!(is_allowed_pb_path("/api/realtime"));
assert!(is_allowed_pb_path("/api/oauth2-redirect"));
assert!(is_allowed_pb_path("/api/files/abc/def/file.png"));
}
}