feat: runtime config, Matomo analytics, chat accounts, DM history/search, and Prometheus retention
This commit is contained in:
1 parent
06ab5b4655
commit
121fdbacdc
27 files changed
+1841
-161
No files matched your search
@@ -137,4 +137,52 @@ func RequireAdmin(store *SessionStore, cookieName string) func(http.HandlerFunc)
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserSessionStore maps user session tokens to usernames with expiry.
|
||||
type UserSessionStore struct {
|
||||
mu sync.Mutex
|
||||
sessions map[string]userSession
|
||||
}
|
||||
|
||||
type userSession struct {
|
||||
Username string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
// NewUserSessionStore creates a new user session store.
|
||||
func NewUserSessionStore() *UserSessionStore {
|
||||
return &UserSessionStore{sessions: make(map[string]userSession)}
|
||||
}
|
||||
|
||||
// Add stores a user session token with username and expiry.
|
||||
func (s *UserSessionStore) Add(token, username string, expiresAt time.Time) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.sessions[token] = userSession{Username: username, ExpiresAt: expiresAt}
|
||||
}
|
||||
|
||||
// Username returns the username for a valid, unexpired token.
|
||||
func (s *UserSessionStore) Username(token string) (string, bool) {
|
||||
if token == "" {
|
||||
return "", false
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
sess, ok := s.sessions[token]
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
if time.Now().After(sess.ExpiresAt) {
|
||||
delete(s.sessions, token)
|
||||
return "", false
|
||||
}
|
||||
return sess.Username, true
|
||||
}
|
||||
|
||||
// Remove deletes a user session token.
|
||||
func (s *UserSessionStore) Remove(token string) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
delete(s.sessions, token)
|
||||
}
|
||||
Reference in new issue
Block a user