Merge SEC-08: atomic system token issuance

This commit is contained in:
2026-03-13 00:50:39 -07:00
4 changed files with 149 additions and 15 deletions

View File

@@ -470,17 +470,15 @@ func (s *Server) handleTokenIssue(w http.ResponseWriter, r *http.Request) {
return
}
// Revoke existing system token if any.
// Atomically revoke existing system token (if any), track the new token,
// and update system_tokens — all in a single transaction.
// Security: prevents inconsistent state if a crash occurs mid-operation.
var oldJTI string
existing, err := s.db.GetSystemToken(acct.ID)
if err == nil && existing != nil {
_ = s.db.RevokeToken(existing.JTI, "rotated")
oldJTI = existing.JTI
}
if err := s.db.TrackToken(claims.JTI, acct.ID, claims.IssuedAt, claims.ExpiresAt); err != nil {
middleware.WriteError(w, http.StatusInternalServerError, "internal error", "internal_error")
return
}
if err := s.db.SetSystemToken(acct.ID, claims.JTI, claims.ExpiresAt); err != nil {
if err := s.db.IssueSystemToken(oldJTI, claims.JTI, acct.ID, claims.IssuedAt, claims.ExpiresAt); err != nil {
middleware.WriteError(w, http.StatusInternalServerError, "internal error", "internal_error")
return
}