package auth import ( "net/http" "emperror.dev/errors" "github.com/go-chi/chi/v5" "github.com/go-chi/render" "gitlab.com/1f320/pronouns/backend/server" ) type Server struct { *server.Server } func Mount(srv *server.Server, r chi.Router) { s := &Server{srv} r.Route("/auth", func(r chi.Router) { // generate csrf token, returns all supported OAuth provider URLs r.Get("/urls", server.WrapHandler(s.oauthURLs)) r.Route("/discord", func(r chi.Router) { // takes code + state, validates it, returns token OR discord signup ticket r.Post("/callback", nil) // takes discord signup ticket to register account r.Post("/signup", nil) }) }) } type oauthURLsRequest struct { CallbackURL string `json:"callback_url"` } type oauthURLsResponse struct { Discord string `json:"discord"` } func (s *Server) oauthURLs(w http.ResponseWriter, r *http.Request) error { req, err := Decode[oauthURLsRequest](r) if err != nil { return server.APIError{Code: server.ErrBadRequest} } // generate CSRF state state, err := s.setCSRFState(r.Context()) if err != nil { return errors.Wrap(err, "setting CSRF state") } // copy Discord config and set redirect url discordCfg := discordOAuthConfig discordCfg.RedirectURL = req.CallbackURL render.JSON(w, r, oauthURLsResponse{ Discord: discordCfg.AuthCodeURL(state), }) return nil }