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("/.well-known/oauth-protected-resource", handler.HandleProtectedResourceMetadata) 32 33 // OAuth flow endpoints - stricter rate limiting for authentication attempts 34 r.With(loginLimiter.Middleware).Get("/oauth/login", handler.HandleLogin) 35 r.With(loginLimiter.Middleware).Get("/oauth/mobile/login", handler.HandleMobileLogin) 36 37 // OAuth callback - needs CORS for potential cross-origin redirects from PDS 38 // Use login limiter since callback completes the authentication flow 39 r.With(corsMiddleware(allowedOrigins), loginLimiter.Middleware).Get("/oauth/callback", handler.HandleCallback) 40 41 // Mobile Universal Link callback route 42 // This route is used for iOS Universal Links and Android App Links 43 // Path must match the path in .well-known/apple-app-site-association 44 // Uses the same handler as web callback - the system routes it to the mobile app 45 r.With(loginLimiter.Middleware).Get("/app/oauth/callback", handler.HandleCallback) 46 47 // Session management - dedicated rate limits 48 r.With(logoutLimiter.Middleware).Post("/oauth/logout", handler.HandleLogout) 49 r.With(refreshLimiter.Middleware).Post("/oauth/refresh", handler.HandleRefresh) 50} 51 52// corsMiddleware creates a CORS middleware for OAuth callback with specific allowed origins 53func corsMiddleware(allowedOrigins []string) func(next http.Handler) http.Handler { 54 return cors.Handler(cors.Options{ 55 AllowedOrigins: allowedOrigins, // Only allow specific origins for OAuth callback 56 AllowedMethods: []string{"GET", "POST", "OPTIONS"}, 57 AllowedHeaders: []string{ 58 "Accept", 59 "Authorization", 60 "Content-Type", 61 "X-CSRF-Token", 62 }, 63 ExposedHeaders: []string{"Link"}, 64 AllowCredentials: true, 65 MaxAge: 300, // 5 minutes 66 }) 67}