Add session management: track active sessions, show on profile, allow revocation
Some checks failed
Deploy / Deploy Production (push) Has been skipped
Deploy / Deploy Preview (push) Failing after 1s
Deploy / Cleanup Preview (push) Has been skipped
CI / UI / Build (pull_request) Failing after 13s
CI / Scraper / Lint (pull_request) Successful in 19s
CI / Scraper / Test (pull_request) Successful in 20s
CI / Scraper / Build (pull_request) Successful in 12s
Some checks failed
Deploy / Deploy Production (push) Has been skipped
Deploy / Deploy Preview (push) Failing after 1s
Deploy / Cleanup Preview (push) Has been skipped
CI / UI / Build (pull_request) Failing after 13s
CI / Scraper / Lint (pull_request) Successful in 19s
CI / Scraper / Test (pull_request) Successful in 20s
CI / Scraper / Build (pull_request) Successful in 12s
- Add user_sessions PocketBase collection (user_id, session_id, user_agent, ip, created/last_seen) - Extend auth token format to include a per-login authSessionId (4th segment) - Hook validates authSessionId against DB on each request; revoked sessions are cleared immediately - Login/register create a session record capturing user-agent and IP - Profile page shows all active sessions with current session highlighted; per-session End/Sign out buttons - GET /api/sessions and DELETE /api/sessions/[id] endpoints for client-side revocation - Backward compatible: legacy 3-segment tokens pass through without DB check
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
// books_found(number), chapters_scraped(number),
|
||||
// chapters_skipped(number), errors(number),
|
||||
// started(date), finished(date), error_message(text)
|
||||
// user_sessions — user_id(text), session_id(text,unique), user_agent(text),
|
||||
// ip(text), created_at(date), last_seen(date)
|
||||
package storage
|
||||
|
||||
import (
|
||||
@@ -394,6 +396,18 @@ func (s *PocketBaseStore) EnsureCollections(ctx context.Context) error {
|
||||
{"name": "error_message", "type": "text"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "user_sessions",
|
||||
"type": "base",
|
||||
"fields": []map[string]interface{}{
|
||||
{"name": "user_id", "type": "text", "required": true},
|
||||
{"name": "session_id", "type": "text", "required": true}, // random ID embedded in auth token
|
||||
{"name": "user_agent", "type": "text"},
|
||||
{"name": "ip", "type": "text"},
|
||||
{"name": "created_at", "type": "date"},
|
||||
{"name": "last_seen", "type": "date"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, col := range collections {
|
||||
name, _ := col["name"].(string)
|
||||
|
||||
Reference in New Issue
Block a user