feat: fb and google oauth
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/prabhupadasays/spsays-bff/internal/worker"
|
||||
"github.com/prabhupadasays/spsays-bff/pkg/auth"
|
||||
"github.com/prabhupadasays/spsays-bff/pkg/mailer"
|
||||
"github.com/prabhupadasays/spsays-bff/pkg/oauth"
|
||||
"github.com/prabhupadasays/spsays-bff/pkg/shorturl"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@@ -45,6 +46,7 @@ type Server struct {
|
||||
searchH *handler.SearchHandler
|
||||
shortURLH *handler.ShortURLHandler
|
||||
authH *handler.AuthHandler
|
||||
oauthH *handler.OAuthHandler
|
||||
userH *handler.UserHandler
|
||||
postH *handler.PostHandler
|
||||
bookmarkH *handler.BookmarkHandler
|
||||
@@ -121,6 +123,7 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
|
||||
|
||||
userRepo := repository.NewUserRepo(s.pg)
|
||||
tokenRepo := repository.NewAuthTokenRepo(s.pg)
|
||||
oauthRepo := repository.NewOAuthAccountRepo(s.pg)
|
||||
|
||||
r2, err := repository.NewR2(repository.R2Config{
|
||||
AccountID: cfg.R2AccountID,
|
||||
@@ -145,7 +148,7 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
|
||||
From: cfg.SMTPFrom,
|
||||
}, logger)
|
||||
|
||||
authSvc := service.NewAuthService(userRepo, tokenRepo, issuer, mail, logger, cfg.FrontendURL)
|
||||
authSvc := service.NewAuthService(userRepo, tokenRepo, oauthRepo, issuer, mail, logger, cfg.FrontendURL)
|
||||
userSvc := service.NewUserService(userRepo, r2)
|
||||
|
||||
// Social repositories + services share the same Postgres pool and R2 client.
|
||||
@@ -162,6 +165,25 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
|
||||
s.userRepo = userRepo
|
||||
s.authH = handler.NewAuthHandler(authSvc, cookieOpts)
|
||||
s.userH = handler.NewUserHandler(userSvc)
|
||||
|
||||
// OAuth — wired only when at least one provider is configured. The
|
||||
// registry skips providers with missing creds, so partial configs (e.g.
|
||||
// Google only, no Facebook) work out of the box.
|
||||
providers := oauth.NewRegistry(oauth.Credentials{
|
||||
GoogleClientID: cfg.GoogleOAuthClientID,
|
||||
GoogleClientSecret: cfg.GoogleOAuthClientSecret,
|
||||
FacebookClientID: cfg.FacebookOAuthClientID,
|
||||
FacebookClientSecret: cfg.FacebookOAuthClientSecret,
|
||||
})
|
||||
if len(providers) > 0 {
|
||||
s.oauthH = handler.NewOAuthHandler(
|
||||
authSvc, cookieOpts, providers,
|
||||
[]byte(cfg.JWTSecret), cfg.BFFPublicURL, cfg.FrontendURL,
|
||||
logger,
|
||||
)
|
||||
} else {
|
||||
logger.Info("oauth: no providers configured — /auth/oauth/* will 404")
|
||||
}
|
||||
s.postH = handler.NewPostHandler(postSvc)
|
||||
s.bookmarkH = handler.NewBookmarkHandler(bookmarkSvc)
|
||||
s.collectionH = handler.NewCollectionHandler(collectionSvc, postRepo, issuer, userRepo)
|
||||
@@ -486,6 +508,15 @@ func (s *Server) setupRouter() {
|
||||
r.Post("/reset-password", s.authH.ResetPassword)
|
||||
r.Post("/verify-email", s.authH.VerifyEmail)
|
||||
|
||||
// OAuth (Google, Facebook, …). GET endpoints because the browser
|
||||
// navigates directly to /start (top-level redirect) and the
|
||||
// provider redirects back to /callback. Both flows set cookies
|
||||
// and 302 — they never return JSON.
|
||||
if s.oauthH != nil {
|
||||
r.Get("/oauth/{provider}/start", s.oauthH.Start)
|
||||
r.Get("/oauth/{provider}/callback", s.oauthH.Callback)
|
||||
}
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(middleware.RequireAuth(s.authIssuer, s.userRepo))
|
||||
r.Get("/me", s.authH.Me)
|
||||
|
||||
Reference in New Issue
Block a user