MCPcopy Create free account
hub / github.com/PatchMon/PatchMon / Callback

Method Callback

server-source-code/internal/handler/discord.go:170–339  ·  view source on GitHub ↗

Callback handles GET /api/v1/auth/discord/callback. Uses relative redirects (e.g. "/login?error=...") so the browser resolves to the same origin as the callback request. This avoids ERR_INVALID_REDIRECT from malformed CORS_ORIGIN.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

168// Uses relative redirects (e.g. "/login?error=...") so the browser resolves to the same origin
169// as the callback request. This avoids ERR_INVALID_REDIRECT from malformed CORS_ORIGIN.
170func (h *DiscordHandler) Callback(w http.ResponseWriter, r *http.Request) {
171 redirectTo := func(path string) {
172 http.Redirect(w, r, path, http.StatusFound)
173 }
174 if h.discordStore == nil {
175 redirectTo("/login?error=Discord+not+available")
176 return
177 }
178 q := r.URL.Query()
179 code := q.Get("code")
180 state := q.Get("state")
181 oauthError := q.Get("error")
182 if oauthError != "" {
183 if h.log != nil {
184 h.log.Error("discord oauth error", "error", oauthError)
185 }
186 redirectTo("/login?error=Authentication+failed")
187 return
188 }
189 if state == "" || code == "" {
190 redirectTo("/login?error=Invalid+authentication+response")
191 return
192 }
193 cookieState, _ := r.Cookie("discord_state")
194 if cookieState != nil && cookieState.Value != state {
195 redirectTo("/login?error=Invalid+authentication+response")
196 return
197 }
198 sessionData, err := h.discordStore.GetAndDelete(r.Context(), state)
199 if err != nil || sessionData == nil {
200 redirectTo("/login?error=Session+expired")
201 return
202 }
203 http.SetCookie(w, &http.Cookie{Name: "discord_state", Value: "", Path: "/", MaxAge: -1, HttpOnly: true, Secure: isSecureRequest(r)})
204 cfg, err := h.loadDiscordConfig(r.Context())
205 if err != nil || cfg == nil {
206 redirectTo("/login?error=Discord+not+configured")
207 return
208 }
209 accessToken, err := cfg.ExchangeCode(r.Context(), code, sessionData.CodeVerifier)
210 if err != nil {
211 if h.log != nil {
212 h.log.Error("discord token exchange failed", "error", err)
213 }
214 redirectTo("/login?error=Authentication+failed")
215 return
216 }
217 discordUser, err := discord.GetUser(r.Context(), accessToken)
218 if err != nil {
219 if h.log != nil {
220 h.log.Error("discord get user failed", "error", err)
221 }
222 redirectTo("/login?error=Authentication+failed")
223 return
224 }
225 avatarURL := discord.AvatarURL(discordUser.ID, discordUser.Avatar)
226 var avatarPtr *string
227 if avatarURL != "" {

Callers

nothing calls this directly

Calls 15

loadDiscordConfigMethod · 0.95
isSecureRequestFunction · 0.85
AutoSubscribeIfHostedFunction · 0.85
QueryMethod · 0.80
ErrorMethod · 0.80
ExchangeCodeMethod · 0.80
GetByDiscordIDMethod · 0.80
UpdateDiscordLinkMethod · 0.80
GetByDiscordIDOrEmailMethod · 0.80
GetFirstMethod · 0.80
ReplaceAllMethod · 0.80

Tested by

no test coverage detected