pull/429/head
hunterlong 2020-02-17 09:45:33 -08:00
parent 0836c2c01b
commit f82abe9b49
8 changed files with 107 additions and 109 deletions

View File

@ -24,6 +24,9 @@
async created() {
await this.$store.dispatch('loadRequired')
this.loaded = true
if (!this.$store.getters.core.setup) {
this.$router.push('/setup')
}
window.console.log('finished loadRequired')
},
async mounted() {

View File

@ -6,7 +6,6 @@
{{service.online ? "ONLINE" : "OFFLINE"}}
</span>
</h5>
<transition name="fade">
<div v-if="loaded && service.online" class="row">
<div class="col-6">
<ServiceSparkLine :title="set1_name" subtitle="Last Day Latency" :series="set1"/>
@ -15,7 +14,6 @@
<ServiceSparkLine :title="set2_name" subtitle="Last 7 Days Latency" :series="set2"/>
</div>
</div>
</transition>
</div>
<span v-for="(failure, index) in failures" v-bind:key="index" class="alert alert-light">
Failed {{duration(current(), failure.created_at)}}<br>

View File

@ -6,7 +6,7 @@
<div class="col-12">
<form @submit="saveSetup">
<form @submit.prevent="saveSetup">
<div class="row">
<div class="col-6">
<div class="form-group">
@ -85,7 +85,7 @@
{{error}}
</div>
<button @click="saveSetup" v-bind:disabled="loading" type="submit" class="btn btn-primary btn-block" :class="{'btn-primary': !loading, 'btn-default': loading}">
<button @click.prevent="saveSetup" v-bind:disabled="canSubmit() && loading" type="submit" class="btn btn-primary btn-block" :class="{'btn-primary': !loading, 'btn-default': loading}">
{{loading ? "Loading..." : "Save Settings"}}
</button>
</div>
@ -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) {

View File

@ -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
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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))

View File

@ -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 {