auth: Registrierung, Login, Logout, per-user Sessions (Backend)

This commit is contained in:
OpenClaw Dev 2026-10-31 11:28:17 +01:00
parent c7b4acea02
commit 0ef39cffd6
12 changed files with 703 additions and 40 deletions

View file

@ -54,6 +54,15 @@ CREATE TABLE IF NOT EXISTS summaries(
upto_message_id INTEGER NOT NULL, content TEXT NOT NULL, created_at INTEGER NOT NULL);
CREATE INDEX IF NOT EXISTS idx_summaries_session ON summaries(session_id, id);
CREATE TABLE IF NOT EXISTS settings(key TEXT PRIMARY KEY, value TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE COLLATE NOCASE,
password_hash TEXT NOT NULL, created_at INTEGER NOT NULL);
CREATE TABLE IF NOT EXISTS auth_tokens(
token_hash TEXT PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL);
CREATE INDEX IF NOT EXISTS idx_auth_tokens_user ON auth_tokens(user_id);
`
// migrations add columns to databases created by older versions.
@ -61,6 +70,7 @@ var migrations = []struct{ table, column, ddl string }{
{"sessions", "provider", "ALTER TABLE sessions ADD COLUMN provider TEXT NOT NULL DEFAULT ''"},
{"sessions", "model", "ALTER TABLE sessions ADD COLUMN model TEXT NOT NULL DEFAULT ''"},
{"messages", "cancelled", "ALTER TABLE messages ADD COLUMN cancelled INTEGER NOT NULL DEFAULT 0"},
{"sessions", "user_id", "ALTER TABLE sessions ADD COLUMN user_id INTEGER NOT NULL DEFAULT 0"},
}
func migrate(db *sql.DB) error {
@ -103,10 +113,15 @@ func newID() string {
}
func (s *Store) CreateSession(ctx context.Context, title string) (Session, error) {
return s.CreateSessionFor(ctx, 0, title)
}
// CreateSessionFor creates a session owned by userID (0 = legacy/admin).
func (s *Store) CreateSessionFor(ctx context.Context, userID int64, title string) (Session, error) {
now := time.Now().UTC()
ss := Session{ID: newID(), Title: title, CreatedAt: now, UpdatedAt: now}
_, err := s.db.ExecContext(ctx, `INSERT INTO sessions(id,title,created_at,updated_at) VALUES(?,?,?,?)`,
ss.ID, ss.Title, now.UnixMilli(), now.UnixMilli())
_, err := s.db.ExecContext(ctx, `INSERT INTO sessions(id,title,user_id,created_at,updated_at) VALUES(?,?,?,?,?)`,
ss.ID, ss.Title, userID, now.UnixMilli(), now.UnixMilli())
return ss, err
}
@ -122,7 +137,16 @@ func (s *Store) GetSession(ctx context.Context, id string) (Session, error) {
}
func (s *Store) ListSessions(ctx context.Context, limit int) ([]Session, error) {
rows, err := s.db.QueryContext(ctx, `SELECT id,title,provider,model,created_at,updated_at FROM sessions ORDER BY updated_at DESC LIMIT ?`, limit)
return s.ListSessionsFor(ctx, AllUsers, limit)
}
// AllUsers disables per-user scoping (admin / static token).
const AllUsers int64 = -1
// ListSessionsFor lists the sessions of userID (AllUsers = every session).
func (s *Store) ListSessionsFor(ctx context.Context, userID int64, limit int) ([]Session, error) {
rows, err := s.db.QueryContext(ctx, `SELECT id,title,provider,model,created_at,updated_at FROM sessions
WHERE (?<0 OR user_id=?) ORDER BY updated_at DESC LIMIT ?`, userID, userID, limit)
if err != nil {
return nil, err
}