···21212222var jwtExpirationDuration = 30 * time.Second
23232424+// Returned by [ClientApp.ProcessCallback] if the AS signals an error in the redirect URL parameters, per rfc6749 section 4.1.2.1
2525+//
2626+// NOTE: This is untrusted data and should not be e.g. rendered to HTML without appropriate escaping
2727+type CallbackError struct {
2828+ code string
2929+ description string
3030+ uri *syntax.URI
3131+}
3232+3333+func (e *CallbackError) Error() string {
3434+ res := "callbackError: " + e.code
3535+ if e.description != "" {
3636+ res += ": " + e.description
3737+ }
3838+ if e.uri != nil {
3939+ res += " (" + e.uri.String() + ")"
4040+ }
4141+ return res
4242+}
4343+2444// Service-level client. Used to establish and refrsh OAuth sessions, but is not itself account or session specific, and can not be used directly to make API calls on behalf of a user.
2545type ClientApp struct {
2646 Client *http.Client
···579599580600// 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.
581601func (app *ClientApp) ProcessCallback(ctx context.Context, params url.Values) (*ClientSessionData, error) {
602602+603603+ errorCode := params.Get("error")
604604+ if errorCode != "" {
605605+ var errorUri *syntax.URI
606606+ parsedUri, err := syntax.ParseURI(params.Get("error_uri"))
607607+ if err == nil {
608608+ errorUri = &parsedUri
609609+ }
610610+ return nil, &CallbackError{
611611+ code: errorCode,
612612+ description: params.Get("error_description"),
613613+ uri: errorUri,
614614+ }
615615+ }
582616583617 state := params.Get("state")
584618 authserverURL := params.Get("iss")