mirror of https://github.com/statping/statping
checkin form fix, user/token route for auth
parent
aeaba54f82
commit
79b6e620bf
|
@ -7,6 +7,7 @@
|
|||
- Modified SCSS/SASS files to be generated from 1, main.scss to main.css
|
||||
- Modified index page to use /assets directory for assets, (main.css, style.css)
|
||||
- Modified index page to use CDN asset paths
|
||||
- Fixed New Checkin form
|
||||
|
||||
# 0.90.61 (07-22-2020)
|
||||
- Modified sass layouts, organized and split up sections
|
||||
|
|
|
@ -3275,6 +3275,8 @@
|
|||
"pm.test(\"Check Login JWT Token\", function () {",
|
||||
" var jsonData = pm.response.json();",
|
||||
" pm.expect(jsonData).to.have.property('token');",
|
||||
" pm.expect(jsonData).to.have.property('admin');",
|
||||
" pm.globals.set(\"token\", jsonData.token);",
|
||||
"});"
|
||||
],
|
||||
"type": "text/javascript"
|
||||
|
@ -3371,24 +3373,141 @@
|
|||
"_postman_previewlanguage": "json",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Length",
|
||||
"value": "174"
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "Set-Cookie",
|
||||
"value": "statping_auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsInNjb3BlcyI6ImFkbWluIiwiZXhwIjoxNTk2NzQzMDUzfQ.dQQGgUDhFEjCL2Gi-Seg0hBp_sqVsDn3cXB0GpSorJI; Path=/; Expires=Thu, 06 Aug 2020 19:44:13 GMT; Max-Age=259200"
|
||||
},
|
||||
{
|
||||
"key": "Date",
|
||||
"value": "Mon, 03 Aug 2020 19:44:13 GMT"
|
||||
},
|
||||
{
|
||||
"key": "Content-Length",
|
||||
"value": "197"
|
||||
},
|
||||
{
|
||||
"key": "Connection",
|
||||
"value": "close"
|
||||
}
|
||||
],
|
||||
"cookie": [],
|
||||
"body": "{\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsInNjb3BlcyI6ImFkbWluIiwiZXhwIjoxNTk2NzQzMDUzfQ.dQQGgUDhFEjCL2Gi-Seg0hBp_sqVsDn3cXB0GpSorJI\",\n \"admin\": true\n}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Check User Token",
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"id": "560e439b-d588-4a2f-a8a6-a0607531d74c",
|
||||
"exec": [
|
||||
"pm.test(\"Response is ok\", function () {",
|
||||
" pm.response.to.have.status(200);",
|
||||
"});",
|
||||
"",
|
||||
"pm.test(\"View Token Response\", function () {",
|
||||
" var jsonData = pm.response.json();",
|
||||
" pm.expect(jsonData.username).to.eql(\"admin\");",
|
||||
" pm.expect(jsonData.admin).to.eql(true);",
|
||||
" pm.expect(jsonData.scopes).to.eql(\"admin\");",
|
||||
"});"
|
||||
],
|
||||
"type": "text/javascript"
|
||||
}
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{api_key}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "urlencoded",
|
||||
"urlencoded": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{endpoint}}/api/users/token",
|
||||
"host": [
|
||||
"{{endpoint}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"users",
|
||||
"token"
|
||||
]
|
||||
},
|
||||
"description": "Send your JWT token from login to this endpoint to return the JSON values."
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"name": "Check User Token",
|
||||
"originalRequest": {
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "urlencoded",
|
||||
"urlencoded": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{endpoint}}/api/users/token",
|
||||
"host": [
|
||||
"{{endpoint}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"users",
|
||||
"token"
|
||||
]
|
||||
}
|
||||
},
|
||||
"status": "OK",
|
||||
"code": 200,
|
||||
"_postman_previewlanguage": "json",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "Date",
|
||||
"value": "Sat, 02 May 2020 00:56:17 GMT"
|
||||
"value": "Mon, 03 Aug 2020 19:47:23 GMT"
|
||||
},
|
||||
{
|
||||
"key": "Set-Cookie",
|
||||
"value": "statping_auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsImV4cCI6MTU4ODY0MDE3N30.tf399_LfAphSGlKMtgphg6qpPrn-_w92XfCrK5FwbZY; Expires=Tue, 05 May 2020 00:56:17 GMT"
|
||||
"key": "Content-Length",
|
||||
"value": "68"
|
||||
},
|
||||
{
|
||||
"key": "Connection",
|
||||
"value": "close"
|
||||
}
|
||||
],
|
||||
"cookie": [],
|
||||
"body": "{\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsImV4cCI6MTU4ODY0MDE3N30.tf399_LfAphSGlKMtgphg6qpPrn-_w92XfCrK5FwbZY\",\n \"admin\": true\n}"
|
||||
"body": "{\n \"username\": \"admin\",\n \"admin\": true,\n \"scopes\": \"admin\",\n \"exp\": 1596743053\n}"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -235,6 +235,11 @@ class Api {
|
|||
return axios.post('api/theme', data).then(response => (response.data))
|
||||
}
|
||||
|
||||
async check_token(token) {
|
||||
const f = {token: token}
|
||||
return axios.post('api/users/token', qs.stringify(f)).then(response => (response.data))
|
||||
}
|
||||
|
||||
async login(username, password) {
|
||||
const f = {username: username, password: password}
|
||||
return axios.post('api/login', qs.stringify(f)).then(response => (response.data))
|
||||
|
|
|
@ -15,7 +15,7 @@ A:HOVER {
|
|||
}
|
||||
|
||||
.text-muted {
|
||||
color: darken($text-color, 30%) !important;
|
||||
color: lighten($text-color, 30%) !important;
|
||||
}
|
||||
|
||||
.day-success {
|
||||
|
|
|
@ -15,7 +15,7 @@ $navbar-background: #ffffff;
|
|||
$input-background: #fdfdfd;
|
||||
$input-color: #4e4e4e;
|
||||
$input-border: 1px solid #c9c9c9;
|
||||
$day-success-background: #18ce08;
|
||||
$day-success-background: #20ac13;
|
||||
$day-error-background: #d50a0a;
|
||||
|
||||
/* Status Container */
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<button @click="deleteCheckin(checkin)" class="btn btn-sm small btn-danger float-right text-uppercase">Delete</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" :value="`${core.domain}/checkin/${checkin.api_key}`" readonly>
|
||||
<div class="input-group-append copy-btn">
|
||||
|
@ -137,6 +136,9 @@ export default {
|
|||
},
|
||||
last_record(checkin) {
|
||||
const r = this.records(checkin)
|
||||
if (r.length === 0) {
|
||||
return {success: false}
|
||||
}
|
||||
return r[0]
|
||||
},
|
||||
fixInts() {
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
<label for="checkin_interval" class="col-form-label">Interval (minutes)</label>
|
||||
<input v-model="checkin.interval" type="number" name="interval" class="form-control" id="checkin_interval" placeholder="1" min="1">
|
||||
</div>
|
||||
<div class="col-12 col-md-5">
|
||||
<label for="grace_period" class="col-form-label">Grace Period</label>
|
||||
<input v-model="checkin.grace" type="number" name="grace" class="form-control" id="grace_period" placeholder="10">
|
||||
</div>
|
||||
<div class="col-12 col-md-5">
|
||||
<label class="col-form-label"></label>
|
||||
<button @click.prevent="saveCheckin" type="submit" id="submit" class="btn btn-success d-block mt-2">Save Checkin</button>
|
||||
|
@ -54,7 +50,6 @@
|
|||
checkin: {
|
||||
name: "",
|
||||
interval: 60,
|
||||
grace: 60,
|
||||
service_id: this.service.id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
No updates found, create a new Incident Update below.
|
||||
</div>
|
||||
|
||||
<transition-group name="fade" tag="div">
|
||||
<div v-for="update in updates.reverse()" :key="update.id">
|
||||
<IncidentUpdate :update="update" :onUpdate="loadUpdates" :admin="true"/>
|
||||
</div>
|
||||
</transition-group>
|
||||
<div v-for="update in updates.reverse()" :key="update.id">
|
||||
<IncidentUpdate :update="update" :onUpdate="loadUpdates" :admin="true"/>
|
||||
</div>
|
||||
|
||||
<form class="row" @submit.prevent="createIncidentUpdate">
|
||||
<div class="col-12 col-md-3 mb-3 mb-md-0">
|
||||
|
@ -51,7 +49,7 @@
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
updates: [],
|
||||
updates: null,
|
||||
incident_update: {
|
||||
incident: this.incident.id,
|
||||
message: "",
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-2 col-form-label">{{$t('username')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input @keyup="checkForm" type="text" v-model="username" name="username" class="form-control" id="username" placeholder="Username" autocorrect="off" autocapitalize="none">
|
||||
<input @keyup="checkForm" type="text" v-model="username" autocomplete="username" name="username" class="form-control" id="username" placeholder="Username" autocorrect="off" autocapitalize="none">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-sm-2 col-form-label">{{$t('password')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input @keyup="checkForm" type="password" v-model="password" name="password" class="form-control" id="password" placeholder="Password">
|
||||
<input @keyup="checkForm" type="password" v-model="password" autocomplete="current-password" name="password" class="form-control" id="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
@ -46,6 +46,7 @@
|
|||
|
||||
<script>
|
||||
import Api from "../API";
|
||||
import store from "@/store";
|
||||
|
||||
export default {
|
||||
name: 'FormLogin',
|
||||
|
@ -59,17 +60,20 @@
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
username: "",
|
||||
password: "",
|
||||
auth: {},
|
||||
loading: false,
|
||||
error: false,
|
||||
disabled: true,
|
||||
username: "",
|
||||
password: "",
|
||||
auth: {},
|
||||
loading: false,
|
||||
error: false,
|
||||
disabled: true,
|
||||
google_scope: "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email",
|
||||
slack_scope: "identity.email,identity.basic"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
mounted() {
|
||||
this.$cookies.remove("statping_auth")
|
||||
},
|
||||
methods: {
|
||||
checkForm() {
|
||||
if (!this.username || !this.password) {
|
||||
this.disabled = true
|
||||
|
@ -84,9 +88,10 @@
|
|||
if (auth.error) {
|
||||
this.error = true
|
||||
} else if (auth.token) {
|
||||
// this.$cookies.set("statping_auth", auth.token)
|
||||
this.$cookies.set("statping_auth", auth.token)
|
||||
await this.$store.dispatch('loadAdmin')
|
||||
this.$store.commit('setAdmin', auth.admin)
|
||||
this.$store.commit('setLoggedIn', true)
|
||||
this.$router.push('/dashboard')
|
||||
}
|
||||
this.loading = false
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
<div v-if="notifier.method==='mobile'">
|
||||
<div class="form-group row mt-3">
|
||||
<label for="domain" class="col-sm-4 col-form-label">Statping Domain</label>
|
||||
<label for="statping_domain" class="col-sm-4 col-form-label">Statping Domain</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input v-bind:value="$store.getters.core.domain" type="text" class="form-control" id="domain" readonly>
|
||||
<input v-bind:value="$store.getters.core.domain" type="text" class="form-control" id="statping_domain" readonly>
|
||||
<div class="input-group-append copy-btn">
|
||||
<button @click.prevent="copy($store.getters.core.domain)" class="btn btn-outline-secondary" type="button">Copy</button>
|
||||
</div>
|
||||
|
|
|
@ -106,10 +106,6 @@ export default Vue.mixin({
|
|||
isAdmin() {
|
||||
return this.$store.state.admin
|
||||
},
|
||||
loggedIn() {
|
||||
const core = this.$store.getters.core
|
||||
return core.logged_in === true
|
||||
},
|
||||
iconName(name) {
|
||||
switch (name) {
|
||||
case "fas fa-terminal":
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Api from "@/API";
|
||||
import store from "@/store";
|
||||
|
||||
const Group = () => import('@/components/Index/Group')
|
||||
const Header = () => import('@/components/Index/Header')
|
||||
const MessageBlock = () => import('@/components/Index/MessageBlock')
|
||||
|
@ -44,10 +47,10 @@ export default {
|
|||
components: {
|
||||
IncidentsBlock,
|
||||
GroupServiceFailures,
|
||||
ServiceBlock,
|
||||
MessageBlock,
|
||||
Group,
|
||||
Header
|
||||
ServiceBlock,
|
||||
MessageBlock,
|
||||
Group,
|
||||
Header
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -67,14 +70,24 @@ export default {
|
|||
services_no_group() {
|
||||
return this.$store.getters.servicesNoGroup
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.logged_in = this.loggedIn()
|
||||
},
|
||||
async mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
async checkLogin() {
|
||||
const token = this.$cookies.get('statping_auth')
|
||||
if (!token) {
|
||||
this.$store.commit('setLoggedIn', false)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const jwt = await Api.check_token(token)
|
||||
this.$store.commit('setAdmin', jwt.admin)
|
||||
if (jwt.username) {
|
||||
this.$store.commit('setLoggedIn', true)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
},
|
||||
inRange(message) {
|
||||
return this.isBetween(this.now(), message.start_on, message.start_on === message.end_on ? this.maxDate().toISOString() : message.end_on)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ const NotFound = () => import('@/pages/NotFound')
|
|||
|
||||
import VueRouter from "vue-router";
|
||||
import Api from "./API";
|
||||
import store from "./store"
|
||||
|
||||
const Loading = {
|
||||
template: '<div class="jumbotron">LOADING</div>'
|
||||
|
@ -26,7 +27,10 @@ const routes = [
|
|||
{
|
||||
path: '/setup',
|
||||
name: 'Setup',
|
||||
component: Setup
|
||||
component: Setup,
|
||||
meta: {
|
||||
title: 'Statping Setup',
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
|
@ -37,14 +41,37 @@ const routes = [
|
|||
path: '/dashboard',
|
||||
component: Dashboard,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Dashboard',
|
||||
},
|
||||
beforeEnter: async (to, from, next) => {
|
||||
if (to.matched.some(record => record.meta.requiresAuth)) {
|
||||
let tk = await Api.token()
|
||||
if (to.path !== '/login' && !tk) {
|
||||
next('/login')
|
||||
return
|
||||
if (to.path !== '/login') {
|
||||
if(store.getters.loggedIn) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
const token = $cookies.get('statping_auth')
|
||||
if (!token) {
|
||||
next('/login')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const jwt = await Api.check_token(token)
|
||||
store.commit('setAdmin', jwt.admin)
|
||||
if (jwt.admin) {
|
||||
store.commit('setLoggedIn', true)
|
||||
store.commit('setUser', true)
|
||||
} else {
|
||||
store.commit('setLoggedIn', false)
|
||||
next('/login')
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
next('/login')
|
||||
return
|
||||
}
|
||||
}
|
||||
next()
|
||||
} else {
|
||||
|
@ -55,81 +82,96 @@ const routes = [
|
|||
path: '',
|
||||
component: DashboardIndex,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Dashboard',
|
||||
}
|
||||
},{
|
||||
path: 'users',
|
||||
component: DashboardUsers,
|
||||
loading: Loading,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Users',
|
||||
}
|
||||
},{
|
||||
path: 'services',
|
||||
component: DashboardServices,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Services',
|
||||
}
|
||||
},{
|
||||
path: 'create_service',
|
||||
component: EditService,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Create Service',
|
||||
}
|
||||
},{
|
||||
path: 'edit_service/:id',
|
||||
component: EditService,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Edit Service',
|
||||
}
|
||||
},{
|
||||
path: 'service/:id/incidents',
|
||||
component: Incidents,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Incidents',
|
||||
}
|
||||
},{
|
||||
path: 'service/:id/checkins',
|
||||
component: Checkins,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Checkins',
|
||||
}
|
||||
},{
|
||||
path: 'service/:id/failures',
|
||||
component: Failures,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Service Failures',
|
||||
}
|
||||
},{
|
||||
path: 'messages',
|
||||
component: DashboardMessages,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Messages',
|
||||
}
|
||||
},{
|
||||
path: 'settings',
|
||||
component: Settings,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Settings',
|
||||
}
|
||||
},{
|
||||
path: 'logs',
|
||||
component: Logs,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Logs',
|
||||
}
|
||||
},{
|
||||
path: 'help',
|
||||
component: Logs,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
requiresAuth: true,
|
||||
title: 'Statping - Help',
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: Login
|
||||
component: Login,
|
||||
meta: {
|
||||
title: 'Statping - Login',
|
||||
}
|
||||
},
|
||||
{ path: '/logout', redirect: '/' },
|
||||
{
|
||||
|
@ -157,23 +199,23 @@ const router = new VueRouter({
|
|||
routes
|
||||
})
|
||||
|
||||
let CheckAuth = (to, from, next) => {
|
||||
if (to.matched.some(record => record.meta.requiresAuth)) {
|
||||
let item = this.$cookies.get("statping_auth")
|
||||
window.console.log(item)
|
||||
if (to.path !== '/login' && !item) {
|
||||
next('/login')
|
||||
return
|
||||
}
|
||||
const auth = JSON.parse(item)
|
||||
if (!auth.token) {
|
||||
next('/login')
|
||||
return
|
||||
}
|
||||
next()
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
router.beforeEach((to, from, next) => {
|
||||
const nearestWithTitle = to.matched.slice().reverse().find(r => r.meta && r.meta.title);
|
||||
const nearestWithMeta = to.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
|
||||
const previousNearestWithMeta = from.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
|
||||
if(nearestWithTitle) document.title = nearestWithTitle.meta.title;
|
||||
Array.from(document.querySelectorAll('[data-vue-router-controlled]')).map(el => el.parentNode.removeChild(el));
|
||||
if(!nearestWithMeta) return next();
|
||||
nearestWithMeta.meta.metaTags.map(tagDef => {
|
||||
const tag = document.createElement('meta');
|
||||
Object.keys(tagDef).forEach(key => {
|
||||
tag.setAttribute(key, tagDef[key]);
|
||||
});
|
||||
tag.setAttribute('data-vue-router-controlled', '');
|
||||
return tag;
|
||||
})
|
||||
.forEach(tag => document.head.appendChild(tag));
|
||||
next();
|
||||
});
|
||||
|
||||
export default router
|
||||
|
|
|
@ -30,7 +30,8 @@ export default new Vuex.Store({
|
|||
notifiers: [],
|
||||
checkins: [],
|
||||
admin: false,
|
||||
user: false
|
||||
user: false,
|
||||
loggedIn: false
|
||||
},
|
||||
getters: {
|
||||
hasAllData: state => state.hasAllData,
|
||||
|
@ -46,6 +47,7 @@ export default new Vuex.Store({
|
|||
users: state => state.users,
|
||||
notifiers: state => state.notifiers,
|
||||
checkins: state => state.checkins,
|
||||
loggedIn: state => state.loggedIn,
|
||||
|
||||
isAdmin: state => state.admin,
|
||||
isUser: state => state.user,
|
||||
|
@ -131,6 +133,9 @@ export default new Vuex.Store({
|
|||
setAdmin (state, admin) {
|
||||
state.admin = admin
|
||||
},
|
||||
setLoggedIn (state, loggedIn) {
|
||||
state.loggedIn = loggedIn
|
||||
},
|
||||
setUser (state, user) {
|
||||
state.user = user
|
||||
},
|
||||
|
|
|
@ -51,17 +51,9 @@ func setJwtToken(user *users.User, w http.ResponseWriter) (JwtClaim, string) {
|
|||
return jwtClaim, tokenString
|
||||
}
|
||||
|
||||
func getJwtToken(r *http.Request) (JwtClaim, error) {
|
||||
c, err := r.Cookie(cookieName)
|
||||
if err != nil {
|
||||
if err == http.ErrNoCookie {
|
||||
return JwtClaim{}, err
|
||||
}
|
||||
return JwtClaim{}, err
|
||||
}
|
||||
|
||||
func parseToken(token string) (JwtClaim, error) {
|
||||
var claims JwtClaim
|
||||
tkn, err := jwt.ParseWithClaims(c.Value, &claims, func(token *jwt.Token) (interface{}, error) {
|
||||
tkn, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
|
||||
return jwtKey, nil
|
||||
})
|
||||
|
||||
|
@ -74,5 +66,16 @@ func getJwtToken(r *http.Request) (JwtClaim, error) {
|
|||
if !tkn.Valid {
|
||||
return claims, errors.New("token is not valid")
|
||||
}
|
||||
return claims, err
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func getJwtToken(r *http.Request) (JwtClaim, error) {
|
||||
c, err := r.Cookie(cookieName)
|
||||
if err != nil {
|
||||
if err == http.ErrNoCookie {
|
||||
return JwtClaim{}, err
|
||||
}
|
||||
return JwtClaim{}, err
|
||||
}
|
||||
return parseToken(c.Value)
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ func Router() *mux.Router {
|
|||
// API USER Routes
|
||||
api.Handle("/api/users", authenticated(apiAllUsersHandler, false)).Methods("GET")
|
||||
api.Handle("/api/users", authenticated(apiCreateUsersHandler, false)).Methods("POST")
|
||||
api.Handle("/api/users/token", http.HandlerFunc(apiCheckUserTokenHandler)).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")
|
||||
|
|
|
@ -80,6 +80,23 @@ func apiAllUsersHandler(w http.ResponseWriter, r *http.Request) {
|
|||
returnJson(allUsers, w, r)
|
||||
}
|
||||
|
||||
func apiCheckUserTokenHandler(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
token := r.PostForm.Get("token")
|
||||
if token == "" {
|
||||
sendErrorJson(errors.New("missing token parameter"), w, r)
|
||||
return
|
||||
}
|
||||
|
||||
claim, err := parseToken(token)
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
returnJson(claim, w, r)
|
||||
}
|
||||
|
||||
func apiCreateUsersHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var user *users.User
|
||||
err := DecodeJSON(r, &user)
|
||||
|
|
|
@ -19,11 +19,11 @@ var (
|
|||
)
|
||||
|
||||
func TestMobileNotifier(t *testing.T) {
|
||||
t.SkipNow()
|
||||
err := utils.InitLogs()
|
||||
require.Nil(t, err)
|
||||
|
||||
t.Parallel()
|
||||
t.SkipNow()
|
||||
|
||||
mobileToken = utils.Params.GetString("MOBILE_TOKEN")
|
||||
if mobileToken == "" {
|
||||
|
|
Loading…
Reference in New Issue