diff --git a/authenticate/authenticate.go b/authenticate/authenticate.go index bad54d1af..5183afca4 100644 --- a/authenticate/authenticate.go +++ b/authenticate/authenticate.go @@ -137,7 +137,7 @@ func (a *Authenticate) getWebAuthnURL(values url.Values) (*url.URL, error) { urlutil.QueryDeviceType: {webauthnutil.DefaultDeviceType}, urlutil.QueryEnrollmentToken: nil, urlutil.QueryRedirectURI: {uri.ResolveReference(&url.URL{ - Path: "/.pomerium/", + Path: "/.pomerium/device-enrolled", }).String()}, }).Encode(), }) diff --git a/authenticate/handlers.go b/authenticate/handlers.go index 523febac1..dd6ef5f2d 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -18,6 +18,7 @@ import ( "golang.org/x/oauth2" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/pomerium/pomerium/authenticate/handlers" "github.com/pomerium/pomerium/authenticate/handlers/webauthn" "github.com/pomerium/pomerium/internal/httputil" "github.com/pomerium/pomerium/internal/identity" @@ -98,6 +99,7 @@ func (a *Authenticate) mountDashboard(r *mux.Router) { sr.Path("/sign_in").Handler(a.requireValidSignature(a.SignIn)) sr.Path("/sign_out").Handler(a.requireValidSignature(a.SignOut)) sr.Path("/webauthn").Handler(webauthn.New(a.getWebauthnState)) + sr.Path("/device-enrolled").Handler(handlers.DeviceEnrolled()) } func (a *Authenticate) mountWellKnown(r *mux.Router) { diff --git a/authenticate/handlers/device-enrolled.go b/authenticate/handlers/device-enrolled.go new file mode 100644 index 000000000..236c72e1d --- /dev/null +++ b/authenticate/handlers/device-enrolled.go @@ -0,0 +1,18 @@ +package handlers + +import ( + "html/template" + "net/http" + + "github.com/pomerium/pomerium/internal/frontend" + "github.com/pomerium/pomerium/internal/httputil" +) + +// DeviceEnrolled displays an HTML page informing the user that they've successfully enrolled a device. +func DeviceEnrolled() http.Handler { + tpl := template.Must(frontend.NewTemplates()) + type TemplateData struct{} + return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { + return tpl.ExecuteTemplate(w, "device-enrolled.html", TemplateData{}) + }) +} diff --git a/authenticate/handlers/handlers.go b/authenticate/handlers/handlers.go new file mode 100644 index 000000000..5e6ef3192 --- /dev/null +++ b/authenticate/handlers/handlers.go @@ -0,0 +1,2 @@ +// Package handlers contains various web handlers for the authenticate service. +package handlers diff --git a/authenticate/handlers/webauthn/webauthn.go b/authenticate/handlers/webauthn/webauthn.go index bf95f9ad2..401f9fec6 100644 --- a/authenticate/handlers/webauthn/webauthn.go +++ b/authenticate/handlers/webauthn/webauthn.go @@ -302,6 +302,7 @@ func (h *Handler) handleRegister(w http.ResponseWriter, r *http.Request, state * Id: webauthnutil.GetDeviceCredentialID(serverCredential.ID), }, }) + return h.saveSessionAndRedirect(w, r, state, redirectURIParam) } @@ -432,7 +433,7 @@ func (h *Handler) saveSessionAndRedirect(w http.ResponseWriter, r *http.Request, encodedJWT := base64.URLEncoding.EncodeToString(encryptedJWT) // redirect to the proxy callback URL with the session - callbackURL, err := urlutil.GetCallbackURL(r, encodedJWT) + callbackURL, err := urlutil.GetCallbackURLForRedirectURI(r, encodedJWT, rawRedirectURI) if err != nil { return err } diff --git a/internal/frontend/assets/html/device-enrolled.go.html b/internal/frontend/assets/html/device-enrolled.go.html new file mode 100644 index 000000000..9597d8e0d --- /dev/null +++ b/internal/frontend/assets/html/device-enrolled.go.html @@ -0,0 +1,30 @@ +{{define "device-enrolled.html"}} + + + Device Successfully Enrolled + {{template "header.html"}} + + + +
+
+
+
+
+
+
+
+ Device Successfully Enrolled + +
+
+
+
+
+ + +{{end}} diff --git a/internal/urlutil/proxy.go b/internal/urlutil/proxy.go index c4e64f65f..87ef13ebf 100644 --- a/internal/urlutil/proxy.go +++ b/internal/urlutil/proxy.go @@ -11,7 +11,12 @@ 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) { - rawRedirectURI := r.FormValue(QueryRedirectURI) + 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 }