mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-28 18:06:34 +02:00
core/ui: fix page title (#4957)
* core/ui: fix page title * cache template
This commit is contained in:
parent
76862c2fe8
commit
c6d1f17100
9 changed files with 56 additions and 31 deletions
|
@ -10,6 +10,6 @@ import (
|
||||||
// DeviceEnrolled displays an HTML page informing the user that they've successfully enrolled a device.
|
// DeviceEnrolled displays an HTML page informing the user that they've successfully enrolled a device.
|
||||||
func DeviceEnrolled(data UserInfoData) http.Handler {
|
func DeviceEnrolled(data UserInfoData) http.Handler {
|
||||||
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||||
return ui.ServePage(w, r, "DeviceEnrolled", data.ToJSON())
|
return ui.ServePage(w, r, "DeviceEnrolled", "Device Enrolled", data.ToJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,6 @@ func SignedOut(data SignedOutData) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise show the signed-out page
|
// otherwise show the signed-out page
|
||||||
return ui.ServePage(w, r, "SignedOut", data.ToJSON())
|
return ui.ServePage(w, r, "SignedOut", "Signed Out", data.ToJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ func (data SignOutConfirmData) ToJSON() map[string]interface{} {
|
||||||
// SignOutConfirm returns a handler that renders the sign out confirm page.
|
// SignOutConfirm returns a handler that renders the sign out confirm page.
|
||||||
func SignOutConfirm(data SignOutConfirmData) http.Handler {
|
func SignOutConfirm(data SignOutConfirmData) http.Handler {
|
||||||
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||||
return ui.ServePage(w, r, "SignOutConfirm", data.ToJSON())
|
return ui.ServePage(w, r, "SignOutConfirm", "Confirm Sign Out", data.ToJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,6 @@ func (data UserInfoData) ToJSON() map[string]any {
|
||||||
// UserInfo returns a handler that renders the user info page.
|
// UserInfo returns a handler that renders the user info page.
|
||||||
func UserInfo(data UserInfoData) http.Handler {
|
func UserInfo(data UserInfoData) http.Handler {
|
||||||
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||||
return ui.ServePage(w, r, "UserInfo", data.ToJSON())
|
return ui.ServePage(w, r, "UserInfo", "User Info Dashboard", data.ToJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,7 +402,7 @@ func (h *Handler) handleView(w http.ResponseWriter, r *http.Request, state *Stat
|
||||||
"selfUrl": r.URL.String(),
|
"selfUrl": r.URL.String(),
|
||||||
}
|
}
|
||||||
httputil.AddBrandingOptionsToMap(m, state.BrandingOptions)
|
httputil.AddBrandingOptionsToMap(m, state.BrandingOptions)
|
||||||
return ui.ServePage(w, r, "WebAuthnRegistration", m)
|
return ui.ServePage(w, r, "WebAuthnRegistration", "Device Registration", m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) saveSessionAndRedirect(w http.ResponseWriter, r *http.Request, state *State, rawRedirectURI string) error {
|
func (h *Handler) saveSessionAndRedirect(w http.ResponseWriter, r *http.Request, state *State, rawRedirectURI string) error {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package httputil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ func (e *HTTPError) ErrorResponse(ctx context.Context, w http.ResponseWriter, r
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
|
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
|
||||||
w.WriteHeader(response.Status)
|
w.WriteHeader(response.Status)
|
||||||
if err := ui.ServePage(w, r, "Error", m); err != nil {
|
if err := ui.ServePage(w, r, "Error", fmt.Sprintf("%d %s", response.Status, response.StatusText), m); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
ui/dist/index.html → ui/dist/index.gohtml
vendored
4
ui/dist/index.html → ui/dist/index.gohtml
vendored
|
@ -25,14 +25,14 @@
|
||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
/>
|
/>
|
||||||
<title>User info dashboard</title>
|
<title>{{.Title}}</title>
|
||||||
<link rel="stylesheet" href="/.pomerium/index.css" />
|
<link rel="stylesheet" href="/.pomerium/index.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script>
|
<script>
|
||||||
window.POMERIUM_DATA = {};
|
window.POMERIUM_DATA = {{.Data}};
|
||||||
</script>
|
</script>
|
||||||
<script src="/.pomerium/index.js"></script>
|
<script src="/.pomerium/index.js"></script>
|
||||||
</body>
|
</body>
|
64
ui/embed.go
64
ui/embed.go
|
@ -3,10 +3,12 @@ package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pomerium/csrf"
|
"github.com/pomerium/csrf"
|
||||||
|
@ -26,35 +28,59 @@ func ServeFile(w http.ResponseWriter, r *http.Request, filePath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServePage serves the index.html page.
|
// ServePage serves the index.html page.
|
||||||
func ServePage(w http.ResponseWriter, r *http.Request, page string, data map[string]interface{}) error {
|
func ServePage(w http.ResponseWriter, r *http.Request, page, title string, data map[string]interface{}) error {
|
||||||
if data == nil {
|
if data == nil {
|
||||||
data = make(map[string]interface{})
|
data = make(map[string]any)
|
||||||
}
|
}
|
||||||
data["csrfToken"] = csrf.Token(r)
|
data["csrfToken"] = csrf.Token(r)
|
||||||
data["page"] = page
|
data["page"] = page
|
||||||
|
|
||||||
jsonData, err := json.Marshal(data)
|
bs, err := renderIndex(map[string]any{
|
||||||
|
"Title": title,
|
||||||
|
"Data": data,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, _, err := openFile("dist/index.html")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bs, err := io.ReadAll(f)
|
|
||||||
_ = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
bs = bytes.Replace(bs,
|
|
||||||
[]byte("window.POMERIUM_DATA = {}"),
|
|
||||||
append([]byte("window.POMERIUM_DATA = "), jsonData...),
|
|
||||||
1)
|
|
||||||
|
|
||||||
http.ServeContent(w, r, "index.html", time.Now(), bytes.NewReader(bs))
|
http.ServeContent(w, r, "index.html", time.Now(), bytes.NewReader(bs))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var startTime = time.Now()
|
var startTime = time.Now()
|
||||||
|
|
||||||
|
func renderIndex(data any) ([]byte, error) {
|
||||||
|
tpl, err := parseIndex()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = tpl.Execute(&buf, data)
|
||||||
|
return buf.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
parseIndexOnce sync.Once
|
||||||
|
parseIndexTemplate *template.Template
|
||||||
|
parseIndexError error
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseIndex() (*template.Template, error) {
|
||||||
|
parseIndexOnce.Do(func() {
|
||||||
|
var f fs.File
|
||||||
|
f, _, parseIndexError = openFile("dist/index.gohtml")
|
||||||
|
if parseIndexError != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var bs []byte
|
||||||
|
bs, parseIndexError = io.ReadAll(f)
|
||||||
|
_ = f.Close()
|
||||||
|
if parseIndexError != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parseIndexTemplate, parseIndexError = template.New("").Parse(string(bs))
|
||||||
|
})
|
||||||
|
return parseIndexTemplate, parseIndexError
|
||||||
|
}
|
||||||
|
|
|
@ -7,10 +7,8 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// ExtUIFS must be set to provide access to UI dist/ files
|
||||||
// ExtUIFS must be set to provide access to UI dist/ files
|
var ExtUIFS fs.FS
|
||||||
ExtUIFS fs.FS
|
|
||||||
)
|
|
||||||
|
|
||||||
func openFile(name string) (f fs.File, etag string, err error) {
|
func openFile(name string) (f fs.File, etag string, err error) {
|
||||||
if ExtUIFS == nil {
|
if ExtUIFS == nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue