Add Web Push, mobile login and manual escalate for the mobile companion

Sandbar sends Web Push (VAPID + aes128gcm, standard library only) to devices
registered for a topic, serves the companion PWA at /app/, allows one CORS
origin, and exposes a read-only Hammerhead edge view and POST .../escalate.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-27 16:57:07 -06:00
1 parent b4fd31a182
commit 042a60152c
12 files changed
+1056 -18

No files matched your search

+16 -7
View File
@@ -147,6 +147,22 @@ var errThrottled = errors.New("too many attempts, try again in a few minutes")
// login checks credentials and starts a session.
func (s *Server) login(w http.ResponseWriter, r *http.Request, email, password string) (*User, error) {
u, err := s.checkLogin(r, email, password)
if err != nil {
return nil, err
}
tok := newToken()
exp := s.now().Add(sessionTTL)
if _, err := s.st.db.Exec(`INSERT INTO sessions(hash,user_id,expires) VALUES(?,?,?)`, hashToken(tok), u.ID, exp.Unix()); err != nil {
return nil, err
}
http.SetCookie(w, &http.Cookie{Name: sessionCookie, Value: tok, Path: "/", Expires: exp, HttpOnly: true,
SameSite: http.SameSiteStrictMode, Secure: strings.HasPrefix(s.opts.URL, "https://")})
return u, nil
}
// checkLogin verifies an email and password, counting failures against the client's address.
func (s *Server) checkLogin(r *http.Request, email, password string) (*User, error) {
ip := s.realIP(r)
if s.throttled(ip) {
return nil, errThrottled
@@ -160,13 +176,6 @@ func (s *Server) login(w http.ResponseWriter, r *http.Request, email, password s
s.noteFailure(ip)
return nil, errors.New("wrong email or password")
}
tok := newToken()
exp := s.now().Add(sessionTTL)
if _, err := s.st.db.Exec(`INSERT INTO sessions(hash,user_id,expires) VALUES(?,?,?)`, hashToken(tok), u.ID, exp.Unix()); err != nil {
return nil, err
}
http.SetCookie(w, &http.Cookie{Name: sessionCookie, Value: tok, Path: "/", Expires: exp, HttpOnly: true,
SameSite: http.SameSiteStrictMode, Secure: strings.HasPrefix(s.opts.URL, "https://")})
return u, nil
}