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:
@@ -53,6 +53,30 @@ func Open(path string) (*sql.DB, error) {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
// Per-user item ownership. On a migrated DB the column is added without a
|
||||
// REFERENCES clause (ALTER TABLE ADD COLUMN can't carry one cleanly), then
|
||||
// orphaned items are assigned to the first admin (or, failing that, the
|
||||
// first user) so the operator keeps their existing watchlist. Fresh DBs get
|
||||
// the FK from schema.sql and have no rows to backfill.
|
||||
if err := addColumnIfMissing(conn, "items", "user_id", "INTEGER"); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
if _, err := conn.Exec(`
|
||||
UPDATE items SET user_id = (
|
||||
SELECT id FROM users
|
||||
ORDER BY (role = 'admin') DESC, id ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE user_id IS NULL AND EXISTS (SELECT 1 FROM users)
|
||||
`); err != nil {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("backfill item ownership: %w", err)
|
||||
}
|
||||
if _, err := conn.Exec(`CREATE INDEX IF NOT EXISTS idx_items_user ON items(user_id)`); err != nil {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("create items user index: %w", err)
|
||||
}
|
||||
// Multi-user / email columns (Authentik forward-auth + Resend mail).
|
||||
for _, c := range []struct{ col, typ string }{
|
||||
{"email", "TEXT"},
|
||||
|
||||
Reference in New Issue
Block a user