diff --git a/app/servers.go b/app/servers.go index 47a5c6775..12cd2808f 100644 --- a/app/servers.go +++ b/app/servers.go @@ -1,11 +1,15 @@ package app import ( + "fmt" + "io/fs" "net/http" + "os" "path" "regexp" "strings" + "github.com/cortezaproject/corteza-server/assets" automationRest "github.com/cortezaproject/corteza-server/automation/rest" composeRest "github.com/cortezaproject/corteza-server/compose/rest" "github.com/cortezaproject/corteza-server/docs" @@ -24,6 +28,40 @@ func (app *CortezaApp) mountHttpRoutes(r chi.Router) { ho = app.Opt.HTTPServer ) + func() { + // asset serving has some overlap with auth assets, web-console and webapp serving + // and might be joined with one or more of them in the later version + + var ( + url = options.CleanBase(ho.BaseUrl, "assets") + aPath = ho.AssetsPath + files fs.FS + err error + ) + + if len(aPath) > 0 { + if files, err = loadAssetsFromPath(aPath); err != nil { + // log warning but fallback to embedded assets + app.Log.Warn( + fmt.Sprintf("failed to use custom assets path (HTTP_SERVER_ASSETS_PATH=%s)", aPath), + zap.Error(err), + ) + } + } + + if files == nil { + aPath = "embedded" + files, err = fs.Sub(assets.Embedded, "src") + if err != nil { + // if this is off, we might as well panic + panic(err) + } + } + + r.Handle(url+"/*", http.StripPrefix(url+"/", http.FileServer(http.FS(files)))) + app.Log.Info("web assets mounted", zap.String("url", url), zap.String("path", aPath)) + }() + func() { if ho.WebappEnabled && ho.ApiEnabled && ho.ApiBaseUrl == ho.WebappBaseUrl { app.Log. @@ -133,3 +171,30 @@ func (app *CortezaApp) mountHttpRoutes(r chi.Router) { r.Handle("/.well-known/openid-configuration", app.AuthService.WellKnownOpenIDConfiguration()) }() } + +func loadAssetsFromPath(path string) (assets fs.FS, err error) { + // at least favicon file should exist in the custom asset path + // otherwise we default to embedded files + const check = "favicon32x32.png" + + var ( + fi os.FileInfo + ) + + if fi, err = os.Stat(path); err != nil { + return + + } + + if !fi.IsDir() { + return nil, fmt.Errorf("expecting directory") + + } + + assets = os.DirFS(path) + if _, err = assets.Open(check); err != nil { + return nil, err + } + + return +} diff --git a/assets/embed.go b/assets/embed.go new file mode 100644 index 000000000..49a2a281e --- /dev/null +++ b/assets/embed.go @@ -0,0 +1,10 @@ +package assets + +import ( + "embed" +) + +var ( + //go:embed src/* + Embedded embed.FS +) diff --git a/assets/src/favicon32x32.png b/assets/src/favicon32x32.png new file mode 100644 index 000000000..a0549aa54 Binary files /dev/null and b/assets/src/favicon32x32.png differ diff --git a/assets/src/logo.png b/assets/src/logo.png new file mode 100644 index 000000000..402a07f98 Binary files /dev/null and b/assets/src/logo.png differ