A community based topic aggregation platform built on atproto
1package routes 2 3import ( 4 "Coves/internal/api/middleware" 5 "Coves/internal/atproto/oauth" 6 "net/http" 7 "time" 8 9 "github.com/go-chi/chi/v5" 10 "github.com/go-chi/cors" 11) 12 13// RegisterOAuthRoutes registers OAuth-related endpoints on the router with dedicated rate limiting 14// OAuth endpoints have stricter rate limits to prevent: 15// - Credential stuffing attacks on login endpoints 16// - OAuth state exhaustion 17// - Refresh token abuse 18func RegisterOAuthRoutes(r chi.Router, handler *oauth.OAuthHandler, allowedOrigins []string) { 19 // Create stricter rate limiters for OAuth endpoints 20 // Login endpoints: 10 req/min per IP (credential stuffing protection) 21 loginLimiter := middleware.NewRateLimiter(10, 1*time.Minute) 22 23 // Refresh endpoint: 20 req/min per IP (slightly higher for legitimate token refresh) 24 refreshLimiter := middleware.NewRateLimiter(20, 1*time.Minute) 25 26 // Logout endpoint: 10 req/min per IP 27 logoutLimiter := middleware.NewRateLimiter(10, 1*time.Minute) 28 29 // OAuth metadata endpoints - public, no extra rate limiting (use global limit) 30 r.Get("/oauth/client-metadata.json", handler.HandleClientMetadata) 31 r.Get("/oauth/jwks.json", handler.HandleJWKS) 32 33 // Alternative well-known paths for OAuth metadata 34 r.Get("/.well-known/oauth-jwks.json", handler.HandleJWKS) 35 r.Get("/.well-known/oauth-protected-resource", handler.HandleProtectedResourceMetadata) 36 37 // OAuth flow endpoints - stricter rate limiting for authentication attempts 38 r.With(loginLimiter.Middleware).Get("/oauth/login", handler.HandleLogin) 39 r.With(loginLimiter.Middleware).Get("/oauth/mobile/login", handler.HandleMobileLogin) 40 41 // OAuth callback - needs CORS for potential cross-origin redirects from PDS 42 // Use login limiter since callback completes the authentication flow 43 r.With(corsMiddleware(allowedOrigins), loginLimiter.Middleware).Get("/oauth/callback", handler.HandleCallback) 44 45 // Mobile Universal Link callback route 46 // This route is used for iOS Universal Links and Android App Links 47 // Path must match the path in .well-known/apple-app-site-association 48 // Uses the same handler as web callback - the system routes it to the mobile app 49 r.With(loginLimiter.Middleware).Get("/app/oauth/callback", handler.HandleCallback) 50 51 // Session management - dedicated rate limits 52 r.With(logoutLimiter.Middleware).Post("/oauth/logout", handler.HandleLogout) 53 r.With(refreshLimiter.Middleware).Post("/oauth/refresh", handler.HandleRefresh) 54} 55 56// corsMiddleware creates a CORS middleware for OAuth callback with specific allowed origins 57func corsMiddleware(allowedOrigins []string) func(next http.Handler) http.Handler { 58 return cors.Handler(cors.Options{ 59 AllowedOrigins: allowedOrigins, // Only allow specific origins for OAuth callback 60 AllowedMethods: []string{"GET", "POST", "OPTIONS"}, 61 AllowedHeaders: []string{ 62 "Accept", 63 "Authorization", 64 "Content-Type", 65 "X-CSRF-Token", 66 }, 67 ExposedHeaders: []string{"Link"}, 68 AllowCredentials: true, 69 MaxAge: 300, // 5 minutes 70 }) 71}