Now use vuex to manage state for authentication
This commit is contained in:
parent
df94ae37bf
commit
b5ce65fc3e
|
@ -1,99 +0,0 @@
|
||||||
import logger from '@/logging'
|
|
||||||
import config from '@/config'
|
|
||||||
import cache from '@/cache'
|
|
||||||
import Vue from 'vue'
|
|
||||||
|
|
||||||
import favoriteTracks from '@/favorites/tracks'
|
|
||||||
|
|
||||||
// URL and endpoint constants
|
|
||||||
const LOGIN_URL = config.API_URL + 'token/'
|
|
||||||
const USER_PROFILE_URL = config.API_URL + 'users/users/me/'
|
|
||||||
// const SIGNUP_URL = API_URL + 'users/'
|
|
||||||
|
|
||||||
let userData = {
|
|
||||||
authenticated: false,
|
|
||||||
username: '',
|
|
||||||
availablePermissions: {},
|
|
||||||
profile: {}
|
|
||||||
}
|
|
||||||
let auth = {
|
|
||||||
|
|
||||||
// Send a request to the login URL and save the returned JWT
|
|
||||||
login (context, creds, redirect, onError) {
|
|
||||||
return context.$http.post(LOGIN_URL, creds).then(response => {
|
|
||||||
logger.default.info('Successfully logged in as', creds.username)
|
|
||||||
cache.set('token', response.data.token)
|
|
||||||
cache.set('username', creds.username)
|
|
||||||
|
|
||||||
this.user.authenticated = true
|
|
||||||
this.user.username = creds.username
|
|
||||||
this.connect()
|
|
||||||
// Redirect to a specified route
|
|
||||||
if (redirect) {
|
|
||||||
context.$router.push(redirect)
|
|
||||||
}
|
|
||||||
}, response => {
|
|
||||||
logger.default.error('Error while logging in', response.data)
|
|
||||||
if (onError) {
|
|
||||||
onError(response)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// To log out, we just need to remove the token
|
|
||||||
logout () {
|
|
||||||
cache.clear()
|
|
||||||
this.user.authenticated = false
|
|
||||||
logger.default.info('Log out, goodbye!')
|
|
||||||
},
|
|
||||||
|
|
||||||
checkAuth () {
|
|
||||||
logger.default.info('Checking authentication...')
|
|
||||||
var jwt = this.getAuthToken()
|
|
||||||
var username = cache.get('username')
|
|
||||||
if (jwt) {
|
|
||||||
this.user.authenticated = true
|
|
||||||
this.user.username = username
|
|
||||||
logger.default.info('Logged back in as ' + username)
|
|
||||||
this.connect()
|
|
||||||
} else {
|
|
||||||
logger.default.info('Anonymous user')
|
|
||||||
this.user.authenticated = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getAuthToken () {
|
|
||||||
return cache.get('token')
|
|
||||||
},
|
|
||||||
|
|
||||||
// The object to be passed as a header for authenticated requests
|
|
||||||
getAuthHeader () {
|
|
||||||
return 'JWT ' + this.getAuthToken()
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchProfile () {
|
|
||||||
let resource = Vue.resource(USER_PROFILE_URL)
|
|
||||||
return resource.get({}).then((response) => {
|
|
||||||
logger.default.info('Successfully fetched user profile')
|
|
||||||
return response.data
|
|
||||||
}, (response) => {
|
|
||||||
logger.default.info('Error while fetching user profile')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
connect () {
|
|
||||||
// called once user has logged in successfully / reauthenticated
|
|
||||||
// e.g. after a page refresh
|
|
||||||
let self = this
|
|
||||||
this.fetchProfile().then(data => {
|
|
||||||
Vue.set(self.user, 'profile', data)
|
|
||||||
Object.keys(data.permissions).forEach(function (key) {
|
|
||||||
// this makes it easier to check for permissions in templates
|
|
||||||
Vue.set(self.user.availablePermissions, key, data.permissions[String(key)].status)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
favoriteTracks.fetch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vue.set(auth, 'user', userData)
|
|
||||||
export default auth
|
|
|
@ -28,8 +28,8 @@
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<div class="ui bottom attached active tab" data-tab="library">
|
<div class="ui bottom attached active tab" data-tab="library">
|
||||||
<div class="ui inverted vertical fluid menu">
|
<div class="ui inverted vertical fluid menu">
|
||||||
<router-link class="item" v-if="auth.user.authenticated" :to="{name: 'profile', params: {username: auth.user.username}}"><i class="user icon"></i> Logged in as {{ auth.user.username }}</router-link>
|
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'profile', params: {username: $store.state.auth.username}}"><i class="user icon"></i> Logged in as {{ $store.state.auth.username }}</router-link>
|
||||||
<router-link class="item" v-if="auth.user.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i> Logout</router-link>
|
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i> Logout</router-link>
|
||||||
<router-link class="item" v-else :to="{name: 'login'}"><i class="sign in icon"></i> Login</router-link>
|
<router-link class="item" v-else :to="{name: 'login'}"><i class="sign in icon"></i> Login</router-link>
|
||||||
<router-link class="item" :to="{path: '/library'}"><i class="sound icon"> </i>Browse library</router-link>
|
<router-link class="item" :to="{path: '/library'}"><i class="sound icon"> </i>Browse library</router-link>
|
||||||
<router-link class="item" :to="{path: '/favorites'}"><i class="heart icon"></i> Favorites</router-link>
|
<router-link class="item" :to="{path: '/favorites'}"><i class="heart icon"></i> Favorites</router-link>
|
||||||
|
@ -97,7 +97,6 @@ import Player from '@/components/audio/Player'
|
||||||
import favoriteTracks from '@/favorites/tracks'
|
import favoriteTracks from '@/favorites/tracks'
|
||||||
import Logo from '@/components/Logo'
|
import Logo from '@/components/Logo'
|
||||||
import SearchBar from '@/components/audio/SearchBar'
|
import SearchBar from '@/components/audio/SearchBar'
|
||||||
import auth from '@/auth'
|
|
||||||
import backend from '@/audio/backend'
|
import backend from '@/audio/backend'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
|
@ -113,7 +112,6 @@ export default {
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
auth: auth,
|
|
||||||
backend: backend,
|
backend: backend,
|
||||||
favoriteTracks
|
favoriteTracks
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
<script>
|
<script>
|
||||||
import jQuery from 'jquery'
|
import jQuery from 'jquery'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import auth from '@/auth'
|
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
|
||||||
const SEARCH_URL = config.API_URL + 'search?query={query}'
|
const SEARCH_URL = config.API_URL + 'search?query={query}'
|
||||||
|
@ -27,7 +26,7 @@ export default {
|
||||||
},
|
},
|
||||||
apiSettings: {
|
apiSettings: {
|
||||||
beforeXHR: function (xhrObject) {
|
beforeXHR: function (xhrObject) {
|
||||||
xhrObject.setRequestHeader('Authorization', auth.getAuthHeader())
|
xhrObject.setRequestHeader('Authorization', this.$store.getters['auth/header'])
|
||||||
return xhrObject
|
return xhrObject
|
||||||
},
|
},
|
||||||
onResponse: function (initialResponse) {
|
onResponse: function (initialResponse) {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<script>
|
<script>
|
||||||
import {mapState} from 'vuex'
|
import {mapState} from 'vuex'
|
||||||
import backend from '@/audio/backend'
|
import backend from '@/audio/backend'
|
||||||
import auth from '@/auth'
|
|
||||||
import url from '@/utils/url'
|
import url from '@/utils/url'
|
||||||
|
|
||||||
// import logger from '@/logging'
|
// import logger from '@/logging'
|
||||||
|
@ -40,12 +39,12 @@ export default {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let path = backend.absoluteUrl(file.path)
|
let path = backend.absoluteUrl(file.path)
|
||||||
if (auth.user.authenticated) {
|
if (this.$store.state.auth.authenticated) {
|
||||||
// we need to send the token directly in url
|
// we need to send the token directly in url
|
||||||
// so authentication can be checked by the backend
|
// so authentication can be checked by the backend
|
||||||
// because for audio files we cannot use the regular Authentication
|
// because for audio files we cannot use the regular Authentication
|
||||||
// header
|
// header
|
||||||
path = url.updateQueryString(path, 'jwt', auth.getAuthToken())
|
path = url.updateQueryString(path, 'jwt', this.$store.state.auth.token)
|
||||||
}
|
}
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,9 @@
|
||||||
Keep your PRIVATE_TOKEN secret as it gives access to your account.
|
Keep your PRIVATE_TOKEN secret as it gives access to your account.
|
||||||
</div>
|
</div>
|
||||||
<pre>
|
<pre>
|
||||||
export PRIVATE_TOKEN="{{ auth.getAuthToken ()}}"
|
export PRIVATE_TOKEN="{{ $store.state.auth.token ()}}"
|
||||||
<template v-for="track in tracks"><template v-if="track.files.length > 0">
|
<template v-for="track in tracks"><template v-if="track.files.length > 0">
|
||||||
curl -G -o "{{ track.files[0].filename }}" <template v-if="auth.user.authenticated">--header "Authorization: JWT $PRIVATE_TOKEN"</template> "{{ backend.absoluteUrl(track.files[0].path) }}"</template></template>
|
curl -G -o "{{ track.files[0].filename }}" <template v-if="$store.state.auth.authenticated">--header "Authorization: JWT $PRIVATE_TOKEN"</template> "{{ backend.absoluteUrl(track.files[0].path) }}"</template></template>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,7 +83,6 @@ curl -G -o "{{ track.files[0].filename }}" <template v-if="auth.user.authenticat
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import backend from '@/audio/backend'
|
import backend from '@/audio/backend'
|
||||||
import auth from '@/auth'
|
|
||||||
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
||||||
import PlayButton from '@/components/audio/PlayButton'
|
import PlayButton from '@/components/audio/PlayButton'
|
||||||
|
|
||||||
|
@ -102,7 +101,6 @@ export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
backend: backend,
|
backend: backend,
|
||||||
auth: auth,
|
|
||||||
showDownloadModal: false
|
showDownloadModal: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import auth from '@/auth'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'login',
|
name: 'login',
|
||||||
props: {
|
props: {
|
||||||
next: {type: String}
|
next: {type: String, default: '/'}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -72,14 +71,17 @@ export default {
|
||||||
}
|
}
|
||||||
// We need to pass the component's this context
|
// We need to pass the component's this context
|
||||||
// to properly make use of http in the auth service
|
// to properly make use of http in the auth service
|
||||||
auth.login(this, credentials, {path: this.next}, function (response) {
|
this.$store.dispatch('auth/login', {
|
||||||
// error callback
|
credentials,
|
||||||
if (response.status === 400) {
|
next: this.next,
|
||||||
self.error = 'invalid_credentials'
|
onError: response => {
|
||||||
} else {
|
if (response.status === 400) {
|
||||||
self.error = 'unknown_error'
|
self.error = 'invalid_credentials'
|
||||||
|
} else {
|
||||||
|
self.error = 'unknown_error'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).then((response) => {
|
}).then(e => {
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
<div class="ui vertical stripe segment">
|
<div class="ui vertical stripe segment">
|
||||||
<div class="ui small text container">
|
<div class="ui small text container">
|
||||||
<h2>Are you sure you want to log out?</h2>
|
<h2>Are you sure you want to log out?</h2>
|
||||||
<p>You are currently logged in as {{ auth.user.username }}</p>
|
<p>You are currently logged in as {{ $store.state.auth.username }}</p>
|
||||||
<button class="ui button" @click="logout">Yes, log me out!</button>
|
<button class="ui button" @click="$store.dispatch('auth/logout')">Yes, log me out!</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,23 +12,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import auth from '@/auth'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'logout',
|
name: 'logout'
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
// We need to initialize the component with any
|
|
||||||
// properties that will be used in it
|
|
||||||
auth: auth
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
logout () {
|
|
||||||
auth.logout()
|
|
||||||
this.$router.push({name: 'index'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
<div v-if="isLoading" class="ui vertical segment">
|
<div v-if="isLoading" class="ui vertical segment">
|
||||||
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
|
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="profile">
|
<template v-if="$store.state.auth.profile">
|
||||||
<div :class="['ui', 'head', 'vertical', 'center', 'aligned', 'stripe', 'segment']">
|
<div :class="['ui', 'head', 'vertical', 'center', 'aligned', 'stripe', 'segment']">
|
||||||
<h2 class="ui center aligned icon header">
|
<h2 class="ui center aligned icon header">
|
||||||
<i class="circular inverted user green icon"></i>
|
<i class="circular inverted user green icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{ profile.username }}
|
{{ $store.state.auth.profile.username }}
|
||||||
<div class="sub header">Registered since {{ signupDate }}</div>
|
<div class="sub header">Registered since {{ signupDate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui basic green label">this is you!</div>
|
<div class="ui basic green label">this is you!</div>
|
||||||
<div v-if="profile.is_staff" class="ui yellow label">
|
<div v-if="$store.state.auth.profile.is_staff" class="ui yellow label">
|
||||||
<i class="star icon"></i>
|
<i class="star icon"></i>
|
||||||
Staff member
|
Staff member
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,35 +23,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import auth from '@/auth'
|
const dateFormat = require('dateformat')
|
||||||
var dateFormat = require('dateformat')
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'login',
|
name: 'login',
|
||||||
props: ['username'],
|
props: ['username'],
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
profile: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created () {
|
created () {
|
||||||
this.fetchProfile()
|
this.$store.dispatch('auth/fetchProfile')
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchProfile () {
|
|
||||||
let self = this
|
|
||||||
auth.fetchProfile().then(data => {
|
|
||||||
self.profile = data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
signupDate () {
|
signupDate () {
|
||||||
let d = new Date(this.profile.date_joined)
|
let d = new Date(this.$store.state.auth.profile.date_joined)
|
||||||
return dateFormat(d, 'longDate')
|
return dateFormat(d, 'longDate')
|
||||||
},
|
},
|
||||||
isLoading () {
|
isLoading () {
|
||||||
return !this.profile
|
return !this.$store.state.auth.profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<router-link class="ui item" to="/library" exact>Browse</router-link>
|
<router-link class="ui item" to="/library" exact>Browse</router-link>
|
||||||
<router-link class="ui item" to="/library/artists" exact>Artists</router-link>
|
<router-link class="ui item" to="/library/artists" exact>Artists</router-link>
|
||||||
<div class="ui secondary right menu">
|
<div class="ui secondary right menu">
|
||||||
<router-link v-if="auth.user.availablePermissions['import.launch']" class="ui item" to="/library/import/launch" exact>Import</router-link>
|
<router-link v-if="$store.state.auth.availablePermissions['import.launch']" class="ui item" to="/library/import/launch" exact>Import</router-link>
|
||||||
<router-link v-if="auth.user.availablePermissions['import.launch']" class="ui item" to="/library/import/batches">Import batches</router-link>
|
<router-link v-if="$store.state.auth.availablePermissions['import.launch']" class="ui item" to="/library/import/batches">Import batches</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<router-view :key="$route.fullPath"></router-view>
|
<router-view :key="$route.fullPath"></router-view>
|
||||||
|
@ -14,15 +14,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import auth from '@/auth'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'library',
|
name: 'library'
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
auth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import auth from '@/auth'
|
|
||||||
import url from '@/utils/url'
|
import url from '@/utils/url'
|
||||||
import logger from '@/logging'
|
import logger from '@/logging'
|
||||||
import backend from '@/audio/backend'
|
import backend from '@/audio/backend'
|
||||||
|
@ -124,8 +123,8 @@ export default {
|
||||||
downloadUrl () {
|
downloadUrl () {
|
||||||
if (this.track.files.length > 0) {
|
if (this.track.files.length > 0) {
|
||||||
let u = backend.absoluteUrl(this.track.files[0].path)
|
let u = backend.absoluteUrl(this.track.files[0].path)
|
||||||
if (auth.user.authenticated) {
|
if (this.$store.state.auth.authenticated) {
|
||||||
u = url.updateQueryString(u, 'jwt', auth.getAuthToken())
|
u = url.updateQueryString(u, 'jwt', this.$store.state.auth.token)
|
||||||
}
|
}
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<script>
|
<script>
|
||||||
import jQuery from 'jquery'
|
import jQuery from 'jquery'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import auth from '@/auth'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -66,7 +65,7 @@ export default {
|
||||||
},
|
},
|
||||||
apiSettings: {
|
apiSettings: {
|
||||||
beforeXHR: function (xhrObject, s) {
|
beforeXHR: function (xhrObject, s) {
|
||||||
xhrObject.setRequestHeader('Authorization', auth.getAuthHeader())
|
xhrObject.setRequestHeader('Authorization', this.$store.getters['auth/header'])
|
||||||
return xhrObject
|
return xhrObject
|
||||||
},
|
},
|
||||||
onResponse: function (initialResponse) {
|
onResponse: function (initialResponse) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Vue from 'vue'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import VueResource from 'vue-resource'
|
import VueResource from 'vue-resource'
|
||||||
import auth from './auth'
|
|
||||||
import VueLazyload from 'vue-lazyload'
|
import VueLazyload from 'vue-lazyload'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
|
|
||||||
|
@ -26,8 +25,8 @@ Vue.config.productionTip = false
|
||||||
|
|
||||||
Vue.http.interceptors.push(function (request, next) {
|
Vue.http.interceptors.push(function (request, next) {
|
||||||
// modify headers
|
// modify headers
|
||||||
if (auth.user.authenticated) {
|
if (store.state.auth.authenticated) {
|
||||||
request.headers.set('Authorization', auth.getAuthHeader())
|
request.headers.set('Authorization', store.getters['auth/header'])
|
||||||
}
|
}
|
||||||
next(function (response) {
|
next(function (response) {
|
||||||
// redirect to login form when we get unauthorized response from server
|
// redirect to login form when we get unauthorized response from server
|
||||||
|
@ -38,7 +37,7 @@ Vue.http.interceptors.push(function (request, next) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
auth.checkAuth()
|
store.dispatch('auth/check')
|
||||||
/* eslint-disable no-new */
|
/* eslint-disable no-new */
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import config from '@/config'
|
||||||
|
import logger from '@/logging'
|
||||||
|
import cache from '@/cache'
|
||||||
|
import router from '@/router'
|
||||||
|
// import favoriteTracks from '@/favorites/tracks'
|
||||||
|
|
||||||
|
const LOGIN_URL = config.API_URL + 'token/'
|
||||||
|
const USER_PROFILE_URL = config.API_URL + 'users/users/me/'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
authenticated: false,
|
||||||
|
username: '',
|
||||||
|
availablePermissions: {},
|
||||||
|
profile: null,
|
||||||
|
token: ''
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
header: state => {
|
||||||
|
return 'JWT ' + state.token
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
profile: (state, value) => {
|
||||||
|
state.profile = value
|
||||||
|
},
|
||||||
|
authenticated: (state, value) => {
|
||||||
|
state.authenticated = value
|
||||||
|
},
|
||||||
|
username: (state, value) => {
|
||||||
|
state.username = value
|
||||||
|
},
|
||||||
|
token: (state, value) => {
|
||||||
|
state.token = value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// Send a request to the login URL and save the returned JWT
|
||||||
|
login ({commit, dispatch, state}, {next, credentials, onError}) {
|
||||||
|
let resource = Vue.resource(LOGIN_URL)
|
||||||
|
return resource.save({}, credentials).then(response => {
|
||||||
|
logger.default.info('Successfully logged in as', credentials.username)
|
||||||
|
commit('token', response.data.token)
|
||||||
|
cache.set('token', response.data.token)
|
||||||
|
commit('username', credentials.username)
|
||||||
|
cache.set('username', credentials.username)
|
||||||
|
commit('authenticated', true)
|
||||||
|
dispatch('fetchProfile')
|
||||||
|
// Redirect to a specified route
|
||||||
|
router.push(next)
|
||||||
|
}, response => {
|
||||||
|
logger.default.error('Error while logging in', response.data)
|
||||||
|
onError(response)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
logout ({commit}) {
|
||||||
|
cache.clear()
|
||||||
|
commit('authenticated', false)
|
||||||
|
commit('profile', null)
|
||||||
|
logger.default.info('Log out, goodbye!')
|
||||||
|
router.push({name: 'index'})
|
||||||
|
},
|
||||||
|
check ({commit, dispatch, state}) {
|
||||||
|
logger.default.info('Checking authentication...')
|
||||||
|
var jwt = cache.get('token')
|
||||||
|
var username = cache.get('username')
|
||||||
|
if (jwt) {
|
||||||
|
commit('authenticated', true)
|
||||||
|
commit('username', username)
|
||||||
|
commit('token', jwt)
|
||||||
|
logger.default.info('Logged back in as ' + username)
|
||||||
|
dispatch('fetchProfile')
|
||||||
|
} else {
|
||||||
|
logger.default.info('Anonymous user')
|
||||||
|
commit('authenticated', false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetchProfile ({commit, state}) {
|
||||||
|
let resource = Vue.resource(USER_PROFILE_URL)
|
||||||
|
return resource.get({}).then((response) => {
|
||||||
|
logger.default.info('Successfully fetched user profile')
|
||||||
|
let data = response.data
|
||||||
|
commit('profile', data)
|
||||||
|
// favoriteTracks.fetch()
|
||||||
|
console.log('AFTER')
|
||||||
|
Object.keys(data.permissions).forEach(function (key) {
|
||||||
|
// this makes it easier to check for permissions in templates
|
||||||
|
state.availablePermissions[key] = data.permissions[String(key)].status
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
|
}, (response) => {
|
||||||
|
logger.default.info('Error while fetching user profile')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import auth from './auth'
|
||||||
import queue from './queue'
|
import queue from './queue'
|
||||||
import radios from './radios'
|
import radios from './radios'
|
||||||
import player from './player'
|
import player from './player'
|
||||||
|
@ -9,6 +10,7 @@ Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
|
auth,
|
||||||
queue,
|
queue,
|
||||||
radios,
|
radios,
|
||||||
player
|
player
|
||||||
|
|
Loading…
Reference in New Issue