lint / go (push) Canceled after 0s
lint / go_mod (push) Canceled after 0s
lint / conf (push) Canceled after 0s
lint / docslinks (push) Canceled after 0s
lint / docsorder (push) Canceled after 0s
lint / apidocs (push) Canceled after 0s
lint / other (push) Canceled after 0s
test / test_64 (push) Canceled after 0s
test / test_32 (push) Canceled after 0s
test / test_e2e (push) Canceled after 0s
66 lines
1.6 KiB
Go
66 lines
1.6 KiB
Go
package api //nolint:revive
|
|
|
|
import (
|
|
"embed"
|
|
"net/http"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
//go:embed admin/*
|
|
var adminAssets embed.FS
|
|
|
|
var adminContentTypes = map[string]string{
|
|
".css": "text/css; charset=utf-8",
|
|
".html": "text/html; charset=utf-8",
|
|
".js": "text/javascript; charset=utf-8",
|
|
}
|
|
|
|
func setAdminSecurityHeaders(ctx *gin.Context) {
|
|
ctx.Header("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self'; "+
|
|
"connect-src 'self'; frame-src http: https:; img-src 'self' data:; "+
|
|
"object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'self'")
|
|
ctx.Header("Referrer-Policy", "no-referrer")
|
|
ctx.Header("X-Content-Type-Options", "nosniff")
|
|
ctx.Header("X-Frame-Options", "SAMEORIGIN")
|
|
}
|
|
|
|
func (a *API) onAdminRedirect(ctx *gin.Context) {
|
|
ctx.Redirect(http.StatusMovedPermanently, "/admin/")
|
|
}
|
|
|
|
func (a *API) onAdminAsset(ctx *gin.Context) {
|
|
assetPath := strings.TrimPrefix(ctx.Param("path"), "/")
|
|
if assetPath == "" {
|
|
assetPath = "index.html"
|
|
}
|
|
|
|
assetPath = path.Clean(assetPath)
|
|
if assetPath == "." || strings.HasPrefix(assetPath, "../") {
|
|
ctx.Status(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
byts, err := adminAssets.ReadFile("admin/" + assetPath)
|
|
if err != nil {
|
|
ctx.Status(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
contentType, ok := adminContentTypes[path.Ext(assetPath)]
|
|
if !ok {
|
|
ctx.Status(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
setAdminSecurityHeaders(ctx)
|
|
if assetPath == "index.html" {
|
|
ctx.Header("Cache-Control", "no-store")
|
|
} else {
|
|
ctx.Header("Cache-Control", "no-cache")
|
|
}
|
|
ctx.Data(http.StatusOK, contentType, byts)
|
|
}
|