diff --git a/go.mod b/go.mod index e5029cf..2a6d1ca 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/pquerna/otp v1.4.0 github.com/rs/zerolog v1.32.0 github.com/tkw1536/goprogram v0.5.0 - github.com/tkw1536/pkglib v0.0.0-20240405094335-7587fbd14dcb + github.com/tkw1536/pkglib v0.0.0-20240408205952-086ddbf0c2d1 github.com/yuin/goldmark v1.6.0 github.com/yuin/goldmark-meta v1.1.0 golang.org/x/crypto v0.22.0 diff --git a/go.sum b/go.sum index 648a4c3..d0f31f1 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,8 @@ github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM= github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tkw1536/goprogram v0.5.0 h1:7vcIjmMdcZPJyRhgdlCaGfHAoOG3oYlFrno1pWXy1Bs= github.com/tkw1536/goprogram v0.5.0/go.mod h1:MDCwqLmvcc2QryMm6oSC9h/QAdE9PewZ2Mp2Lm7MmAg= -github.com/tkw1536/pkglib v0.0.0-20240405094335-7587fbd14dcb h1:FblAz7MB6T+cuWViTEokBcvXcjzZXe8GlgVDTTTDL9Y= -github.com/tkw1536/pkglib v0.0.0-20240405094335-7587fbd14dcb/go.mod h1:A5DbN3900aj/necUqbUQlVjYLU69uMIg0EaBf80b1cY= +github.com/tkw1536/pkglib v0.0.0-20240408205952-086ddbf0c2d1 h1:qhI+Z9mhpTOn81/Wlbh8fcCOlUBChiHdJR/RLgGLs7w= +github.com/tkw1536/pkglib v0.0.0-20240408205952-086ddbf0c2d1/go.mod h1:lXQyTJrMOV6DkSbCamf7R+12pWjWyPFB9f+foGgOoxk= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/internal/dis/component/auth/panel/password.go b/internal/dis/component/auth/panel/password.go index 46c5a3e..f3f55fe 100644 --- a/internal/dis/component/auth/panel/password.go +++ b/internal/dis/component/auth/panel/password.go @@ -43,8 +43,9 @@ func (panel *UserPanel) routePassword(context.Context) http.Handler { }, FieldTemplate: assets.PureCSSFieldTemplate, - Template: tpl.Template(), - TemplateContext: panel.UserFormContext(tpl, menuChangePassword), + Template: tpl.Template(), + TemplateContext: panel.UserFormContext(tpl, menuChangePassword), + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (struct{}, error) { old, passcode, new, new2 := values["old"], values["otp"], values["new"], values["new2"] diff --git a/internal/dis/component/auth/panel/ssh.go b/internal/dis/component/auth/panel/ssh.go index 79880d4..e610b24 100644 --- a/internal/dis/component/auth/panel/ssh.go +++ b/internal/dis/component/auth/panel/ssh.go @@ -160,8 +160,9 @@ func (panel *UserPanel) sshAddRoute(context.Context) http.Handler { }, FieldTemplate: assets.PureCSSFieldTemplate, - Template: tpl.Template(), - TemplateContext: templating.FormTemplateContext(tpl), + Template: tpl.Template(), + TemplateContext: templating.FormTemplateContext(tpl), + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (ak addKeyResult, err error) { ak.User, err = panel.dependencies.Auth.UserOfSession(r) diff --git a/internal/dis/component/auth/panel/tokens.go b/internal/dis/component/auth/panel/tokens.go index e893809..bb390bd 100644 --- a/internal/dis/component/auth/panel/tokens.go +++ b/internal/dis/component/auth/panel/tokens.go @@ -147,8 +147,9 @@ func (panel *UserPanel) tokensAddRoute(context.Context) http.Handler { }, FieldTemplate: assets.PureCSSFieldTemplate, - Template: tplForm.Template(), - TemplateContext: templating.FormTemplateContext(tplForm), + Template: tplForm.Template(), + TemplateContext: templating.FormTemplateContext(tplForm), + LogTemplateError: tplForm.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (at addTokenResult, err error) { at.User, err = panel.dependencies.Auth.UserOfSession(r) diff --git a/internal/dis/component/auth/panel/totp.go b/internal/dis/component/auth/panel/totp.go index 63477e7..90620c7 100644 --- a/internal/dis/component/auth/panel/totp.go +++ b/internal/dis/component/auth/panel/totp.go @@ -37,8 +37,9 @@ func (panel *UserPanel) routeTOTPEnable(context.Context) http.Handler { return struct{}{}, err == nil && user != nil && user.IsTOTPEnabled() }, - Template: tpl.Template(), - TemplateContext: panel.UserFormContext(tpl, menuTOTPEnable), + Template: tpl.Template(), + TemplateContext: panel.UserFormContext(tpl, menuTOTPEnable), + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (struct{}, error) { password := values["password"] @@ -133,6 +134,7 @@ func (panel *UserPanel) routeTOTPEnroll(context.Context) http.Handler { return tpl.Context(r, ctx) }, + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (struct{}, error) { password, otp := values["password"], values["otp"] @@ -189,8 +191,9 @@ func (panel *UserPanel) routeTOTPDisable(context.Context) http.Handler { return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled() }, - Template: tpl.Template(), - TemplateContext: panel.UserFormContext(tpl, menuTOTPDisable), + Template: tpl.Template(), + TemplateContext: panel.UserFormContext(tpl, menuTOTPDisable), + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (struct{}, error) { password, otp := values["password"], values["otp"] diff --git a/internal/dis/component/auth/session.go b/internal/dis/component/auth/session.go index 9636512..86ea3d3 100644 --- a/internal/dis/component/auth/session.go +++ b/internal/dis/component/auth/session.go @@ -197,6 +197,7 @@ func (auth *Auth) authLogin(ctx context.Context) http.Handler { } return tpl.Context(r, templating.NewFormContext(ctx)) }, + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (*AuthUser, error) { username, password, passcode := values["username"], values["password"], values["otp"] diff --git a/internal/dis/component/server/admin/users.go b/internal/dis/component/server/admin/users.go index fb690fb..6c6a3b0 100644 --- a/internal/dis/component/server/admin/users.go +++ b/internal/dis/component/server/admin/users.go @@ -89,8 +89,9 @@ func (admin *Admin) createUser(context.Context) http.Handler { }, FieldTemplate: assets.PureCSSFieldTemplate, - Template: tpl.Template(), - TemplateContext: templating.FormTemplateContext(tpl), + Template: tpl.Template(), + TemplateContext: templating.FormTemplateContext(tpl), + LogTemplateError: tpl.LogTemplateError, Validate: func(r *http.Request, values map[string]string) (cu createUserResult, err error) { cu.User, cu.Passsword, cu.Admin = values["username"], values["password"], values["admin"] == field.CheckboxChecked diff --git a/internal/dis/component/server/handling/handling.go b/internal/dis/component/server/handling/handling.go index 17815de..1016826 100644 --- a/internal/dis/component/server/handling/handling.go +++ b/internal/dis/component/server/handling/handling.go @@ -57,5 +57,12 @@ func (h *Handling) Redirect(Handler content.RedirectFunc) http.Handler { } func (h *Handling) WriteHTML(context any, err error, template *template.Template, w http.ResponseWriter, r *http.Request) error { - return content.WriteHTMLI(context, err, template, h.HTMLInterceptor(), w, r) + return LogTemplateError(r, content.WriteHTMLI(context, err, template, h.HTMLInterceptor(), w, r)) +} + +func LogTemplateError(r *http.Request, err error) error { + if err != nil { + zerolog.Ctx(r.Context()).Err(err).Str("path", r.URL.String()).Msg("error rendering template") + } + return err } diff --git a/internal/dis/component/server/templating/base.go b/internal/dis/component/server/templating/base.go index 668b2e6..4ba1753 100644 --- a/internal/dis/component/server/templating/base.go +++ b/internal/dis/component/server/templating/base.go @@ -34,6 +34,11 @@ func (tpl *Template[C]) Template() *template.Template { return baseTemplate } +// LogTepmplateError logs a non-nil error into the logger found in the request +func (*Template[C]) LogTemplateError(r *http.Request, err error) { + handling.LogTemplateError(r, err) +} + // Context generates the context to pass to an instance of the template returned by Template. func (tpl *Template[C]) Context(r *http.Request, c C, funcs ...FlagFunc) (ctx *tContext[C]) { ctx = tpl.context(r, funcs...)