Skip to content

Commit

Permalink
feat: ✨ User sessions are now persisted and refreshed automatically.
Browse files Browse the repository at this point in the history
Fixes #15
  • Loading branch information
EricLambrecht committed Oct 13, 2019
1 parent 07fde37 commit 5960f2a
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div id="app" v-resize:throttle.300="onResize">
<template v-if="$route.matched.length">
<router-view />
<router-view :key="$route.fullPath" />
</template>
<template v-else>
<logged-out-window v-if="!hasAccess" />
Expand Down
36 changes: 0 additions & 36 deletions src/components/auth/AuthTokenRetrieval.vue

This file was deleted.

13 changes: 13 additions & 0 deletions src/components/core/UnknownRoute.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
$END$
</template>

<script>
export default {
name: "UnknownRoute"
}
</script>

<style scoped>
</style>
68 changes: 68 additions & 0 deletions src/components/init/AppInitializer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<div class="loading-screen">
<b-square-image :url="logoUrl" :size="140" />
<b-headline level="1" class="headline">
Spotify Magician
</b-headline>
<b-text class="status">
{{ status }}
</b-text>
</div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
import logoUrl from '../../assets/logo.png';
export default {
name: 'AppInitializer',
data: () => ({
logoUrl,
status: '',
}),
computed: {
...mapGetters({
hasAccess: 'user/hasAccess',
}),
},
async mounted() {
try {
this.status = 'Authenticating...';
await this.$store.dispatch('user/requestToken');
await this.$router.replace({ name: 'home' });
} catch (e) {
if (e.trigger_login) {
await this.$router.replace({ name: 'login' });
} else {
this.addToast({ message: e.message, type: 'error' });
throw new Error(e);
}
}
},
methods: {
...mapActions('app', [
'addToast',
]),
},
};
</script>

<style lang="scss" scoped>
.loading-screen {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 80vh;
text-align: center;
font-family: var(--font-family);
.headline {
margin-bottom: 20px;
}
.status {
font-size: 18px;
}
}
</style>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="logged-out-window">
<div class="login-screen">
<b-square-image :url="logoUrl" :size="140" />
<b-headline level="1" class="app-name">
Spotify Magician
Expand Down Expand Up @@ -31,14 +31,14 @@ export default {
+ 'response_type=code&'
+ `state=${this.authState}`
+ `scope=${getScopes()}&`
+ `redirect_uri=${encodeURIComponent(`${window.location.protocol}//${window.location.host}/requestToken`)}`;
+ `redirect_uri=${encodeURIComponent(`${window.location.protocol}//${window.location.host}/init`)}`;
},
},
};
</script>

<style lang="scss" scoped>
.logged-out-window {
.login-screen {
display: flex;
flex-direction: column;
justify-content: center;
Expand Down
21 changes: 18 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import * as Integrations from '@sentry/integrations';

import App from './App';
import store from './store';
import AuthTokenRetrieval from './components/auth/AuthTokenRetrieval';
import AppInitializer from './components/init/AppInitializer';
import LoggedOutWindow from './components/init/LoginScreen';
import MainWindow from './components/core/MainWindow';

import versionFile from './version.json';

// Register base components globally
import './components/_base/_setup';

Expand All @@ -31,9 +32,23 @@ const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/requestToken', component: AuthTokenRetrieval },
{
path: '/',
name: 'home',
component: MainWindow,
beforeEnter(to, from, next) {
if (!store.getters['user/hasAccess']) {
next('/init');
} else {
next();
}
},
},
{ path: '/login', component: LoggedOutWindow, name: 'login' },
{ path: '/init', component: AppInitializer, name: 'init' },
{
path: '/logout',
name: 'logout',
// beforeEnter(to, from, next) {
// console.warn('logging out is not supported yet');
// next('/');
Expand Down
8 changes: 7 additions & 1 deletion src/store/user/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default {
},
body: JSON.stringify({
code,
redirect_uri: `${window.location.protocol}//${window.location.host}/requestToken`,
redirect_uri: `${window.location.protocol}//${window.location.host}/init`,
}),
});
} else {
Expand All @@ -35,6 +35,12 @@ export default {
});
}

if (result.status === 400) {
const error = new Error('No refresh token');
error.trigger_login = true;
throw error;
}

const tokenData = await result.json();

if (!tokenData.error) {
Expand Down

1 comment on commit 5960f2a

@EricLambrecht
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also includes work towards #74 ("Loading Screen")

Please sign in to comment.