mirror of https://github.com/statping/statping
updates
parent
7d927d2b24
commit
c812715bb8
|
@ -96,7 +96,6 @@ func main() {
|
||||||
configs, err := core.LoadConfigFile(utils.Directory)
|
configs, err := core.LoadConfigFile(utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
core.SetupMode = true
|
|
||||||
writeAble, err := utils.DirWritable(utils.Directory)
|
writeAble, err := utils.DirWritable(utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
|
@ -104,6 +103,7 @@ func main() {
|
||||||
if !writeAble {
|
if !writeAble {
|
||||||
log.Fatalf("Statping does not have write permissions at: %v\nYou can change this directory by setting the STATPING_DIR environment variable to a dedicated path before starting.", utils.Directory)
|
log.Fatalf("Statping does not have write permissions at: %v\nYou can change this directory by setting the STATPING_DIR environment variable to a dedicated path before starting.", utils.Directory)
|
||||||
}
|
}
|
||||||
|
core.CoreApp.Setup = false
|
||||||
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ func mainProcess() error {
|
||||||
}
|
}
|
||||||
core.CoreApp.MigrateDatabase()
|
core.CoreApp.MigrateDatabase()
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
if !core.SetupMode {
|
if !core.CoreApp.Setup {
|
||||||
plugin.LoadPlugins()
|
plugin.LoadPlugins()
|
||||||
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
|
|
|
@ -40,6 +40,7 @@ func LoadConfigFile(directory string) (*types.DbConfig, error) {
|
||||||
log.Debugln("attempting to read config file at: " + directory + "/config.yml")
|
log.Debugln("attempting to read config file at: " + directory + "/config.yml")
|
||||||
file, err := ioutil.ReadFile(directory + "/config.yml")
|
file, err := ioutil.ReadFile(directory + "/config.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
CoreApp.Setup = false
|
||||||
return nil, errors.New("config.yml file not found at " + directory + "/config.yml - starting in setup mode")
|
return nil, errors.New("config.yml file not found at " + directory + "/config.yml - starting in setup mode")
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal(file, &configs)
|
err = yaml.Unmarshal(file, &configs)
|
||||||
|
|
|
@ -38,7 +38,6 @@ type Core struct {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
CoreApp *Core // CoreApp is a global variable that contains many elements
|
CoreApp *Core // CoreApp is a global variable that contains many elements
|
||||||
SetupMode bool // SetupMode will be true if Statping does not have a database connection
|
|
||||||
VERSION string // VERSION is set on build automatically by setting a -ldflag
|
VERSION string // VERSION is set on build automatically by setting a -ldflag
|
||||||
log = utils.Log.WithField("type", "core")
|
log = utils.Log.WithField("type", "core")
|
||||||
)
|
)
|
||||||
|
@ -71,7 +70,7 @@ func InitApp() {
|
||||||
CoreApp.Notifications = notifier.AllCommunications
|
CoreApp.Notifications = notifier.AllCommunications
|
||||||
CoreApp.Integrations = integrations.Integrations
|
CoreApp.Integrations = integrations.Integrations
|
||||||
go DatabaseMaintence()
|
go DatabaseMaintence()
|
||||||
SetupMode = false
|
CoreApp.Setup = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertNotifierDB inject the Statping database instance to the Notifier package
|
// InsertNotifierDB inject the Statping database instance to the Notifier package
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app" v-if="loaded">
|
<div id="app" v-if="loaded">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
<Footer version="DEV" />
|
<Footer version="DEV" v-if="$route.path !== '/setup'"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Api from './components/API';
|
|
||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -19,40 +18,18 @@
|
||||||
loaded: false
|
loaded: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created () {
|
async mounted() {
|
||||||
await this.setAllObjects()
|
if (this.$route.path !== '/setup') {
|
||||||
|
const tk = JSON.parse(localStorage.getItem("statping_user"))
|
||||||
|
if (!this.$store.getters.hasPublicData) {
|
||||||
|
await this.$store.dispatch('loadAdmin')
|
||||||
|
}
|
||||||
|
}
|
||||||
this.loaded = true
|
this.loaded = true
|
||||||
this.$store.commit('setHasPublicData', true)
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async setAllObjects () {
|
async setAllObjects () {
|
||||||
await this.setCore()
|
|
||||||
await this.setServices()
|
|
||||||
await this.setGroups()
|
|
||||||
await this.setMessages()
|
|
||||||
await this.setToken()
|
|
||||||
this.$store.commit('setHasPublicData', true)
|
|
||||||
this.loaded = true
|
this.loaded = true
|
||||||
},
|
|
||||||
async setCore () {
|
|
||||||
const core = await Api.core()
|
|
||||||
this.$store.commit('setCore', core)
|
|
||||||
},
|
|
||||||
async setToken () {
|
|
||||||
const token = await Api.token()
|
|
||||||
this.$store.commit('setToken', token)
|
|
||||||
},
|
|
||||||
async setServices () {
|
|
||||||
const services = await Api.services()
|
|
||||||
this.$store.commit('setServices', services)
|
|
||||||
},
|
|
||||||
async setGroups () {
|
|
||||||
const groups = await Api.groups()
|
|
||||||
this.$store.commit('setGroups', groups)
|
|
||||||
},
|
|
||||||
async setMessages () {
|
|
||||||
const messages = await Api.messages()
|
|
||||||
this.$store.commit('setMessages', messages)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ HTML,BODY {
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 190px;
|
height: 200px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ class Api {
|
||||||
return axios.post('/api/core', obj).then(response => (response.data))
|
return axios.post('/api/core', obj).then(response => (response.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setup_save (data) {
|
||||||
|
return axios.post('/api/setup', qs.stringify(data)).then(response => (response.data))
|
||||||
|
}
|
||||||
|
|
||||||
async services () {
|
async services () {
|
||||||
return axios.get('/api/services').then(response => (response.data))
|
return axios.get('/api/services').then(response => (response.data))
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="(service, index) in services" v-bind:key="index">
|
<div v-for="(service, index) in $store.getters.services" v-bind:key="index">
|
||||||
<ServiceInfo :service=service />
|
<ServiceInfo :service=service />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,7 +32,6 @@
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
services: this.$store.getters.servicesInOrder()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -54,9 +54,6 @@
|
||||||
return {
|
return {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
service (id) {
|
service (id) {
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
<th scope="col"></th>
|
<th scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<draggable tag="tbody" :list="services" :key="services.length" class="sortable" handle=".drag_icon">
|
<draggable tag="tbody" :list="$store.getters.servicesInOrder" :key="this.$store.getters.servicesInOrder.length" class="sortable" handle=".drag_icon">
|
||||||
<tr v-for="(service, index) in services" :key="index">
|
<tr v-for="(service, index) in $store.getters.services" :key="index">
|
||||||
<td>
|
<td>
|
||||||
<span class="drag_icon d-none d-md-inline">
|
<span class="drag_icon d-none d-md-inline">
|
||||||
<font-awesome-icon icon="bars" />
|
<font-awesome-icon icon="bars" />
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<draggable tag="tbody" v-model="groupsList" class="sortable_groups" handle=".drag_icon">
|
<draggable tag="tbody" v-model="groupsList" class="sortable_groups" handle=".drag_icon">
|
||||||
<tr v-for="(group, index) in $store.getters.cleanGroups()" v-bind:key="index">
|
<tr v-for="(group, index) in $store.getters.groupsCleaned" v-bind:key="index">
|
||||||
<td><span class="drag_icon d-none d-md-inline"><font-awesome-icon icon="bars" /></span> {{group.name}}</td>
|
<td><span class="drag_icon d-none d-md-inline"><font-awesome-icon icon="bars" /></span> {{group.name}}</td>
|
||||||
<td>{{$store.getters.servicesInGroup(group.id).length}}</td>
|
<td>{{$store.getters.servicesInGroup(group.id).length}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -112,14 +112,9 @@
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
services: []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
|
||||||
const services = await Api.services()
|
|
||||||
this.$store.commit('setServices', services)
|
|
||||||
this.services = this.$store.getters.servicesInOrder()
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
servicesList: {
|
servicesList: {
|
||||||
get() {
|
get() {
|
||||||
|
|
|
@ -44,10 +44,6 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
|
||||||
const users = await Api.users()
|
|
||||||
this.$store.commit('setUsers', users)
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async deleteUser(u) {
|
async deleteUser(u) {
|
||||||
let c = confirm(`Are you sure you want to delete user '${u.username}'?`)
|
let c = confirm(`Are you sure you want to delete user '${u.username}'?`)
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
<template>
|
||||||
|
<div class="container col-md-7 col-sm-12 mt-2 sm-container">
|
||||||
|
<div class="col-12 col-md-8 offset-md-2 mb-4">
|
||||||
|
<img class="col-12 mt-5 mt-md-0" src="/public/banner.png">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
|
||||||
|
<form @submit="">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Database Connection</label>
|
||||||
|
<select v-model="setup.db_connection" class="form-control">
|
||||||
|
<option value="sqlite">Sqlite</option>
|
||||||
|
<option value="postgres">Postgres</option>
|
||||||
|
<option value="mysql">MySQL</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div v-if="setup.db_connection !== 'sqlite'" class="form-group" id="db_host">
|
||||||
|
<label>Host</label>
|
||||||
|
<input v-model="setup.db_host" type="text" class="form-control" placeholder="localhost">
|
||||||
|
</div>
|
||||||
|
<div v-if="setup.db_connection !== 'sqlite'" class="form-group" id="db_port">
|
||||||
|
<label>Database Port</label>
|
||||||
|
<input v-model="setup.db_port" type="text" class="form-control" placeholder="localhost">
|
||||||
|
</div>
|
||||||
|
<div v-if="setup.db_connection !== 'sqlite'" class="form-group" id="db_user">
|
||||||
|
<label>Username</label>
|
||||||
|
<input v-model="setup.db_user" type="text" class="form-control" placeholder="root">
|
||||||
|
</div>
|
||||||
|
<div v-if="setup.db_connection !== 'sqlite'" class="form-group" id="db_password">
|
||||||
|
<label for="db_password">Password</label>
|
||||||
|
<input v-model="setup.db_password" type="password" class="form-control" placeholder="password123">
|
||||||
|
</div>
|
||||||
|
<div v-if="setup.db_connection !== 'sqlite'" class="form-group" id="db_database">
|
||||||
|
<label for="db_database">Database</label>
|
||||||
|
<input v-model="setup.db_database" type="text" class="form-control" placeholder="Database name">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Project Name</label>
|
||||||
|
<input v-model="setup.project" type="text" class="form-control" placeholder="Great Uptime" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Project Description</label>
|
||||||
|
<input v-model="setup.description" type="text" class="form-control" placeholder="Great Uptime">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="domain_input">Domain URL</label>
|
||||||
|
<input v-model="setup.domain" type="text" class="form-control" id="domain_input" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Admin Username</label>
|
||||||
|
<input v-model="setup.username" type="text" class="form-control" placeholder="admin" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Admin Password</label>
|
||||||
|
<input v-model="setup.password" type="password" class="form-control" placeholder="password" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Confirm Admin Password</label>
|
||||||
|
<input v-model="setup.confirm_password" type="password" class="form-control" placeholder="password" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<span class="switch">
|
||||||
|
<input v-model="setup.sample_data" type="checkbox" class="switch" id="switch-normal">
|
||||||
|
<label for="switch-normal">Load Sample Data</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="error" class="col-12 alert alert-danger">
|
||||||
|
{{error}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button @click="saveSetup" v-bind:disabled="loading" type="submit" class="btn btn-primary btn-block" :class="{'btn-primary': !loading, 'btn-default': loading}">
|
||||||
|
{{loading ? "Loading..." : "Save Settings"}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Api from "../components/API";
|
||||||
|
import Index from "../pages/Index";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Setup',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
error: null,
|
||||||
|
loading: false,
|
||||||
|
setup: {
|
||||||
|
db_connection: "sqlite",
|
||||||
|
db_host: "",
|
||||||
|
db_port: "",
|
||||||
|
db_user: "",
|
||||||
|
db_password: "",
|
||||||
|
db_database: "",
|
||||||
|
project: "",
|
||||||
|
description: "",
|
||||||
|
domain: "",
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
confirm_password: "",
|
||||||
|
sample_data: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
const core = await Api.core()
|
||||||
|
if (core.setup) {
|
||||||
|
this.$router.push(Index)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setup.domain = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":"+window.location.port : "")
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async saveSetup(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.loading = true
|
||||||
|
const s = this.setup
|
||||||
|
if (s.password !== s.confirm_password) {
|
||||||
|
alert('Passwords do not match!')
|
||||||
|
this.loading = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const resp = await Api.setup_save(s)
|
||||||
|
if (resp.status === 'error') {
|
||||||
|
this.error = resp.error
|
||||||
|
this.loading = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await this.completeAuth()
|
||||||
|
this.loading = false
|
||||||
|
this.$router.push('')
|
||||||
|
},
|
||||||
|
async completeAuth() {
|
||||||
|
const auth = await Api.login(this.setup.username, this.setup.password)
|
||||||
|
this.auth = Api.saveToken(this.setup.username, auth.token)
|
||||||
|
|
||||||
|
await this.$store.dispatch('loadAdmin')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -6,31 +6,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Login from "./Login";
|
|
||||||
import TopNav from "../components/Dashboard/TopNav";
|
import TopNav from "../components/Dashboard/TopNav";
|
||||||
import Api from "../components/API";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
components: {
|
components: {
|
||||||
TopNav,
|
TopNav,
|
||||||
Login,
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
authenticated: false
|
authenticated: false
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.$store.getters.token !== null) {
|
|
||||||
this.authenticated = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async setServices () {
|
|
||||||
const services = await Api.services()
|
|
||||||
this.$store.commit('setServices', services)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
this.error = true
|
this.error = true
|
||||||
} else if (auth.token) {
|
} else if (auth.token) {
|
||||||
this.auth = Api.saveToken(this.username, auth.token)
|
this.auth = Api.saveToken(this.username, auth.token)
|
||||||
this.$store.commit('setToken', auth)
|
await this.$store.dispatch('loadRequired')
|
||||||
this.$router.push('/dashboard')
|
this.$router.push('/dashboard')
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
|
|
||||||
<h2 class="mt-5">Additional Settings</h2>
|
<h2 class="mt-5">Additional Settings</h2>
|
||||||
<div class="row">
|
<div v-if="core.domain !== ''" class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="row align-content-center">
|
<div class="row align-content-center">
|
||||||
<img class="rounded text-center" width="300" height="300" :src="qrcode">
|
<img class="rounded text-center" width="300" height="300" :src="qrcode">
|
||||||
|
@ -265,7 +265,8 @@
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
tab: "v-pills-home-tab",
|
tab: "v-pills-home-tab",
|
||||||
qrcode: ""
|
qrcode: "",
|
||||||
|
core: this.$store.getters.core
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
|
|
|
@ -9,13 +9,18 @@ import Settings from "./pages/Settings";
|
||||||
import Login from "./pages/Login";
|
import Login from "./pages/Login";
|
||||||
import Service from "./pages/Service";
|
import Service from "./pages/Service";
|
||||||
import VueRouter from "vue-router";
|
import VueRouter from "vue-router";
|
||||||
import Api from "./components/API";
|
import Setup from "./forms/Setup";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/setup',
|
||||||
|
name: 'Setup',
|
||||||
|
component: Setup
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'Index',
|
name: 'Index',
|
||||||
component: Index
|
component: Index,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import Api from "./components/API"
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
@ -37,6 +38,9 @@ export default new Vuex.Store({
|
||||||
users: state => state.users,
|
users: state => state.users,
|
||||||
notifiers: state => state.notifiers,
|
notifiers: state => state.notifiers,
|
||||||
|
|
||||||
|
servicesInOrder: state => state.services,
|
||||||
|
groupsCleaned: state => state.groups.filter(g => g.name !== ''),
|
||||||
|
|
||||||
serviceById: (state) => (id) => {
|
serviceById: (state) => (id) => {
|
||||||
return state.services.find(s => s.id === id)
|
return state.services.find(s => s.id === id)
|
||||||
},
|
},
|
||||||
|
@ -46,9 +50,6 @@ export default new Vuex.Store({
|
||||||
servicesInGroup: (state) => (id) => {
|
servicesInGroup: (state) => (id) => {
|
||||||
return state.services.filter(s => s.group_id === id)
|
return state.services.filter(s => s.group_id === id)
|
||||||
},
|
},
|
||||||
servicesInOrder: (state) => () => {
|
|
||||||
return state.services
|
|
||||||
},
|
|
||||||
onlineServices: (state) => (online) => {
|
onlineServices: (state) => (online) => {
|
||||||
return state.services.filter(s => s.online === online)
|
return state.services.filter(s => s.online === online)
|
||||||
},
|
},
|
||||||
|
@ -79,7 +80,7 @@ export default new Vuex.Store({
|
||||||
state.token = token
|
state.token = token
|
||||||
},
|
},
|
||||||
setServices(state, services) {
|
setServices(state, services) {
|
||||||
state.services = services.sort((a, b) => a.order_id - b.order_id)
|
state.services = services
|
||||||
},
|
},
|
||||||
setGroups(state, groups) {
|
setGroups(state, groups) {
|
||||||
state.groups = groups
|
state.groups = groups
|
||||||
|
@ -95,6 +96,23 @@ export default new Vuex.Store({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
async loadRequired(context) {
|
||||||
|
const core = await Api.core()
|
||||||
|
context.commit("setCore", core);
|
||||||
|
const services = await Api.services()
|
||||||
|
context.commit("setServices", services);
|
||||||
|
const groups = await Api.groups()
|
||||||
|
context.commit("setGroups", groups);
|
||||||
|
const messages = await Api.messages()
|
||||||
|
context.commit("setMessages", messages)
|
||||||
|
context.commit("setHasPublicData", true)
|
||||||
|
},
|
||||||
|
async loadAdmin(context) {
|
||||||
|
await context.dispatch('loadRequired')
|
||||||
|
const notifiers = await Api.notifiers()
|
||||||
|
context.commit("setNotifiers", notifiers);
|
||||||
|
const users = await Api.users()
|
||||||
|
context.commit("setUsers", users);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -18,9 +18,9 @@ require (
|
||||||
github.com/go-mail/mail v2.3.1+incompatible
|
github.com/go-mail/mail v2.3.1+incompatible
|
||||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||||
github.com/gorilla/mux v1.7.3
|
github.com/gorilla/mux v1.7.3
|
||||||
github.com/gorilla/sessions v1.2.0
|
|
||||||
github.com/gorilla/websocket v1.4.1 // indirect
|
github.com/gorilla/websocket v1.4.1 // indirect
|
||||||
github.com/hashicorp/golang-lru v0.5.3 // indirect
|
github.com/hashicorp/golang-lru v0.5.3 // indirect
|
||||||
|
github.com/hunterlong/scopr v0.0.0
|
||||||
github.com/jinzhu/gorm v1.9.11
|
github.com/jinzhu/gorm v1.9.11
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/lib/pq v1.2.0 // indirect
|
github.com/lib/pq v1.2.0 // indirect
|
||||||
|
@ -41,3 +41,5 @@ require (
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
gopkg.in/yaml.v2 v2.2.7 // indirect
|
gopkg.in/yaml.v2 v2.2.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/hunterlong/scopr v0.0.0 => ../scopr
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -85,10 +85,6 @@ github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
|
||||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
|
||||||
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
|
|
||||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
|
||||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
|
|
@ -103,7 +103,7 @@ func RunHTTPServer(ip string, port int) error {
|
||||||
|
|
||||||
// IsReadAuthenticated will allow Read Only authentication for some routes
|
// IsReadAuthenticated will allow Read Only authentication for some routes
|
||||||
func IsReadAuthenticated(r *http.Request) bool {
|
func IsReadAuthenticated(r *http.Request) bool {
|
||||||
if core.SetupMode {
|
if !core.CoreApp.Setup {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var token string
|
var token string
|
||||||
|
@ -132,7 +132,7 @@ func IsFullAuthenticated(r *http.Request) bool {
|
||||||
if core.CoreApp == nil {
|
if core.CoreApp == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if core.SetupMode {
|
if !core.CoreApp.Setup {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var token string
|
var token string
|
||||||
|
@ -185,7 +185,7 @@ func ScopeName(r *http.Request) string {
|
||||||
|
|
||||||
// IsAdmin returns true if the user session is an administrator
|
// IsAdmin returns true if the user session is an administrator
|
||||||
func IsAdmin(r *http.Request) bool {
|
func IsAdmin(r *http.Request) bool {
|
||||||
if core.SetupMode {
|
if !core.CoreApp.Setup {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if os.Getenv("GO_ENV") == "test" {
|
if os.Getenv("GO_ENV") == "test" {
|
||||||
|
@ -201,7 +201,7 @@ func IsAdmin(r *http.Request) bool {
|
||||||
|
|
||||||
// IsUser returns true if the user is registered
|
// IsUser returns true if the user is registered
|
||||||
func IsUser(r *http.Request) bool {
|
func IsUser(r *http.Request) bool {
|
||||||
if core.SetupMode {
|
if !core.CoreApp.Setup {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if os.Getenv("GO_ENV") == "test" {
|
if os.Getenv("GO_ENV") == "test" {
|
||||||
|
|
|
@ -16,11 +16,13 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/hunterlong/statping/core"
|
"github.com/hunterlong/statping/core"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,11 +41,15 @@ func setupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var err error
|
var err error
|
||||||
if !core.SetupMode {
|
if core.CoreApp.Setup {
|
||||||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
sendErrorJson(errors.New("Statping has already been setup"), w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = r.ParseForm(); err != nil {
|
||||||
|
log.Errorln(err)
|
||||||
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.ParseForm()
|
|
||||||
dbHost := r.PostForm.Get("db_host")
|
dbHost := r.PostForm.Get("db_host")
|
||||||
dbUser := r.PostForm.Get("db_user")
|
dbUser := r.PostForm.Get("db_user")
|
||||||
dbPass := r.PostForm.Get("db_password")
|
dbPass := r.PostForm.Get("db_password")
|
||||||
|
@ -56,7 +62,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
description := r.PostForm.Get("description")
|
description := r.PostForm.Get("description")
|
||||||
domain := r.PostForm.Get("domain")
|
domain := r.PostForm.Get("domain")
|
||||||
email := r.PostForm.Get("email")
|
email := r.PostForm.Get("email")
|
||||||
sample := r.PostForm.Get("sample_data") == "on"
|
sample, _ := strconv.ParseBool(r.PostForm.Get("sample_data"))
|
||||||
dir := utils.Directory
|
dir := utils.Directory
|
||||||
|
|
||||||
config := &types.DbConfig{
|
config := &types.DbConfig{
|
||||||
|
@ -80,34 +86,37 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
if _, err := core.CoreApp.SaveConfig(config); err != nil {
|
if _, err := core.CoreApp.SaveConfig(config); err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
config.Error = err
|
sendErrorJson(err, w, r)
|
||||||
setupResponseError(w, r, config)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = core.LoadConfigFile(dir); err != nil {
|
if _, err = core.LoadConfigFile(dir); err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
config.Error = err
|
sendErrorJson(err, w, r)
|
||||||
setupResponseError(w, r, config)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = core.CoreApp.Connect(false, dir); err != nil {
|
if err = core.CoreApp.Connect(false, dir); err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
core.DeleteConfig()
|
core.DeleteConfig()
|
||||||
config.Error = err
|
sendErrorJson(err, w, r)
|
||||||
setupResponseError(w, r, config)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
core.CoreApp.DropDatabase()
|
if err = core.CoreApp.DropDatabase(); err != nil {
|
||||||
core.CoreApp.CreateDatabase()
|
sendErrorJson(err, w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = core.CoreApp.CreateDatabase(); err != nil {
|
||||||
|
sendErrorJson(err, w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
core.CoreApp, err = core.CoreApp.InsertCore(config)
|
core.CoreApp, err = core.CoreApp.InsertCore(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
config.Error = err
|
sendErrorJson(err, w, r)
|
||||||
setupResponseError(w, r, config)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,13 +129,23 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
admin.Create()
|
admin.Create()
|
||||||
|
|
||||||
if sample {
|
if sample {
|
||||||
core.SampleData()
|
if err = core.SampleData(); err != nil {
|
||||||
|
sendErrorJson(err, w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
CacheStorage.Delete("/")
|
CacheStorage.Delete("/")
|
||||||
resetCookies()
|
resetCookies()
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
out := struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Config *types.DbConfig `json:"config"`
|
||||||
|
}{
|
||||||
|
"okokok",
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
returnJson(out, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupResponseError(w http.ResponseWriter, r *http.Request, a interface{}) {
|
func setupResponseError(w http.ResponseWriter, r *http.Request, a interface{}) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ type Core struct {
|
||||||
Footer NullString `gorm:"column:footer" json:"footer"`
|
Footer NullString `gorm:"column:footer" json:"footer"`
|
||||||
Domain string `gorm:"not null;column:domain" json:"domain"`
|
Domain string `gorm:"not null;column:domain" json:"domain"`
|
||||||
Version string `gorm:"column:version" json:"version"`
|
Version string `gorm:"column:version" json:"version"`
|
||||||
|
Setup bool `gorm:"-" json:"setup"`
|
||||||
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
|
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
|
||||||
UseCdn NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
UseCdn NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
||||||
UpdateNotify NullBool `gorm:"column:update_notify;default:true" json:"update_notify,omitempty"`
|
UpdateNotify NullBool `gorm:"column:update_notify;default:true" json:"update_notify,omitempty"`
|
||||||
|
|
Loading…
Reference in New Issue