Fix #124 and #155: properly reset everything on logout

This commit is contained in:
Eliot Berriot 2018-04-19 22:15:13 +02:00
parent 74bd0bae8c
commit de4b0f3022
No known key found for this signature in database
GPG Key ID: DD6965E2476E5C27
11 changed files with 54 additions and 14 deletions

View File

@ -0,0 +1 @@
Reset all sensitive front-end data on logout (#124)

View File

@ -0,0 +1 @@
Fixed broken playlist modal after login (#155)

View File

@ -35,7 +35,7 @@
<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-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" v-if="$store.state.auth.authenticated" :to="{path: '/favorites'}"><i class="heart icon"></i> Favorites</router-link>
<a <a
@click="$store.commit('playlists/chooseTrack', null)" @click="$store.commit('playlists/chooseTrack', null)"
v-if="$store.state.auth.authenticated" v-if="$store.state.auth.authenticated"

View File

@ -19,6 +19,14 @@ export default {
} }
}, },
mutations: { mutations: {
reset (state) {
state.authenticated = false
state.profile = null
state.username = ''
state.token = ''
state.tokenData = {}
state.availablePermissions = {}
},
profile: (state, value) => { profile: (state, value) => {
state.profile = value state.profile = value
}, },
@ -53,8 +61,6 @@ export default {
return axios.post('token/', credentials).then(response => { return axios.post('token/', credentials).then(response => {
logger.default.info('Successfully logged in as', credentials.username) logger.default.info('Successfully logged in as', credentials.username)
commit('token', response.data.token) commit('token', response.data.token)
commit('username', credentials.username)
commit('authenticated', true)
dispatch('fetchProfile') dispatch('fetchProfile')
// Redirect to a specified route // Redirect to a specified route
router.push(next) router.push(next)
@ -64,19 +70,25 @@ export default {
}) })
}, },
logout ({commit}) { logout ({commit}) {
commit('authenticated', false) let modules = [
'auth',
'favorites',
'player',
'playlists',
'queue',
'radios'
]
modules.forEach(m => {
commit(`${m}/reset`, null, {root: true})
})
logger.default.info('Log out, goodbye!') logger.default.info('Log out, goodbye!')
router.push({name: 'index'}) router.push({name: 'index'})
}, },
check ({commit, dispatch, state}) { check ({commit, dispatch, state}) {
logger.default.info('Checking authentication...') logger.default.info('Checking authentication...')
var jwt = state.token var jwt = state.token
var username = state.username
if (jwt) { if (jwt) {
commit('authenticated', true)
commit('username', username)
commit('token', jwt) commit('token', jwt)
logger.default.info('Logged back in as ' + username)
dispatch('fetchProfile') dispatch('fetchProfile')
dispatch('refreshToken') dispatch('refreshToken')
} else { } else {
@ -88,6 +100,7 @@ export default {
return axios.get('users/users/me/').then((response) => { return axios.get('users/users/me/').then((response) => {
logger.default.info('Successfully fetched user profile') logger.default.info('Successfully fetched user profile')
let data = response.data let data = response.data
commit('authenticated', true)
commit('profile', data) commit('profile', data)
commit('username', data.username) commit('username', data.username)
dispatch('favorites/fetch', null, {root: true}) dispatch('favorites/fetch', null, {root: true})

View File

@ -20,6 +20,10 @@ export default {
} }
} }
state.count = state.tracks.length state.count = state.tracks.length
},
reset (state) {
state.tracks = []
state.count = 0
} }
}, },
getters: { getters: {

View File

@ -15,6 +15,10 @@ export default {
looping: 0 // 0 -> no, 1 -> on track, 2 -> on queue looping: 0 // 0 -> no, 1 -> on track, 2 -> on queue
}, },
mutations: { mutations: {
reset (state) {
state.errorCount = 0
state.playing = false
},
volume (state, value) { volume (state, value) {
value = parseFloat(value) value = parseFloat(value)
value = Math.min(value, 1) value = Math.min(value, 1)

View File

@ -17,6 +17,11 @@ export default {
}, },
showModal (state, value) { showModal (state, value) {
state.showModal = value state.showModal = value
},
reset (state) {
state.playlists = []
state.modalTrack = null
state.showModal = false
} }
}, },
actions: { actions: {

View File

@ -10,6 +10,12 @@ export default {
previousQueue: null previousQueue: null
}, },
mutations: { mutations: {
reset (state) {
state.tracks = []
state.currentIndex = -1
state.ended = true
state.previousQueue = null
},
currentIndex (state, value) { currentIndex (state, value) {
state.currentIndex = value state.currentIndex = value
}, },

View File

@ -26,6 +26,10 @@ export default {
} }
}, },
mutations: { mutations: {
reset (state) {
state.running = false
state.current = false
},
current: (state, value) => { current: (state, value) => {
state.current = value state.current = value
}, },

View File

@ -89,7 +89,12 @@ describe('store/auth', () => {
action: store.actions.logout, action: store.actions.logout,
params: {state: {}}, params: {state: {}},
expectedMutations: [ expectedMutations: [
{ type: 'authenticated', payload: false } { type: 'auth/reset', payload: null, options: {root: true} },
{ type: 'favorites/reset', payload: null, options: {root: true} },
{ type: 'player/reset', payload: null, options: {root: true} },
{ type: 'playlists/reset', payload: null, options: {root: true} },
{ type: 'queue/reset', payload: null, options: {root: true} },
{ type: 'radios/reset', payload: null, options: {root: true} }
] ]
}, done) }, done)
}) })
@ -107,8 +112,6 @@ describe('store/auth', () => {
action: store.actions.check, action: store.actions.check,
params: {state: {token: 'test', username: 'user'}}, params: {state: {token: 'test', username: 'user'}},
expectedMutations: [ expectedMutations: [
{ type: 'authenticated', payload: true },
{ type: 'username', payload: 'user' },
{ type: 'token', payload: 'test' } { type: 'token', payload: 'test' }
], ],
expectedActions: [ expectedActions: [
@ -132,8 +135,6 @@ describe('store/auth', () => {
payload: {credentials: credentials}, payload: {credentials: credentials},
expectedMutations: [ expectedMutations: [
{ type: 'token', payload: 'test' }, { type: 'token', payload: 'test' },
{ type: 'username', payload: 'bob' },
{ type: 'authenticated', payload: true }
], ],
expectedActions: [ expectedActions: [
{ type: 'fetchProfile' } { type: 'fetchProfile' }
@ -175,6 +176,7 @@ describe('store/auth', () => {
testAction({ testAction({
action: store.actions.fetchProfile, action: store.actions.fetchProfile,
expectedMutations: [ expectedMutations: [
{ type: 'authenticated', payload: true },
{ type: 'profile', payload: profile }, { type: 'profile', payload: profile },
{ type: 'username', payload: profile.username }, { type: 'username', payload: profile.username },
{ type: 'permission', payload: {key: 'admin', status: true} } { type: 'permission', payload: {key: 'admin', status: true} }

View File

@ -326,7 +326,7 @@ describe('store/queue', () => {
action: store.actions.shuffle, action: store.actions.shuffle,
params: {state: {currentIndex: 1, tracks: tracks}}, params: {state: {currentIndex: 1, tracks: tracks}},
expectedMutations: [ expectedMutations: [
{ type: 'player/currentTime', payload: 0 , options: {root: true}}, { type: 'player/currentTime', payload: 0, options: {root: true}},
{ type: 'tracks', payload: [] } { type: 'tracks', payload: [] }
], ],
expectedActions: [ expectedActions: [