|
@@ -4,6 +4,7 @@ import (
|
|
|
"crypto/subtle"
|
|
|
"net/http"
|
|
|
"net/url"
|
|
|
+ "path"
|
|
|
"regexp"
|
|
|
"strconv"
|
|
|
|
|
@@ -37,7 +38,7 @@ var (
|
|
|
)
|
|
|
|
|
|
// registerHandlers registers HTTP handlers.
|
|
|
-func registerHTTPHandlers(e *echo.Echo, app *App) {
|
|
|
+func initHTTPHandlers(e *echo.Echo, app *App) {
|
|
|
// Group of private handlers with BasicAuth.
|
|
|
var g *echo.Group
|
|
|
|
|
@@ -48,7 +49,15 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
|
|
|
g = e.Group("", middleware.BasicAuth(basicAuth))
|
|
|
}
|
|
|
|
|
|
- g.GET("/", handleIndexPage)
|
|
|
+ // Admin JS app views.
|
|
|
+ // /admin/static/* file server is registered in initHTTPServer().
|
|
|
+ g.GET("/", func(c echo.Context) error {
|
|
|
+ return c.Redirect(http.StatusPermanentRedirect, path.Join(adminRoot, ""))
|
|
|
+ })
|
|
|
+ g.GET(path.Join(adminRoot, ""), handleAdminPage)
|
|
|
+ g.GET(path.Join(adminRoot, "/*"), handleAdminPage)
|
|
|
+
|
|
|
+ // API endpoints.
|
|
|
g.GET("/api/health", handleHealthCheck)
|
|
|
g.GET("/api/config", handleGetServerConfig)
|
|
|
g.GET("/api/lang/:lang", handleGetI18nLang)
|
|
@@ -125,21 +134,6 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
|
|
|
g.PUT("/api/templates/:id/default", handleTemplateSetDefault)
|
|
|
g.DELETE("/api/templates/:id", handleDeleteTemplate)
|
|
|
|
|
|
- // Static admin views.
|
|
|
- g.GET("/lists", handleIndexPage)
|
|
|
- g.GET("/lists/forms", handleIndexPage)
|
|
|
- g.GET("/subscribers", handleIndexPage)
|
|
|
- g.GET("/subscribers/lists/:listID", handleIndexPage)
|
|
|
- g.GET("/subscribers/import", handleIndexPage)
|
|
|
- g.GET("/subscribers/bounces", handleIndexPage)
|
|
|
- g.GET("/campaigns", handleIndexPage)
|
|
|
- g.GET("/campaigns/new", handleIndexPage)
|
|
|
- g.GET("/campaigns/media", handleIndexPage)
|
|
|
- g.GET("/campaigns/templates", handleIndexPage)
|
|
|
- g.GET("/campaigns/:campignID", handleIndexPage)
|
|
|
- g.GET("/settings", handleIndexPage)
|
|
|
- g.GET("/settings/logs", handleIndexPage)
|
|
|
-
|
|
|
if app.constants.BounceWebhooksEnabled {
|
|
|
// Private authenticated bounce endpoint.
|
|
|
g.POST("/webhooks/bounce", handleBounceWebhook)
|
|
@@ -171,17 +165,16 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
|
|
|
e.GET("/health", handleHealthCheck)
|
|
|
}
|
|
|
|
|
|
-// handleIndex is the root handler that renders the Javascript frontend.
|
|
|
-func handleIndexPage(c echo.Context) error {
|
|
|
+// handleAdminPage is the root handler that renders the Javascript admin frontend.
|
|
|
+func handleAdminPage(c echo.Context) error {
|
|
|
app := c.Get("app").(*App)
|
|
|
|
|
|
- b, err := app.fs.Read("/frontend/index.html")
|
|
|
+ b, err := app.fs.Read(path.Join(adminRoot, "/index.html"))
|
|
|
if err != nil {
|
|
|
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
|
|
}
|
|
|
|
|
|
- c.Response().Header().Set("Content-Type", "text/html")
|
|
|
- return c.String(http.StatusOK, string(b))
|
|
|
+ return c.HTMLBlob(http.StatusOK, b)
|
|
|
}
|
|
|
|
|
|
// handleHealthCheck is a healthcheck endpoint that returns a 200 response.
|