mirror of https://github.com/statping/statping
parent
af989a2399
commit
4327569bac
|
@ -200,8 +200,8 @@ class Api {
|
||||||
return localStorage.removeItem(tokenKey)
|
return localStorage.removeItem(tokenKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
saveToken(username, token) {
|
saveToken(username, token, admin) {
|
||||||
const user = {username: username, token: token}
|
const user = {username: username, token: token, admin: admin}
|
||||||
localStorage.setItem(tokenKey, JSON.stringify(user));
|
localStorage.setItem(tokenKey, JSON.stringify(user));
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="d-none d-md-table-cell">{{niceDate(message.start_on)}}</td>
|
<td class="d-none d-md-table-cell">{{niceDate(message.start_on)}}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div v-if="$store.state.admin" class="btn-group">
|
||||||
<a @click.prevent="editMessage(message, edit)" href="#" class="btn btn-outline-secondary"><i class="fas fa-exclamation-triangle"></i> Edit</a>
|
<a @click.prevent="editMessage(message, edit)" href="#" class="btn btn-outline-secondary"><i class="fas fa-exclamation-triangle"></i> Edit</a>
|
||||||
<a @click.prevent="deleteMessage(message)" href="#" class="btn btn-danger"><font-awesome-icon icon="times" /></a>
|
<a @click.prevent="deleteMessage(message)" href="#" class="btn btn-danger"><font-awesome-icon icon="times" /></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormMessage :edit="editChange" :in_message="message"/>
|
<FormMessage v-if="$store.state.admin" :edit="editChange" :in_message="message"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card contain-card text-black-50 bg-white mb-4">
|
<div class="card contain-card text-black-50 bg-white mb-4">
|
||||||
<div class="card-header">Services
|
<div class="card-header">Services
|
||||||
<router-link to="/dashboard/create_service" class="btn btn-sm btn-outline-success float-right">
|
<router-link v-if="$store.state.admin" to="/dashboard/create_service" class="btn btn-sm btn-outline-success float-right">
|
||||||
<font-awesome-icon icon="plus"/> Create
|
<font-awesome-icon icon="plus"/> Create
|
||||||
</router-link></div>
|
</router-link></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<span v-if="!group.public" class="badge badge-secondary">PRIVATE</span>
|
<span v-if="!group.public" class="badge badge-secondary">PRIVATE</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div v-if="$store.state.admin" class="btn-group">
|
||||||
<a @click.prevent="editGroup(group, edit)" href="#" class="btn btn-outline-secondary"><font-awesome-icon icon="chart-area" /> Edit</a>
|
<a @click.prevent="editGroup(group, edit)" href="#" class="btn btn-outline-secondary"><font-awesome-icon icon="chart-area" /> Edit</a>
|
||||||
<a @click.prevent="deleteGroup(group)" href="#" class="btn btn-danger">
|
<a @click.prevent="deleteGroup(group)" href="#" class="btn btn-danger">
|
||||||
<font-awesome-icon icon="times" />
|
<font-awesome-icon icon="times" />
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<FormGroup :edit="editChange" :in_group="group"/>
|
<FormGroup v-if="$store.state.admin" :edit="editChange" :in_group="group"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormUser :edit="editChange" :in_user="user"/>
|
<FormUser v-if="$store.state.admin" :edit="editChange" :in_user="user"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
<draggable tag="tbody" v-model="servicesList" handle=".drag_icon">
|
<draggable tag="tbody" v-model="servicesList" handle=".drag_icon">
|
||||||
<tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id">
|
<tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id">
|
||||||
<td>
|
<td>
|
||||||
<span class="drag_icon d-none d-md-inline">
|
<span v-if="$store.state.admin" class="drag_icon d-none d-md-inline">
|
||||||
<font-awesome-icon icon="bars" class="mr-3"/>
|
<font-awesome-icon icon="bars" class="mr-3"/>
|
||||||
</span> {{service.name}}
|
</span> {{service.name}}
|
||||||
</td>
|
</td>
|
||||||
<td class="d-none d-md-table-cell">
|
<td v-if="$store.state.admin" class="d-none d-md-table-cell">
|
||||||
<ToggleSwitch v-if="service.online" :service="service"/>
|
<ToggleSwitch v-if="service.online" :service="service"/>
|
||||||
</td>
|
</td>
|
||||||
<td class="d-none d-md-table-cell">
|
<td class="d-none d-md-table-cell">
|
||||||
|
@ -25,17 +25,19 @@
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="d-none d-md-table-cell">
|
<td class="d-none d-md-table-cell">
|
||||||
<div v-if="service.group_id !== 0"><span class="badge badge-secondary">{{serviceGroup(service)}}</span></div>
|
<div v-if="service.group_id !== 0">
|
||||||
|
<span class="badge badge-secondary">{{serviceGroup(service)}}</span>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<router-link :to="{path: `/dashboard/edit_service/${service.id}`, params: {service: service} }" class="btn btn-outline-secondary">
|
<router-link v-if="$store.state.admin" :to="{path: `/dashboard/edit_service/${service.id}`, params: {service: service} }" class="btn btn-outline-secondary">
|
||||||
<i class="fas fa-chart-area"></i> Edit
|
<i class="fas fa-chart-area"></i> Edit
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link :to="{path: serviceLink(service), params: {service: service} }" class="btn btn-outline-secondary">
|
<router-link :to="{path: serviceLink(service), params: {service: service} }" class="btn btn-outline-secondary">
|
||||||
<i class="fas fa-chart-area"></i> View
|
<i class="fas fa-chart-area"></i> View
|
||||||
</router-link>
|
</router-link>
|
||||||
<a @click.prevent="deleteService(service)" href="#" class="btn btn-danger">
|
<a v-if="$store.state.admin" @click.prevent="deleteService(service)" href="#" class="btn btn-danger">
|
||||||
<font-awesome-icon icon="times" />
|
<font-awesome-icon icon="times" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,17 +14,16 @@
|
||||||
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
||||||
<router-link to="/dashboard/services" class="nav-link">Services</router-link>
|
<router-link to="/dashboard/services" class="nav-link">Services</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
<li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
|
||||||
<router-link to="/dashboard/users" class="nav-link">Users</router-link>
|
<router-link to="/dashboard/users" class="nav-link">Users</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
||||||
<router-link to="/dashboard/messages" class="nav-link">Messages</router-link>
|
<router-link to="/dashboard/messages" class="nav-link">Messages</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
|
||||||
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
|
||||||
<router-link to="/dashboard/settings" class="nav-link">Settings</router-link>
|
<router-link to="/dashboard/settings" class="nav-link">Settings</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li @click="navopen = !navopen" class="nav-item navbar-item">
|
<li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
|
||||||
<router-link to="/dashboard/logs" class="nav-link">Logs</router-link>
|
<router-link to="/dashboard/logs" class="nav-link">Logs</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@
|
||||||
name: 'TopNav',
|
name: 'TopNav',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
navopen: false,
|
navopen: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -55,6 +54,7 @@
|
||||||
await Api.logout()
|
await Api.logout()
|
||||||
this.$store.commit('setHasAllData', false)
|
this.$store.commit('setHasAllData', false)
|
||||||
this.$store.commit('setToken', null)
|
this.$store.commit('setToken', null)
|
||||||
|
this.$store.commit('setAdmin', false)
|
||||||
await this.$router.push('/')
|
await this.$router.push('/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4">
|
<div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4">
|
||||||
<div class="card-header">Incident: {{incident.title}}
|
<div class="card-header">Incident: {{incident.title}}
|
||||||
<button @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
|
<button v-if="IsAdmin()" @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
|
||||||
<font-awesome-icon icon="times" /> Delete
|
<font-awesome-icon icon="times" /> Delete
|
||||||
</button></div>
|
</button></div>
|
||||||
<div class="card-body bg-light pt-1">
|
<div class="card-body bg-light pt-1">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="card contain-card text-black-50 bg-white mb-5">
|
<div v-if="IsAdmin()" class="card contain-card text-black-50 bg-white mb-5">
|
||||||
<div class="card-header">Create Incident for {{service.name}}</div>
|
<div class="card-header">Create Incident for {{service.name}}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form @submit.prevent="createIncident">
|
<form @submit.prevent="createIncident">
|
||||||
|
|
|
@ -60,8 +60,10 @@
|
||||||
if (auth.error) {
|
if (auth.error) {
|
||||||
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, auth.admin)
|
||||||
this.$store.dispatch('loadAdmin')
|
this.$store.dispatch('loadAdmin')
|
||||||
|
this.$store.commit('setAdmin', auth.admin)
|
||||||
|
window.console.log(auth)
|
||||||
this.$router.push('/dashboard')
|
this.$router.push('/dashboard')
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
|
@ -61,6 +61,9 @@ export default Vue.mixin({
|
||||||
isInt(n) {
|
isInt(n) {
|
||||||
return n % 1 === 0;
|
return n % 1 === 0;
|
||||||
},
|
},
|
||||||
|
isAdmin() {
|
||||||
|
return this.$store.state.admin
|
||||||
|
},
|
||||||
loggedIn() {
|
loggedIn() {
|
||||||
const core = this.$store.getters.core
|
const core = this.$store.getters.core
|
||||||
return core.logged_in === true
|
return core.logged_in === true
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||||
<TopNav/>
|
<TopNav :admin="$store.state.admin"/>
|
||||||
<router-view/>
|
<router-view :admin="$store.state.admin"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -14,20 +14,14 @@
|
||||||
components: {
|
components: {
|
||||||
TopNav,
|
TopNav,
|
||||||
},
|
},
|
||||||
async mounted() {
|
|
||||||
if (this.$route.path !== "/login") {
|
|
||||||
try {
|
|
||||||
const u = await Api.users()
|
|
||||||
} catch (e) {
|
|
||||||
this.$router.push('/logout')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
authenticated: false
|
authenticated: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async mounted() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ export default new Vuex.Store({
|
||||||
groups: [],
|
groups: [],
|
||||||
messages: [],
|
messages: [],
|
||||||
users: [],
|
users: [],
|
||||||
notifiers: []
|
notifiers: [],
|
||||||
|
admin: false
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
hasAllData: state => state.hasAllData,
|
hasAllData: state => state.hasAllData,
|
||||||
|
@ -39,6 +40,8 @@ export default new Vuex.Store({
|
||||||
users: state => state.users,
|
users: state => state.users,
|
||||||
notifiers: state => state.notifiers,
|
notifiers: state => state.notifiers,
|
||||||
|
|
||||||
|
isAdmin: state => state.admin,
|
||||||
|
|
||||||
servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id),
|
servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id),
|
||||||
groupsInOrder: state => state.groups.sort((a, b) => a.order_id - b.order_id),
|
groupsInOrder: state => state.groups.sort((a, b) => a.order_id - b.order_id),
|
||||||
groupsClean: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id),
|
groupsClean: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id),
|
||||||
|
@ -106,7 +109,10 @@ export default new Vuex.Store({
|
||||||
},
|
},
|
||||||
setNotifiers (state, notifiers) {
|
setNotifiers (state, notifiers) {
|
||||||
state.notifiers = notifiers
|
state.notifiers = notifiers
|
||||||
}
|
},
|
||||||
|
setAdmin (state, admin) {
|
||||||
|
state.admin = admin
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async getAllServices(context) {
|
async getAllServices(context) {
|
||||||
|
|
|
@ -43,13 +43,12 @@ type apiResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiIndexHandler(r *http.Request) interface{} {
|
func apiIndexHandler(r *http.Request) interface{} {
|
||||||
coreClone := core.App
|
coreClone := *core.App
|
||||||
var loggedIn bool
|
|
||||||
_, err := getJwtToken(r)
|
_, err := getJwtToken(r)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
loggedIn = true
|
coreClone.LoggedIn = true
|
||||||
|
coreClone.IsAdmin = IsAdmin(r)
|
||||||
}
|
}
|
||||||
coreClone.LoggedIn = loggedIn
|
|
||||||
return coreClone
|
return coreClone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,12 +212,14 @@ func apiLoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
user, auth := users.AuthUser(username, password)
|
user, auth := users.AuthUser(username, password)
|
||||||
if auth {
|
if auth {
|
||||||
utils.Log.Infoln(fmt.Sprintf("User %v logged in from IP %v", user.Username, r.RemoteAddr))
|
utils.Log.Infoln(fmt.Sprintf("User %v logged in from IP %v", user.Username, r.RemoteAddr))
|
||||||
_, token := setJwtToken(user, w)
|
claim, token := setJwtToken(user, w)
|
||||||
|
|
||||||
resp := struct {
|
resp := struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
IsAdmin bool `json:"admin"`
|
||||||
}{
|
}{
|
||||||
token,
|
token,
|
||||||
|
claim.Admin,
|
||||||
}
|
}
|
||||||
returnJson(resp, w, r)
|
returnJson(resp, w, r)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -87,9 +87,9 @@ func Router() *mux.Router {
|
||||||
|
|
||||||
// API Routes
|
// API Routes
|
||||||
r.Handle("/api", scoped(apiIndexHandler))
|
r.Handle("/api", scoped(apiIndexHandler))
|
||||||
|
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
|
||||||
//r.Handle("/oauth/callback", http.HandlerFunc(OAuthRedirect))
|
//r.Handle("/oauth/callback", http.HandlerFunc(OAuthRedirect))
|
||||||
api.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")
|
|
||||||
api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
|
api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
|
||||||
api.Handle("/api/renew", authenticated(apiRenewHandler, false))
|
api.Handle("/api/renew", authenticated(apiRenewHandler, false))
|
||||||
api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
|
api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
|
||||||
|
|
|
@ -31,6 +31,7 @@ type Core struct {
|
||||||
UseCdn null.NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
UseCdn null.NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
||||||
Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"`
|
Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"`
|
||||||
LoggedIn bool `gorm:"-" json:"logged_in"`
|
LoggedIn bool `gorm:"-" json:"logged_in"`
|
||||||
|
IsAdmin bool `gorm:"-" json:"admin"`
|
||||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||||
Started time.Time `gorm:"-" json:"started_on"`
|
Started time.Time `gorm:"-" json:"started_on"`
|
||||||
|
|
Loading…
Reference in New Issue