Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee
17
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: correctly log ip in join requests

+12 -11
+2 -3
internal/handlers/handlers.go
··· 1973 1973 } 1974 1974 1975 1975 emailAddr := strings.TrimSpace(r.FormValue("email")) 1976 - handle := strings.TrimSpace(r.FormValue("handle")) 1977 1976 message := strings.TrimSpace(r.FormValue("message")) 1978 1977 1979 1978 // Basic email validation ··· 1988 1987 Email: emailAddr, 1989 1988 Message: message, 1990 1989 CreatedAt: time.Now().UTC(), 1991 - IP: r.RemoteAddr, 1990 + IP: middleware.GetClientIP(r), 1992 1991 } 1993 1992 1994 1993 if h.joinStore != nil { ··· 1997 1996 http.Error(w, "Failed to save request, please try again", http.StatusInternalServerError) 1998 1997 return 1999 1998 } 2000 - log.Info().Str("email", emailAddr).Str("handle", handle).Msg("Join request saved") 1999 + log.Info().Str("email", emailAddr).Msg("Join request saved") 2001 2000 } 2002 2001 2003 2002 // Send admin notification email (non-blocking)
+3 -3
internal/middleware/logging.go
··· 11 11 "github.com/rs/zerolog" 12 12 ) 13 13 14 - // getClientIP extracts the real client IP address from the request, 14 + // GetClientIP extracts the real client IP address from the request, 15 15 // checking X-Forwarded-For and X-Real-IP headers for reverse proxy setups. 16 - func getClientIP(r *http.Request) string { 16 + func GetClientIP(r *http.Request) string { 17 17 // Check X-Forwarded-For header (can contain multiple IPs: client, proxy1, proxy2) 18 18 if xff := r.Header.Get("X-Forwarded-For"); xff != "" { 19 19 // Take the first IP (the original client) ··· 73 73 Str("query", r.URL.RawQuery). 74 74 Int("status", rw.statusCode). 75 75 Dur("duration", duration). 76 - Str("client_ip", getClientIP(r)). 76 + Str("client_ip", GetClientIP(r)). 77 77 Str("user_agent", r.UserAgent()). 78 78 Int64("bytes_written", rw.bytesWritten). 79 79 Str("proto", r.Proto)
+1 -2
internal/middleware/security.go
··· 179 179 func RateLimitMiddleware(config *RateLimitConfig) func(http.Handler) http.Handler { 180 180 return func(next http.Handler) http.Handler { 181 181 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 182 - ip := getClientIP(r) 182 + ip := GetClientIP(r) 183 183 path := r.URL.Path 184 184 185 185 var limiter *RateLimiter ··· 205 205 } 206 206 } 207 207 208 - // getClientIP is defined in logging.go 209 208 210 209 // RequireHTMXMiddleware ensures that certain API routes are only accessible via HTMX requests. 211 210 // This prevents direct browser access to internal API endpoints that return fragments or JSON.
+6 -3
module.nix
··· 146 146 host = lib.mkOption { 147 147 type = lib.types.str; 148 148 default = ""; 149 - description = "SMTP server hostname. Can also be set via SMTP_HOST in an environment file."; 149 + description = 150 + "SMTP server hostname. Can also be set via SMTP_HOST in an environment file."; 150 151 example = "smtp.example.com"; 151 152 }; 152 153 153 154 port = lib.mkOption { 154 155 type = lib.types.nullOr lib.types.port; 155 156 default = null; 156 - description = "SMTP server port. Can also be set via SMTP_PORT in an environment file. Defaults to 587 if unset."; 157 + description = 158 + "SMTP server port. Can also be set via SMTP_PORT in an environment file."; 157 159 }; 158 160 159 161 from = lib.mkOption { 160 162 type = lib.types.str; 161 163 default = ""; 162 - description = "Sender address for outgoing email. Can also be set via SMTP_FROM in an environment file."; 164 + description = 165 + "Sender address for outgoing email. Can also be set via SMTP_FROM in an environment file."; 163 166 example = "noreply@arabica.example.com"; 164 167 }; 165 168 };