package urlutil import ( "errors" "net/http" "net/url" ) // ErrMissingRedirectURI indicates the pomerium_redirect_uri was missing from the query string. var ErrMissingRedirectURI = errors.New("missing " + QueryRedirectURI) // GetCallbackURL gets the proxy's callback URL from a request and a base64url encoded + encrypted session state JWT. func GetCallbackURL(r *http.Request, encodedSessionJWT string) (*url.URL, error) { return GetCallbackURLForRedirectURI(r, encodedSessionJWT, r.FormValue(QueryRedirectURI)) } // GetCallbackURLForRedirectURI gets the proxy's callback URL from a request and a base64url encoded + encrypted session // state JWT. func GetCallbackURLForRedirectURI(r *http.Request, encodedSessionJWT, rawRedirectURI string) (*url.URL, error) { if rawRedirectURI == "" { return nil, ErrMissingRedirectURI } redirectURI, err := ParseAndValidateURL(rawRedirectURI) if err != nil { return nil, err } var callbackURI *url.URL if callbackStr := r.FormValue(QueryCallbackURI); callbackStr != "" { callbackURI, err = ParseAndValidateURL(callbackStr) if err != nil { return nil, err } } else { // otherwise, assume callback is the same host as redirect callbackURI, err = DeepCopy(redirectURI) if err != nil { return nil, err } callbackURI.Path = "/.pomerium/callback/" callbackURI.RawQuery = "" } callbackParams := callbackURI.Query() if r.FormValue(QueryIsProgrammatic) == "true" { callbackParams.Set(QueryIsProgrammatic, "true") } // add our encoded and encrypted route-session JWT to a query param callbackParams.Set(QuerySessionEncrypted, encodedSessionJWT) callbackParams.Set(QueryRedirectURI, redirectURI.String()) callbackURI.RawQuery = callbackParams.Encode() return callbackURI, nil }