@@ -85,7 +85,7 @@
{{error}}
-
@@ -135,8 +135,15 @@
this.setup.domain = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":"+window.location.port : "")
},
methods: {
- async saveSetup(e) {
- e.preventDefault();
+ canSubmit() {
+ if (this.db_connection !== 'sqlite') {
+ if (!this.db_host || !this.db_port || !this.db_user || !this.db_password || !this.db_database) {
+ return false
+ }
+ }
+ return !(!this.project || !this.description || !this.domain || !this.username || !this.password || !this.confirm_password);
+ },
+ async saveSetup() {
this.loading = true
const s = this.setup
if (s.password !== s.confirm_password) {
diff --git a/handlers/index.go b/handlers/index.go
index 4bbc585d..e0a5d6f2 100644
--- a/handlers/index.go
+++ b/handlers/index.go
@@ -21,7 +21,7 @@ import (
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
- if core.CoreApp.Config == nil {
+ if !core.CoreApp.Setup {
http.Redirect(w, r, "/setup", http.StatusSeeOther)
return
}
diff --git a/handlers/messages.go b/handlers/messages.go
index 63d90236..4bea0ae4 100644
--- a/handlers/messages.go
+++ b/handlers/messages.go
@@ -25,26 +25,6 @@ import (
"net/http"
)
-func messagesHandler(w http.ResponseWriter, r *http.Request) {
- if !IsUser(r) {
- http.Redirect(w, r, basePath, http.StatusSeeOther)
- return
- }
- messages, _ := core.SelectMessages()
- ExecuteResponse(w, r, "messages.gohtml", messages, nil)
-}
-
-func viewMessageHandler(w http.ResponseWriter, r *http.Request) {
- vars := mux.Vars(r)
- id := utils.ToInt(vars["id"])
- message, err := core.SelectMessage(id)
- if err != nil {
- w.WriteHeader(http.StatusNotFound)
- return
- }
- ExecuteResponse(w, r, "message.gohtml", message, nil)
-}
-
func apiAllMessagesHandler(r *http.Request) interface{} {
messages, err := core.SelectMessages()
if err != nil {
diff --git a/handlers/middleware.go b/handlers/middleware.go
index 62898529..8557ce18 100644
--- a/handlers/middleware.go
+++ b/handlers/middleware.go
@@ -4,6 +4,7 @@ import (
"compress/gzip"
"crypto/subtle"
"encoding/json"
+ "errors"
"fmt"
"github.com/hunterlong/statping/core"
"github.com/hunterlong/statping/utils"
@@ -60,6 +61,17 @@ func basicAuthHandler(next http.Handler) http.Handler {
})
}
+// apiMiddleware will confirm if Core has been setup
+func apiMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if !core.CoreApp.Setup {
+ sendErrorJson(errors.New("statping has not been setup"), w, r)
+ return
+ }
+ next.ServeHTTP(w, r)
+ })
+}
+
// sendLog is a http middleware that will log the duration of request and other useful fields
func sendLog(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
diff --git a/handlers/routes.go b/handlers/routes.go
index 187889e2..1d738423 100644
--- a/handlers/routes.go
+++ b/handlers/routes.go
@@ -30,6 +30,11 @@ var (
log = utils.Log.WithField("type", "handlers")
)
+
+func staticAssets(src string) http.Handler {
+ return http.StripPrefix(basePath+src+"/", http.FileServer(http.Dir(utils.Directory+"/assets/"+src)))
+}
+
// Router returns all of the routes used in Statping.
// Server will use static assets if the 'assets' directory is found in the root directory.
func Router() *mux.Router {
@@ -54,101 +59,108 @@ func Router() *mux.Router {
r.Use(sendLog)
if source.UsingAssets(dir) {
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
- r.PathPrefix("/css/").Handler(Gzip(http.StripPrefix(basePath+"css/", http.FileServer(http.Dir(dir+"/assets/css")))))
- r.PathPrefix("/font/").Handler(http.StripPrefix(basePath+"font/", http.FileServer(http.Dir(dir+"/assets/font"))))
- r.PathPrefix("/js/").Handler(Gzip(http.StripPrefix(basePath+"js/", http.FileServer(http.Dir(dir+"/assets/js")))))
+
+ r.PathPrefix("/css/").Handler(Gzip(staticAssets("css")))
+ r.PathPrefix("/font/").Handler(staticAssets("font"))
+ r.PathPrefix("/js/").Handler(Gzip(staticAssets("css")))
r.PathPrefix("/robots.txt").Handler(http.StripPrefix(basePath, indexHandler))
r.PathPrefix("/favicon.ico").Handler(http.StripPrefix(basePath, indexHandler))
r.PathPrefix("/banner.png").Handler(http.StripPrefix(basePath, indexHandler))
} else {
- //r.PathPrefix("/").Handler(http.StripPrefix(basePath+"/", http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/css/").Handler(Gzip(http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/scss/").Handler(Gzip(http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/font/").Handler(http.FileServer(source.TmplBox.HTTPBox()))
- r.PathPrefix("/js/").Handler(Gzip(http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/robots.txt").Handler(http.StripPrefix(basePath, http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/favicon.ico").Handler(http.StripPrefix(basePath, http.FileServer(source.TmplBox.HTTPBox())))
- r.PathPrefix("/banner.png").Handler(http.StripPrefix(basePath, http.FileServer(source.TmplBox.HTTPBox())))
+ tmplFileSrv := http.FileServer(source.TmplBox.HTTPBox())
+ tmplBoxHandler := http.StripPrefix(basePath, tmplFileSrv)
+
+ r.PathPrefix("/css/").Handler(Gzip(tmplFileSrv))
+ r.PathPrefix("/scss/").Handler(Gzip(tmplFileSrv))
+ r.PathPrefix("/font/").Handler(tmplFileSrv)
+ r.PathPrefix("/js/").Handler(Gzip(tmplFileSrv))
+ r.PathPrefix("/robots.txt").Handler(tmplBoxHandler)
+ r.PathPrefix("/favicon.ico").Handler(tmplBoxHandler)
+ r.PathPrefix("/banner.png").Handler(tmplBoxHandler)
}
+ api := r.NewRoute().Subrouter()
+ //api := mux.NewRouter().StrictSlash(true)
+ api.Use(apiMiddleware)
+
// API Routes
r.Handle("/api", scoped(apiIndexHandler))
- r.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST")
+ api.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST")
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
- r.Handle("/api/logout", http.HandlerFunc(logoutHandler))
- r.Handle("/api/renew", authenticated(apiRenewHandler, false))
- r.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
- r.Handle("/api/clear_cache", authenticated(apiClearCacheHandler, false))
- r.Handle("/api/core", authenticated(apiCoreHandler, false)).Methods("POST")
- r.Handle("/api/logs", authenticated(logsHandler, false)).Methods("GET")
- r.Handle("/api/logs/last", authenticated(logsLineHandler, false)).Methods("GET")
+ api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
+ api.Handle("/api/renew", authenticated(apiRenewHandler, false))
+ api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
+ api.Handle("/api/clear_cache", authenticated(apiClearCacheHandler, false))
+ api.Handle("/api/core", authenticated(apiCoreHandler, false)).Methods("POST")
+ api.Handle("/api/logs", authenticated(logsHandler, false)).Methods("GET")
+ api.Handle("/api/logs/last", authenticated(logsLineHandler, false)).Methods("GET")
// API SCSS and ASSETS Routes
- r.Handle("/api/theme", authenticated(apiThemeHandler, false)).Methods("GET")
- r.Handle("/api/theme", authenticated(apiThemeSaveHandler, false)).Methods("POST")
- r.Handle("/api/theme/create", authenticated(apiThemeCreateHandler, false)).Methods("GET")
- r.Handle("/api/theme", authenticated(apiThemeRemoveHandler, false)).Methods("DELETE")
+ api.Handle("/api/theme", authenticated(apiThemeHandler, false)).Methods("GET")
+ api.Handle("/api/theme", authenticated(apiThemeSaveHandler, false)).Methods("POST")
+ api.Handle("/api/theme/create", authenticated(apiThemeCreateHandler, false)).Methods("GET")
+ api.Handle("/api/theme", authenticated(apiThemeRemoveHandler, false)).Methods("DELETE")
// API INTEGRATIONS Routes
- r.Handle("/api/integrations", authenticated(apiAllIntegrationsHandler, false)).Methods("GET")
- r.Handle("/api/integrations/{name}", authenticated(apiIntegrationViewHandler, false)).Methods("GET")
- r.Handle("/api/integrations/{name}", authenticated(apiIntegrationHandler, false)).Methods("POST")
+ api.Handle("/api/integrations", authenticated(apiAllIntegrationsHandler, false)).Methods("GET")
+ api.Handle("/api/integrations/{name}", authenticated(apiIntegrationViewHandler, false)).Methods("GET")
+ api.Handle("/api/integrations/{name}", authenticated(apiIntegrationHandler, false)).Methods("POST")
// API GROUPS Routes
- r.Handle("/api/groups", scoped(apiAllGroupHandler)).Methods("GET")
- r.Handle("/api/groups", authenticated(apiCreateGroupHandler, false)).Methods("POST")
- r.Handle("/api/groups/{id}", readOnly(apiGroupHandler, false)).Methods("GET")
- r.Handle("/api/groups/{id}", authenticated(apiGroupUpdateHandler, false)).Methods("POST")
- r.Handle("/api/groups/{id}", authenticated(apiGroupDeleteHandler, false)).Methods("DELETE")
- r.Handle("/api/reorder/groups", authenticated(apiGroupReorderHandler, false)).Methods("POST")
+ api.Handle("/api/groups", scoped(apiAllGroupHandler)).Methods("GET")
+ api.Handle("/api/groups", authenticated(apiCreateGroupHandler, false)).Methods("POST")
+ api.Handle("/api/groups/{id}", readOnly(apiGroupHandler, false)).Methods("GET")
+ api.Handle("/api/groups/{id}", authenticated(apiGroupUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/groups/{id}", authenticated(apiGroupDeleteHandler, false)).Methods("DELETE")
+ api.Handle("/api/reorder/groups", authenticated(apiGroupReorderHandler, false)).Methods("POST")
// API SERVICE Routes
- r.Handle("/api/services", scoped(apiAllServicesHandler)).Methods("GET")
- r.Handle("/api/services", authenticated(apiCreateServiceHandler, false)).Methods("POST")
- r.Handle("/api/services_test", authenticated(apiTestServiceHandler, false)).Methods("POST")
- r.Handle("/api/services/{id}", scoped(apiServiceHandler)).Methods("GET")
- r.Handle("/api/reorder/services", authenticated(reorderServiceHandler, false)).Methods("POST")
- r.Handle("/api/services/{id}/running", authenticated(apiServiceRunningHandler, false)).Methods("POST")
- r.Handle("/api/services/{id}/data", cached("30s", "application/json", apiServiceDataHandler)).Methods("GET")
- r.Handle("/api/services/{id}/ping", cached("30s", "application/json", apiServicePingDataHandler)).Methods("GET")
- r.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", apiServiceHeatmapHandler)).Methods("GET")
- r.Handle("/api/services/{id}", authenticated(apiServiceUpdateHandler, false)).Methods("POST")
- r.Handle("/api/services/{id}", authenticated(apiServiceDeleteHandler, false)).Methods("DELETE")
- r.Handle("/api/services/{id}/failures", scoped(apiServiceFailuresHandler)).Methods("GET")
- r.Handle("/api/services/{id}/failures", authenticated(servicesDeleteFailuresHandler, false)).Methods("DELETE")
- r.Handle("/api/services/{id}/hits", scoped(apiServiceHitsHandler)).Methods("GET")
+ api.Handle("/api/services", scoped(apiAllServicesHandler)).Methods("GET")
+ api.Handle("/api/services", authenticated(apiCreateServiceHandler, false)).Methods("POST")
+ api.Handle("/api/services_test", authenticated(apiTestServiceHandler, false)).Methods("POST")
+ api.Handle("/api/services/{id}", scoped(apiServiceHandler)).Methods("GET")
+ api.Handle("/api/reorder/services", authenticated(reorderServiceHandler, false)).Methods("POST")
+ api.Handle("/api/services/{id}/running", authenticated(apiServiceRunningHandler, false)).Methods("POST")
+ api.Handle("/api/services/{id}/data", cached("30s", "application/json", apiServiceDataHandler)).Methods("GET")
+ api.Handle("/api/services/{id}/ping", cached("30s", "application/json", apiServicePingDataHandler)).Methods("GET")
+ api.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", apiServiceHeatmapHandler)).Methods("GET")
+ api.Handle("/api/services/{id}", authenticated(apiServiceUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/services/{id}", authenticated(apiServiceDeleteHandler, false)).Methods("DELETE")
+ api.Handle("/api/services/{id}/failures", scoped(apiServiceFailuresHandler)).Methods("GET")
+ api.Handle("/api/services/{id}/failures", authenticated(servicesDeleteFailuresHandler, false)).Methods("DELETE")
+ api.Handle("/api/services/{id}/hits", scoped(apiServiceHitsHandler)).Methods("GET")
// API INCIDENTS Routes
- r.Handle("/api/incidents", readOnly(apiAllIncidentsHandler, false)).Methods("GET")
- r.Handle("/api/incidents", authenticated(apiCreateIncidentHandler, false)).Methods("POST")
- r.Handle("/api/incidents/:id", authenticated(apiIncidentUpdateHandler, false)).Methods("POST")
- r.Handle("/api/incidents/:id", authenticated(apiDeleteIncidentHandler, false)).Methods("DELETE")
+ api.Handle("/api/incidents", readOnly(apiAllIncidentsHandler, false)).Methods("GET")
+ api.Handle("/api/incidents", authenticated(apiCreateIncidentHandler, false)).Methods("POST")
+ api.Handle("/api/incidents/:id", authenticated(apiIncidentUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/incidents/:id", authenticated(apiDeleteIncidentHandler, false)).Methods("DELETE")
// API USER Routes
- r.Handle("/api/users", authenticated(apiAllUsersHandler, false)).Methods("GET")
- r.Handle("/api/users", authenticated(apiCreateUsersHandler, false)).Methods("POST")
- r.Handle("/api/users/{id}", authenticated(apiUserHandler, false)).Methods("GET")
- r.Handle("/api/users/{id}", authenticated(apiUserUpdateHandler, false)).Methods("POST")
- r.Handle("/api/users/{id}", authenticated(apiUserDeleteHandler, false)).Methods("DELETE")
+ api.Handle("/api/users", authenticated(apiAllUsersHandler, false)).Methods("GET")
+ api.Handle("/api/users", authenticated(apiCreateUsersHandler, false)).Methods("POST")
+ api.Handle("/api/users/{id}", authenticated(apiUserHandler, false)).Methods("GET")
+ api.Handle("/api/users/{id}", authenticated(apiUserUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/users/{id}", authenticated(apiUserDeleteHandler, false)).Methods("DELETE")
// API NOTIFIER Routes
- r.Handle("/api/notifiers", authenticated(apiNotifiersHandler, false)).Methods("GET")
- r.Handle("/api/notifier/{notifier}", authenticated(apiNotifierGetHandler, false)).Methods("GET")
- r.Handle("/api/notifier/{notifier}", authenticated(apiNotifierUpdateHandler, false)).Methods("POST")
- r.Handle("/api/notifier/{method}/test", authenticated(testNotificationHandler, false)).Methods("POST")
+ api.Handle("/api/notifiers", authenticated(apiNotifiersHandler, false)).Methods("GET")
+ api.Handle("/api/notifier/{notifier}", authenticated(apiNotifierGetHandler, false)).Methods("GET")
+ api.Handle("/api/notifier/{notifier}", authenticated(apiNotifierUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/notifier/{method}/test", authenticated(testNotificationHandler, false)).Methods("POST")
// API MESSAGES Routes
- r.Handle("/api/messages", scoped(apiAllMessagesHandler)).Methods("GET")
- r.Handle("/api/messages", authenticated(apiMessageCreateHandler, false)).Methods("POST")
- r.Handle("/api/messages/{id}", readOnly(apiMessageGetHandler, false)).Methods("GET")
- r.Handle("/api/messages/{id}", authenticated(apiMessageUpdateHandler, false)).Methods("POST")
- r.Handle("/api/messages/{id}", authenticated(apiMessageDeleteHandler, false)).Methods("DELETE")
+ api.Handle("/api/messages", scoped(apiAllMessagesHandler)).Methods("GET")
+ api.Handle("/api/messages", authenticated(apiMessageCreateHandler, false)).Methods("POST")
+ api.Handle("/api/messages/{id}", readOnly(apiMessageGetHandler, false)).Methods("GET")
+ api.Handle("/api/messages/{id}", authenticated(apiMessageUpdateHandler, false)).Methods("POST")
+ api.Handle("/api/messages/{id}", authenticated(apiMessageDeleteHandler, false)).Methods("DELETE")
// API CHECKIN Routes
- r.Handle("/api/checkins", authenticated(apiAllCheckinsHandler, false)).Methods("GET")
- r.Handle("/api/checkin/{api}", authenticated(apiCheckinHandler, false)).Methods("GET")
- r.Handle("/api/checkin", authenticated(checkinCreateHandler, false)).Methods("POST")
- r.Handle("/api/checkin/{api}", authenticated(checkinDeleteHandler, false)).Methods("DELETE")
+ api.Handle("/api/checkins", authenticated(apiAllCheckinsHandler, false)).Methods("GET")
+ api.Handle("/api/checkin/{api}", authenticated(apiCheckinHandler, false)).Methods("GET")
+ api.Handle("/api/checkin", authenticated(checkinCreateHandler, false)).Methods("POST")
+ api.Handle("/api/checkin/{api}", authenticated(checkinDeleteHandler, false)).Methods("DELETE")
r.Handle("/checkin/{api}", http.HandlerFunc(checkinHitHandler))
//r.PathPrefix("/").Handler(http.HandlerFunc(indexHandler))
diff --git a/handlers/setup.go b/handlers/setup.go
index 8f8f1ab0..362f1138 100644
--- a/handlers/setup.go
+++ b/handlers/setup.go
@@ -21,24 +21,10 @@ import (
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
"net/http"
- "os"
"strconv"
"time"
)
-func setupHandler(w http.ResponseWriter, r *http.Request) {
- if core.CoreApp.Services != nil {
- http.Redirect(w, r, basePath, http.StatusSeeOther)
- return
- }
- var data interface{}
- if os.Getenv("DB_CONN") != "" {
- data, _ = core.LoadUsingEnv()
- }
- w.WriteHeader(http.StatusOK)
- ExecuteResponse(w, r, "setup.gohtml", data, nil)
-}
-
func processSetupHandler(w http.ResponseWriter, r *http.Request) {
var err error
if core.CoreApp.Setup {