package urlutil import ( "net/http" "net/url" ) // DefaultDeviceType is the default device type when none is specified. const DefaultDeviceType = "any" // RedirectURL returns the redirect URL from the query string or a cookie. func RedirectURL(r *http.Request) (string, bool) { if v := r.FormValue(QueryRedirectURI); v != "" { return v, true } if c, err := r.Cookie(QueryRedirectURI); err == nil { return c.Value, true } return "", false } // SignOutURL returns the /.pomerium/sign_out URL. func SignOutURL(r *http.Request, authenticateURL *url.URL, key []byte) string { u := authenticateURL.ResolveReference(&url.URL{ Path: "/.pomerium/sign_out", }) if redirectURI, ok := RedirectURL(r); ok { u.RawQuery = (&url.Values{ QueryRedirectURI: {redirectURI}, }).Encode() } return NewSignedURL(key, u).Sign().String() } // WebAuthnURL returns the /.pomerium/webauthn URL. func WebAuthnURL(r *http.Request, authenticateURL *url.URL, key []byte, values url.Values) string { u := authenticateURL.ResolveReference(&url.URL{ Path: "/.pomerium/webauthn", RawQuery: buildURLValues(values, url.Values{ QueryDeviceType: {DefaultDeviceType}, QueryEnrollmentToken: nil, QueryRedirectURI: {authenticateURL.ResolveReference(&url.URL{ Path: "/.pomerium/device-enrolled", }).String()}, }).Encode(), }) return NewSignedURL(key, u).Sign().String() } func buildURLValues(values, defaults url.Values) url.Values { result := make(url.Values) for k, vs := range defaults { if values.Has(k) { result[k] = values[k] } else if vs != nil { result[k] = vs } } return result }