Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c7d68c742d |
+34
-3
@@ -1,10 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"gitea.leeworks.dev/0xwheatyz/gitea-mobile/internal/config"
|
||||
giteaclient "gitea.leeworks.dev/0xwheatyz/gitea-mobile/internal/gitea"
|
||||
@@ -36,8 +40,35 @@ func main() {
|
||||
handler = middleware.Auth(cfg.SessionSecret, cfg.GiteaToken)(handler)
|
||||
handler = middleware.Logging()(handler)
|
||||
|
||||
slog.Info("server starting", "addr", cfg.ListenAddr, "gitea_url", cfg.GiteaURL)
|
||||
if err := http.ListenAndServe(cfg.ListenAddr, handler); err != nil {
|
||||
log.Fatalf("server error: %v", err)
|
||||
srv := &http.Server{
|
||||
Addr: cfg.ListenAddr,
|
||||
Handler: handler,
|
||||
}
|
||||
|
||||
// Channel to receive shutdown signals.
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
// Start server in a goroutine.
|
||||
go func() {
|
||||
slog.Info("server starting", "addr", cfg.ListenAddr, "gitea_url", cfg.GiteaURL)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("server error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Block until a shutdown signal is received.
|
||||
sig := <-quit
|
||||
slog.Info("shutdown signal received, draining in-flight requests", "signal", sig.String())
|
||||
|
||||
// Give in-flight requests up to 15 seconds to complete.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
slog.Error("server forced to shutdown", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
slog.Info("server stopped gracefully")
|
||||
}
|
||||
|
||||
@@ -78,31 +78,6 @@ func getToken(r *http.Request) string {
|
||||
return middleware.TokenFromContext(r.Context())
|
||||
}
|
||||
|
||||
// isTokenError returns true if the error indicates an expired or revoked API token.
|
||||
func isTokenError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
msg := err.Error()
|
||||
return strings.Contains(msg, "API error 401") || strings.Contains(msg, "API error 403")
|
||||
}
|
||||
|
||||
// redirectOnTokenError checks if the error is a token auth error and redirects
|
||||
// to /settings with an error banner. Returns true if a redirect was performed.
|
||||
func redirectOnTokenError(w http.ResponseWriter, r *http.Request, err error) bool {
|
||||
if !isTokenError(err) {
|
||||
return false
|
||||
}
|
||||
slog.Warn("Gitea API token expired or revoked, redirecting to settings", "error", err)
|
||||
if isHTMX(r) {
|
||||
w.Header().Set("HX-Redirect", "/settings?error=token_expired")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
http.Redirect(w, r, "/settings?error=token_expired", http.StatusSeeOther)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// getUserOrgs returns the list of org names the user belongs to.
|
||||
func (h *Handler) getUserOrgs(r *http.Request) []string {
|
||||
token := getToken(r)
|
||||
@@ -288,9 +263,6 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
queue, err := h.Client.GetTriageQueue(r.Context(), token, queryOrgs)
|
||||
if err != nil {
|
||||
if redirectOnTokenError(w, r, err) {
|
||||
return
|
||||
}
|
||||
slog.Error("failed to get triage queue", "error", err)
|
||||
data.Error = "Error loading triage queue."
|
||||
} else {
|
||||
@@ -374,9 +346,6 @@ func (h *Handler) ListIssues(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
result, err := h.Client.ListAllIssues(r.Context(), token, queryOrgs, selectedState, page, selectedLabel, selectedRepo)
|
||||
if err != nil {
|
||||
if redirectOnTokenError(w, r, err) {
|
||||
return
|
||||
}
|
||||
slog.Error("failed to list issues", "error", err)
|
||||
data.Error = "Error loading issues."
|
||||
} else {
|
||||
@@ -482,9 +451,6 @@ func (h *Handler) ListPulls(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
result, err := h.Client.ListAllPullRequests(r.Context(), token, queryOrgs, selectedState, page, selectedLabel, selectedRepo)
|
||||
if err != nil {
|
||||
if redirectOnTokenError(w, r, err) {
|
||||
return
|
||||
}
|
||||
slog.Error("failed to list pull requests", "error", err)
|
||||
data.Error = "Error loading pull requests."
|
||||
} else {
|
||||
|
||||
@@ -45,13 +45,6 @@ func (h *SettingsHandler) handleGet(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
data := settingsData{HasToken: hasToken}
|
||||
|
||||
// Show error banner when redirected due to expired/revoked token.
|
||||
if r.URL.Query().Get("error") == "token_expired" {
|
||||
data.Message = "Your Gitea API token is expired or has been revoked. Please enter a new token."
|
||||
data.MessageType = "error"
|
||||
}
|
||||
|
||||
h.renderSettings(w, data)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user