Preserve continue URL on auth error re-login

Failed OIDC, magic-link, and SAML sign-ins sent users to /auth/error
without the post-login destination, so Sign in dropped OAuth flows
and deep links. Propagate a validated continue query through auth
error redirects, recover it from OIDC state when the IdP denies or
cancels login, and forward it from AuthErrorPage to /auth/login.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
This commit is contained in:
Cursor Agent
2026-07-27 10:27:38 +00:00
committed by Bryan Frimin
parent 428d28fade
commit 9abea50507
8 changed files with 205 additions and 29 deletions

View File

@@ -128,6 +128,25 @@ func DecodePayload[T any](tokenString string) (*Payload[T], error) {
// ValidateToken validates a token and unmarshals the payload
// It returns an error if the token is invalid or expired
func ValidateToken[T any](secret string, tokenType string, tokenString string) (*Payload[T], error) {
payload, err := parseSignedToken[T](secret, tokenType, tokenString)
if err != nil {
return nil, err
}
if time.Now().After(payload.ExpiresAt) {
return nil, &ErrExpiredToken{message: "token has expired"}
}
return payload, nil
}
// ValidateTokenAllowExpired validates signature and type but ignores expiration.
// Use only when recovering non-sensitive metadata (e.g. post-auth redirect URLs).
func ValidateTokenAllowExpired[T any](secret string, tokenType string, tokenString string) (*Payload[T], error) {
return parseSignedToken[T](secret, tokenType, tokenString)
}
func parseSignedToken[T any](secret string, tokenType string, tokenString string) (*Payload[T], error) {
parts := strings.Split(tokenString, ".")
if len(parts) != 2 {
return nil, &ErrInvalidToken{message: "invalid token format"}
@@ -154,10 +173,6 @@ func ValidateToken[T any](secret string, tokenType string, tokenString string) (
return nil, fmt.Errorf("cannot unmarshal token payload: %w", err)
}
if time.Now().After(payload.ExpiresAt) {
return nil, &ErrExpiredToken{message: "token has expired"}
}
if payload.Type != tokenType {
return nil, &ErrInvalidToken{message: "invalid token type"}
}