nandi/gleanpublic⑂ Fork 0
⑂ 4a7542a
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/glean.git
git clone ssh://git@rickub.com/nandi/glean.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Add real IP-aware request logger and empty dashboard stateUnverified

Julien Robert committed 2026-04-21T01:09:43+02:00 Browse files
4a7542a parent: ea7c0ab
modified internal/server/middleware.go +31 -0
@@ -5,6 +5,9 @@ import (
55 "encoding/hex"
66 "net/http"
77 "strings"
8+ "time"
9+
10+ "github.com/go-chi/chi/v5/middleware"
811 )
912
1013 func (s *Server) sessionMiddleware(next http.Handler) http.Handler {
@@ -81,3 +84,31 @@ func (s *Server) csrfMiddleware(next http.Handler) http.Handler {
8184 func sameOrigin(origin, host string) bool {
8285 return strings.HasPrefix(origin, "http://"+host) || strings.HasPrefix(origin, "https://"+host)
8386 }
87+
88+func (s *Server) realIPLogger(next http.Handler) http.Handler {
89+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90+ start := time.Now()
91+ ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
92+
93+ next.ServeHTTP(ww, r)
94+
95+ ip := r.RemoteAddr
96+ if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
97+ ip = strings.TrimSpace(strings.SplitN(xff, ",", 2)[0])
98+ }
99+
100+ scheme := "http"
101+ if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
102+ scheme = "https"
103+ }
104+
105+ s.logger.Info("request",
106+ "method", r.Method,
107+ "url", scheme+"://"+r.Host+r.RequestURI,
108+ "from", ip,
109+ "status", ww.Status(),
110+ "bytes", ww.BytesWritten(),
111+ "duration", time.Since(start).Round(time.Microsecond),
112+ )
113+ })
114+}
@@ -5,6 +5,9 @@ import (
5 "encoding/hex"5 "encoding/hex"
6 "net/http"6 "net/http"
7 "strings"7 "strings"
8+ "time"
9+
10+ "github.com/go-chi/chi/v5/middleware"
8 )11 )
9 12
10 func (s *Server) sessionMiddleware(next http.Handler) http.Handler {13 func (s *Server) sessionMiddleware(next http.Handler) http.Handler {
@@ -81,3 +84,31 @@ func (s *Server) csrfMiddleware(next http.Handler) http.Handler {
81 func sameOrigin(origin, host string) bool {84 func sameOrigin(origin, host string) bool {
82 return strings.HasPrefix(origin, "http://"+host) || strings.HasPrefix(origin, "https://"+host)85 return strings.HasPrefix(origin, "http://"+host) || strings.HasPrefix(origin, "https://"+host)
83 }86 }
87+
88+func (s *Server) realIPLogger(next http.Handler) http.Handler {
89+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90+ start := time.Now()
91+ ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
92+
93+ next.ServeHTTP(ww, r)
94+
95+ ip := r.RemoteAddr
96+ if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
97+ ip = strings.TrimSpace(strings.SplitN(xff, ",", 2)[0])
98+ }
99+
100+ scheme := "http"
101+ if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
102+ scheme = "https"
103+ }
104+
105+ s.logger.Info("request",
106+ "method", r.Method,
107+ "url", scheme+"://"+r.Host+r.RequestURI,
108+ "from", ip,
109+ "status", ww.Status(),
110+ "bytes", ww.BytesWritten(),
111+ "duration", time.Since(start).Round(time.Microsecond),
112+ )
113+ })
114+}
modified internal/server/server.go +1 -1
@@ -85,7 +85,7 @@ func New(database *db.DB, clientID, callbackURL, addr string, scheduler *feed.Sc
8585 }
8686
8787 func (s *Server) setupMiddleware() {
88- s.router.Use(middleware.Logger)
88+ s.router.Use(s.realIPLogger)
8989 s.router.Use(middleware.Recoverer)
9090 s.router.Use(middleware.Compress(5))
9191 s.router.Use(s.metricsMiddleware)
@@ -85,7 +85,7 @@ func New(database *db.DB, clientID, callbackURL, addr string, scheduler *feed.Sc
85 }85 }
86 86
87 func (s *Server) setupMiddleware() {87 func (s *Server) setupMiddleware() {
88- s.router.Use(middleware.Logger)88+ s.router.Use(s.realIPLogger)
89 s.router.Use(middleware.Recoverer)89 s.router.Use(middleware.Recoverer)
90 s.router.Use(middleware.Compress(5))90 s.router.Use(middleware.Compress(5))
91 s.router.Use(s.metricsMiddleware)91 s.router.Use(s.metricsMiddleware)
modified internal/tmpl/dashboard.html +14 -0
@@ -6,6 +6,19 @@
66 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>
77 </div>
88 </div>
9+{{if eq .SubscriptionCount 0}}
10+<div class="bg-spot-surface rounded-xl py-16 px-6 text-center mb-6">
11+ <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
12+ <svg class="w-8 h-8 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
13+ </div>
14+ <h2 class="text-lg font-semibold text-spot-text mb-2">Add your first feed</h2>
15+ <p class="text-sm text-spot-secondary mb-6">Subscribe to RSS feeds to start building your personalized reading experience.</p>
16+ <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-spot-green text-white text-sm font-medium hover:opacity-90 transition">
17+ <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
18+ Add feeds
19+ </a>
20+</div>
21+{{else}}
922 <p class="text-sm text-spot-secondary mb-6">Your personalized feed, based on your social graph.</p>
1023
1124 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
@@ -119,3 +132,4 @@
119132 </div>
120133 </div>
121134 {{end}}
135+{{end}}
@@ -6,6 +6,19 @@
6 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>6 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>
7 </div>7 </div>
8 </div>8 </div>
9+{{if eq .SubscriptionCount 0}}
10+<div class="bg-spot-surface rounded-xl py-16 px-6 text-center mb-6">
11+ <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
12+ <svg class="w-8 h-8 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
13+ </div>
14+ <h2 class="text-lg font-semibold text-spot-text mb-2">Add your first feed</h2>
15+ <p class="text-sm text-spot-secondary mb-6">Subscribe to RSS feeds to start building your personalized reading experience.</p>
16+ <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-spot-green text-white text-sm font-medium hover:opacity-90 transition">
17+ <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
18+ Add feeds
19+ </a>
20+</div>
21+{{else}}
9 <p class="text-sm text-spot-secondary mb-6">Your personalized feed, based on your social graph.</p>22 <p class="text-sm text-spot-secondary mb-6">Your personalized feed, based on your social graph.</p>
10 23
11 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">24 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
@@ -119,3 +132,4 @@
119 </div>132 </div>
120 </div>133 </div>
121 {{end}}134 {{end}}
135+{{end}}