···579579580580// High-level helper for completing auth flow: verifies callback query parameters against persisted auth request info, makes initial token request to the auth server, validates account identifier, and persists session data.
581581func (app *ClientApp) ProcessCallback(ctx context.Context, params url.Values) (*ClientSessionData, error) {
582582+ // There are two callback response formats, for error and non-error conditions, each expecting different
583583+ // parameters.
584584+ //
585585+ // Error responses expect: state, error (and optionally: error_description, error_uri)
586586+ // Non-error responses expect: state, iss, code
582587583588 state := params.Get("state")
584589 if state == "" {
···589594 if err != nil {
590595 return nil, fmt.Errorf("loading auth request info: %w", err)
591596 }
597597+ // This check should never fail, but it guards against a faulty ClientAuthStore implementation
592598 if info.State != state {
593599 return nil, fmt.Errorf("callback state doesn't match request info")
594600 }
···602608 if err == nil {
603609 errorUri = &parsedUri
604610 }
605605- return nil, &ErrCallback{
606606- code: errorCode,
607607- description: params.Get("error_description"),
608608- uri: errorUri,
611611+ return nil, &AuthRequestCallbackError{
612612+ ErrorCode: errorCode,
613613+ ErrorDescription: params.Get("error_description"),
614614+ ErrorURI: errorUri,
609615 }
610616 }
611617618618+ // If we reached here, there was no `error` and we can process the rest of the parameters
612619 authserverURL := params.Get("iss")
613620 authCode := params.Get("code")
614621 if authserverURL == "" || authCode == "" {
+10-10
atproto/auth/oauth/types.go
···411411// Returned by [ClientApp.ProcessCallback] if the AS signals an error in the redirect URL parameters, per rfc6749 section 4.1.2.1
412412//
413413// NOTE: This is untrusted data and should not be e.g. rendered to HTML without appropriate escaping
414414-type ErrCallback struct {
415415- code string
416416- description string
417417- uri *syntax.URI
414414+type AuthRequestCallbackError struct {
415415+ ErrorCode string
416416+ ErrorDescription string
417417+ ErrorURI *syntax.URI
418418}
419419420420-func (e *ErrCallback) Error() string {
421421- res := "callbackError: " + e.code
422422- if e.description != "" {
423423- res += ": " + e.description
420420+func (e *AuthRequestCallbackError) Error() string {
421421+ res := "OAuth request callback error: " + e.ErrorCode
422422+ if e.ErrorDescription != "" {
423423+ res += ": " + e.ErrorDescription
424424 }
425425- if e.uri != nil {
426426- res += " (" + e.uri.String() + ")"
425425+ if e.ErrorURI != nil {
426426+ res += " (" + e.ErrorURI.String() + ")"
427427 }
428428 return res
429429}