235 lines
6.2 KiB
Vue
235 lines
6.2 KiB
Vue
<template>
|
|
<div id="app" :class="{ 'night-mode':($store.getters.getIsNightMode == 2) }">
|
|
|
|
<div class="ui container" v-if="showFakeSite">
|
|
<div class="ui basic very padded segment">
|
|
<div class="ui inverted red segment">
|
|
<h1>WARNING - False site detected</h1>
|
|
<h2>The Domain for this website is not correct.</h2>
|
|
<h2>Only trust <a class="ui button" href="https://www.solidscribe.com">https://www.solidscribe.com</a></h2>
|
|
<h2>Do not any enter any personal information into this website.</h2>
|
|
<h2>You will be redirected to the correct domain in {{redirectSeconds}}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="auth-block" v-if="requireAuth">
|
|
<div class="ui raised inverted segment">
|
|
<div class="ui centered header">
|
|
Authentication Required
|
|
</div>
|
|
<div class="ui small inverted centered header" v-if="$store.getters.getUsername">
|
|
<i class="green user outline icon"></i>
|
|
{{ $store.getters.getUsername }}
|
|
</div>
|
|
|
|
<div class="ui large form">
|
|
<div class="field">
|
|
<div class="ui small inverted header">Password</div>
|
|
<div class="ui input">
|
|
<input type="password" v-model="password" placeholder="Password">
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<div class="ui small inverted header">One Time Password</div>
|
|
<div class="ui input">
|
|
<input type="password" v-model="otp" placeholder="One Time Password">
|
|
</div>
|
|
</div>
|
|
<div class="ui fluid inverted black button">
|
|
<i class="unlock icon"></i>
|
|
Submit</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<global-site-menu v-if="!showFakeSite" />
|
|
|
|
<router-view v-if="!showFakeSite" />
|
|
|
|
<global-notification />
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
// import io from 'socket.io-client'
|
|
import axios from 'axios'
|
|
|
|
export default {
|
|
name: 'App',
|
|
components: {
|
|
'global-site-menu': require('@/components/GlobalSiteMenu.vue').default,
|
|
'global-notification':require('@/components/GlobalNotificationComponent.vue').default,
|
|
},
|
|
data: function(){
|
|
return {
|
|
showFakeSite:false, //Incorrect domain detection
|
|
redirectSeconds: 15,
|
|
fetchingInProgress: false, //Prevent start getting token while fetch is in progress
|
|
blockUntilNextRequest: false, //If token was just renewed, don't fetch more until next request
|
|
|
|
requireAuth: false,
|
|
password: '',
|
|
otp: '',
|
|
}
|
|
},
|
|
|
|
//Axios response interceptor
|
|
// - Gets new session tokens from server and uses them in app
|
|
beforeCreate: function(){
|
|
|
|
//Before all requests going out
|
|
axios.interceptors.request.use(
|
|
(config) => {
|
|
|
|
//Enable token fetching after another request is made
|
|
if(this.blockUntilNextRequest){
|
|
this.fetchingInProgress = false
|
|
this.blockUntilNextRequest = false
|
|
}
|
|
|
|
return config
|
|
},
|
|
(error) => {
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
// Add a response interceptor, token can be renewed on every response
|
|
axios.interceptors.response.use(
|
|
(response) => {
|
|
|
|
if(typeof response.headers.remaininguses !== 'undefined'){
|
|
|
|
// console.log(response.headers.remaininguses)
|
|
//Look at remaining uses of token, if its less than five, request a new one
|
|
if(response.headers.remaininguses < 15 && !this.fetchingInProgress && !this.blockUntilNextRequest){
|
|
this.fetchingInProgress = true
|
|
const currentToken = localStorage.getItem('loginToken')
|
|
this.$io.emit('renew_session_token', currentToken)
|
|
}
|
|
}
|
|
|
|
return response
|
|
},
|
|
(error) => {
|
|
|
|
//Catch all authorization errors, log user out if we encounter one
|
|
if(error.response && error.response.status == 401){
|
|
|
|
this.$router.push('/')
|
|
this.$store.commit('destroyLoginToken')
|
|
this.$bus.$emit('notification', 'Error: You have been logged out.')
|
|
|
|
}
|
|
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
//Puts token into state on page load
|
|
let token = localStorage.getItem('loginToken')
|
|
let username = localStorage.getItem('username')
|
|
|
|
//
|
|
if(token && token.length > 0){
|
|
|
|
//setup username display
|
|
this.$store.commit('setUsername', username)
|
|
|
|
//Set session token on every request if set
|
|
axios.defaults.headers.common['authorizationtoken'] = token
|
|
|
|
//Setup websockets into vue instance
|
|
const socket = this.$io
|
|
socket.on('connect', () => {
|
|
|
|
//Put user into personal event room for live note updates, etc
|
|
this.$io.emit('user_connect', token)
|
|
})
|
|
}
|
|
|
|
|
|
//Detect if user is on a mobile browser and set a flag in store
|
|
this.$store.commit('detectIsUserOnMobile')
|
|
|
|
//Set Main theme color
|
|
const accentColor = localStorage.getItem('main-accent')
|
|
if(accentColor){
|
|
document.documentElement.style.setProperty('--main-accent', accentColor)
|
|
}
|
|
|
|
//Set color theme based on local storage
|
|
const themeNumber = localStorage.getItem('nightMode')
|
|
if(themeNumber != null){
|
|
this.$store.commit('toggleNightMode', themeNumber)
|
|
}
|
|
|
|
},
|
|
mounted: function(){
|
|
|
|
const isDev = process.env['NODE_ENV'] == 'development'
|
|
if(window.location.hostname.toLowerCase().replace('www.','') != "solidscribe.com" && !isDev){
|
|
this.showFakeSite = true
|
|
setInterval(() => {
|
|
this.redirectSeconds--
|
|
if(this.redirectSeconds == 0){
|
|
window.location.href = 'https://www.solidscribe.com'
|
|
}
|
|
}, 1000)
|
|
}
|
|
|
|
//Update totals for entire app on event
|
|
this.$io.on('update_counts', () => {
|
|
console.log('Got event, update totals')
|
|
this.$store.dispatch('fetchAndUpdateUserTotals')
|
|
})
|
|
|
|
this.$io.on('recievend_new_token', newToken => {
|
|
|
|
// console.log('Got a new token')
|
|
|
|
axios.defaults.headers.common['authorizationtoken'] = newToken
|
|
localStorage.setItem('loginToken', newToken)
|
|
|
|
//Disable getting new tokens until next request
|
|
this.blockUntilNextRequest = true
|
|
})
|
|
|
|
//Track users active sessions
|
|
this.$io.on('update_active_user_count', countData => {
|
|
this.$store.commit('setActiveSessions', countData)
|
|
})
|
|
|
|
},
|
|
computed: {
|
|
loggedIn () {
|
|
//Map logged in from state
|
|
return this.$store.getters.getLoggedIn
|
|
}
|
|
},
|
|
methods: {
|
|
loginGateway() {
|
|
if(!this.loggedIn){
|
|
console.log('This user is not logged in')
|
|
this.$router.push({'path':'/login'})
|
|
return
|
|
}
|
|
},
|
|
logout() {
|
|
|
|
this.$router.push('/')
|
|
axios.post('/api/user/logout')
|
|
|
|
setTimeout(() => {
|
|
this.$store.commit('destroyLoginToken')
|
|
this.$bus.$emit('notification', 'Logged Out')
|
|
}, 200)
|
|
},
|
|
}
|
|
}
|
|
</script> |