From 85e9a2bcd19fd55ad8534139652729156c3694d2 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Fri, 24 Sep 2021 23:18:23 +0200 Subject: [PATCH] Add SRI template rendering, move variables to template Signed-off-by: Knut Ahlers --- .gitignore | 1 + Makefile | 4 +-- frontend/index.html | 17 ++++++++++--- go.mod | 1 + go.sum | 2 ++ main.go | 60 +++++++++++++++++++++++++++++++++------------ 6 files changed, 65 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 898c154..0ccf1d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +frontend/app.js frontend/app.js.LICENSE.txt frontend/css frontend/js diff --git a/Makefile b/Makefile index 2c90dd1..49a5f6c 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ VER_FONTAWESOME=5.14.0 default: generate download_libs generate: - docker run --rm -i -v $(CURDIR):$(CURDIR) -w $(CURDIR)/src node:14-alpine \ - make generate-inner + docker run --rm -i -v $(CURDIR):$(CURDIR) -w $(CURDIR) node:14-alpine \ + sh -exc "apk add make && make -C src -f ../Makefile generate-inner" generate-inner: npx npm@lts ci diff --git a/frontend/index.html b/frontend/index.html index bf637a1..5efed59 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,7 +6,11 @@ - + OTS - One Time Secrets @@ -24,13 +28,20 @@ // Very early load of theme definition to avoid flickering document.addEventListener('DOMContentLoaded', () => window.refreshTheme()) + + // Template variable from Golang process + {{- range $key, $value := .Vars }} + const {{ $key }} = "{{ $value }}" + {{- end }}
- - + diff --git a/go.mod b/go.mod index c1e0901..0819608 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Luzifer/rconfig/v2 v2.2.1 github.com/gofrs/uuid/v3 v3.1.2 github.com/gorilla/mux v1.7.3 + github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.4.2 github.com/xuyu/goredis v0.0.0-20160929021245-89fbe9474b37 ) diff --git a/go.sum b/go.sum index 22a2625..6601d8a 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/leekchan/gtf v0.0.0-20190214083521-5fba33c5b00b/go.mod h1:thNruaSwydMhkQ8dXzapABF9Sc1Tz08ZBcDdgott9RA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= diff --git a/main.go b/main.go index 0e0648a..e738d12 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "embed" "fmt" "mime" @@ -8,8 +9,10 @@ import ( "os" "path" "strings" + "text/template" "github.com/gorilla/mux" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" http_helpers "github.com/Luzifer/go_helpers/v2/http" @@ -24,6 +27,8 @@ var ( VersionAndExit bool `flag:"version" default:"false" description:"Print version information and exit"` } + cachedIndex []byte + product = "ots" version = "dev" ) @@ -56,38 +61,66 @@ func main() { api := newAPI(store) r := mux.NewRouter() + r.Use(http_helpers.GzipHandler) + api.Register(r.PathPrefix("/api").Subrouter()) - r.HandleFunc("/vars.js", handleVars) - r.PathPrefix("/").HandlerFunc(http_helpers.GzipFunc(assetDelivery)) + + r.HandleFunc("/", handleIndex) + r.PathPrefix("/").HandlerFunc(assetDelivery) log.Fatalf("HTTP server quit: %s", http.ListenAndServe(cfg.Listen, http_helpers.NewHTTPLogHandler(r))) } -func assetDelivery(res http.ResponseWriter, r *http.Request) { +func assetDelivery(w http.ResponseWriter, r *http.Request) { assetName := r.URL.Path - if assetName == "/" { - assetName = "/index.html" - } dot := strings.LastIndex(assetName, ".") if dot < 0 { // There are no assets with no dot in it - http.Error(res, "404 not found", http.StatusNotFound) + http.Error(w, "404 not found", http.StatusNotFound) return } ext := assetName[dot:] assetData, err := assets.ReadFile(path.Join("frontend", assetName)) if err != nil { - http.Error(res, "404 not found", http.StatusNotFound) + http.Error(w, "404 not found", http.StatusNotFound) return } - res.Header().Set("Content-Type", mime.TypeByExtension(ext)) - res.Write(assetData) + w.Header().Set("Content-Type", mime.TypeByExtension(ext)) + w.Write(assetData) } -func handleVars(w http.ResponseWriter, r *http.Request) { +func handleIndex(w http.ResponseWriter, r *http.Request) { + if cachedIndex != nil { + w.Write(cachedIndex) + return + } + + indexTpl, err := assets.ReadFile("frontend/index.html") + if err != nil { + http.Error(w, "404 not found", http.StatusNotFound) + return + } + + tpl, err := template.New("index.html").Funcs(tplFuncs).Parse(string(indexTpl)) + if err != nil { + http.Error(w, errors.Wrap(err, "parsing template").Error(), http.StatusInternalServerError) + return + } + + buf := new(bytes.Buffer) + if err = tpl.Execute(buf, struct{ Vars map[string]string }{Vars: getJSVars(r)}); err != nil { + http.Error(w, errors.Wrap(err, "parsing template").Error(), http.StatusInternalServerError) + return + } + + cachedIndex = buf.Bytes() + w.Write(buf.Bytes()) +} + +func getJSVars(r *http.Request) map[string]string { cookie, _ := r.Cookie("lang") cookieLang := "" @@ -110,10 +143,7 @@ func handleVars(w http.ResponseWriter, r *http.Request) { vars["locale"] = defaultLang } - w.Header().Set("Content-Type", "application/javascript") - for k, v := range vars { - fmt.Fprintf(w, "var %s = %q\n", k, v) - } + return vars } func normalizeLang(lang string) string {