feat: add logout endpoint and users/me endpoint
- POST /api/v1/logout: deletes client token, returns {status: ok}
- GET /api/v1/users/me: returns session info (delegates to HandleState)
- Add DeleteClient, GetSessionCount, ClientCountForSession, DeleteStaleSessions to db layer
- Add user count to GET /api/v1/server response
- Extract setupAPIv1 to fix funlen lint issue
This commit is contained in:
@@ -779,6 +779,96 @@ func (database *Database) DeleteSession(
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteClient removes a single client record by ID.
|
||||
func (database *Database) DeleteClient(
|
||||
ctx context.Context,
|
||||
clientID int64,
|
||||
) error {
|
||||
_, err := database.conn.ExecContext(
|
||||
ctx,
|
||||
"DELETE FROM clients WHERE id = ?",
|
||||
clientID,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("delete client: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSessionCount returns the number of active sessions.
|
||||
func (database *Database) GetSessionCount(
|
||||
ctx context.Context,
|
||||
) (int64, error) {
|
||||
var count int64
|
||||
|
||||
err := database.conn.QueryRowContext(
|
||||
ctx,
|
||||
"SELECT COUNT(*) FROM sessions",
|
||||
).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf(
|
||||
"get session count: %w", err,
|
||||
)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// ClientCountForSession returns the number of clients
|
||||
// belonging to a session.
|
||||
func (database *Database) ClientCountForSession(
|
||||
ctx context.Context,
|
||||
sessionID int64,
|
||||
) (int64, error) {
|
||||
var count int64
|
||||
|
||||
err := database.conn.QueryRowContext(
|
||||
ctx,
|
||||
`SELECT COUNT(*) FROM clients
|
||||
WHERE session_id = ?`,
|
||||
sessionID,
|
||||
).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf(
|
||||
"client count for session: %w", err,
|
||||
)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// DeleteStaleSessions removes clients not seen since the
|
||||
// cutoff and cleans up orphaned sessions.
|
||||
func (database *Database) DeleteStaleSessions(
|
||||
ctx context.Context,
|
||||
cutoff time.Time,
|
||||
) (int64, error) {
|
||||
res, err := database.conn.ExecContext(ctx,
|
||||
"DELETE FROM clients WHERE last_seen < ?",
|
||||
cutoff,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf(
|
||||
"delete stale clients: %w", err,
|
||||
)
|
||||
}
|
||||
|
||||
deleted, _ := res.RowsAffected()
|
||||
|
||||
_, err = database.conn.ExecContext(ctx,
|
||||
`DELETE FROM sessions WHERE id NOT IN
|
||||
(SELECT DISTINCT session_id FROM clients)`,
|
||||
)
|
||||
if err != nil {
|
||||
return deleted, fmt.Errorf(
|
||||
"delete orphan sessions: %w", err,
|
||||
)
|
||||
}
|
||||
|
||||
return deleted, nil
|
||||
}
|
||||
|
||||
// GetSessionChannels returns channels a session
|
||||
// belongs to.
|
||||
func (database *Database) GetSessionChannels(
|
||||
|
||||
Reference in New Issue
Block a user