added logout
This commit is contained in:
@@ -28,11 +28,9 @@ func Callback(
|
||||
) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
// Track callback redirect attempts
|
||||
attempts, exceeded, track := store.TrackRedirect(r, "/callback", 5)
|
||||
|
||||
if exceeded {
|
||||
// Build detailed error for logging
|
||||
err := errors.Errorf(
|
||||
"callback redirect loop detected after %d attempts | ip=%s ua=%s path=%s first_seen=%s",
|
||||
attempts,
|
||||
@@ -42,10 +40,8 @@ func Callback(
|
||||
track.FirstSeen.Format("2006-01-02T15:04:05Z07:00"),
|
||||
)
|
||||
|
||||
// Clear the tracking entry
|
||||
store.ClearRedirectTrack(r, "/callback")
|
||||
|
||||
// Show error page
|
||||
throwError(
|
||||
server,
|
||||
w,
|
||||
@@ -66,23 +62,17 @@ func Callback(
|
||||
}
|
||||
data, err := verifyState(cfg.OAuth, w, r, state)
|
||||
if err != nil {
|
||||
// Check if this is a cookie error (401) or signature error (403)
|
||||
if vsErr, ok := err.(*verifyStateError); ok {
|
||||
if vsErr.IsCookieError() {
|
||||
// Cookie missing/expired - normal failed/expired session (DEBUG)
|
||||
throwUnauthorized(server, w, r, "OAuth session not found or expired", err)
|
||||
} else {
|
||||
// Signature verification failed - security violation (WARN)
|
||||
throwForbiddenSecurity(server, w, r, "OAuth state verification failed", err)
|
||||
}
|
||||
} else {
|
||||
// Unknown error type - treat as security issue
|
||||
throwForbiddenSecurity(server, w, r, "OAuth state verification failed", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
// SUCCESS POINT: State verified successfully
|
||||
// Clear redirect tracking - OAuth callback completed successfully
|
||||
store.ClearRedirectTrack(r, "/callback")
|
||||
|
||||
switch data {
|
||||
@@ -108,10 +98,9 @@ func Callback(
|
||||
)
|
||||
}
|
||||
|
||||
// verifyStateError wraps an error with context about what went wrong
|
||||
type verifyStateError struct {
|
||||
err error
|
||||
cookieError bool // true if cookie missing/invalid, false if signature invalid
|
||||
cookieError bool
|
||||
}
|
||||
|
||||
func (e *verifyStateError) Error() string {
|
||||
@@ -135,20 +124,16 @@ func verifyState(
|
||||
return "", errors.New("state param field is empty")
|
||||
}
|
||||
|
||||
// Try to get the cookie
|
||||
uak, err := oauth.GetStateCookie(r)
|
||||
if err != nil {
|
||||
// Cookie missing or invalid - this is a 401 (not authenticated)
|
||||
return "", &verifyStateError{
|
||||
err: errors.Wrap(err, "oauth.GetStateCookie"),
|
||||
cookieError: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the state signature
|
||||
data, err := oauth.VerifyState(cfg, state, uak)
|
||||
if err != nil {
|
||||
// Signature verification failed - this is a 403 (security violation)
|
||||
return "", &verifyStateError{
|
||||
err: errors.Wrap(err, "oauth.VerifyState"),
|
||||
cookieError: false,
|
||||
@@ -170,9 +155,9 @@ func login(
|
||||
store *store.Store,
|
||||
discordAPI *discord.APIClient,
|
||||
) (func(), error) {
|
||||
token, err := discord.AuthorizeWithCode(cfg.Discord, code, cfg.HWSAuth.TrustedHost, discordAPI)
|
||||
token, err := discordAPI.AuthorizeWithCode(code)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "discord.AuthorizeWithCode")
|
||||
return nil, errors.Wrap(err, "discordAPI.AuthorizeWithCode")
|
||||
}
|
||||
session, err := discord.NewOAuthSession(token)
|
||||
if err != nil {
|
||||
@@ -204,6 +189,10 @@ func login(
|
||||
})
|
||||
redirect = "/register"
|
||||
} else {
|
||||
err = user.UpdateDiscordToken(ctx, tx, token)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "user.UpdateDiscordToken")
|
||||
}
|
||||
err := auth.Login(w, r, user, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "auth.Login")
|
||||
|
||||
Reference in New Issue
Block a user