Add per-user item ownership and isolation

Items are now private to their owner. Add items.user_id (migrated in
place, existing items backfilled to the first admin) and scope every
item, results, and dashboard view to the signed-in user via owner-scoped
queries plus an ownedItem 404 guard. Admins get strict isolation too;
elevation stays limited to settings and user management.

Alert routing follows ownership: deal emails go only to the item owner
and the weekly digest is built per-recipient from their own items. The
scheduler still polls every active item; the Apify/eBay budget stays a
shared pool visible to all.

Add TestItemsArePrivatePerUser and seed owners in db tests.
This commit is contained in:
prosolis
2026-06-20 13:39:19 -07:00
parent 90a74967e0
commit feea126c5e
11 changed files with 327 additions and 72 deletions

View File

@@ -190,6 +190,15 @@ func (a *App) page(r *http.Request, title, active string) templates.Page {
}
}
// userID returns the signed-in user's id. Handlers in this group all run under
// RequireAuth, so a user is always present; 0 is only returned defensively.
func (a *App) userID(r *http.Request) int64 {
if u := auth.CurrentUserFromRequest(r); u != nil {
return u.ID
}
return 0
}
// noListFS wraps an http.FileSystem and refuses to open directories, which
// stops http.FileServer from emitting an auto-generated directory listing.
type noListFS struct{ fs http.FileSystem }