#54 user accounts - vuex store and localStorage
This commit is contained in:
parent
7ac9348396
commit
7453a26773
|
@ -39,50 +39,106 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
computed: {
|
||||
...mapState([
|
||||
'user',
|
||||
]),
|
||||
links() {
|
||||
const links = [];
|
||||
links.push({ link: '/', icon: 'home', text: this.$t('home.header'), textLong: this.$t('home.headerLong'), extra: ['all', this.config.template.any.route] });
|
||||
|
||||
links.push({
|
||||
link: '/',
|
||||
icon: 'home',
|
||||
text: this.$t('home.header'),
|
||||
textLong: this.$t('home.headerLong'),
|
||||
extra: ['all', this.config.template.any.route],
|
||||
});
|
||||
|
||||
if (this.config.sources.enabled) {
|
||||
links.push({ link: '/' + this.config.sources.route, icon: 'books', text: this.$t('sources.header'), textLong: this.$t('sources.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.sources.route,
|
||||
icon: 'books',
|
||||
text: this.$t('sources.header'),
|
||||
textLong: this.$t('sources.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.nouns.enabled) {
|
||||
links.push({ link: '/' + this.config.nouns.route, icon: 'atom-alt', text: this.$t('nouns.header'), textLong: this.$t('nouns.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.nouns.route,
|
||||
icon: 'atom-alt',
|
||||
text: this.$t('nouns.header'),
|
||||
textLong: this.$t('nouns.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.names.enabled) {
|
||||
links.push({ link: '/' + this.config.names.route, icon: 'signature', text: this.$t('names.header'), textLong: this.$t('names.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.names.route,
|
||||
icon: 'signature',
|
||||
text: this.$t('names.header'),
|
||||
textLong: this.$t('names.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.faq.enabled) {
|
||||
links.push({ link: '/' + this.config.faq.route, icon: 'map-marker-question', text: this.$t('faq.header'), textLong: this.$t('faq.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.faq.route,
|
||||
icon: 'map-marker-question',
|
||||
text: this.$t('faq.header'),
|
||||
textLong: this.$t('faq.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.links.enabled) {
|
||||
links.push({ link: '/' + this.config.links.route, icon: 'bookmark', text: this.$t('links.header'), textLong: this.$t('links.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.links.route,
|
||||
icon: 'bookmark',
|
||||
text: this.$t('links.header'),
|
||||
textLong: this.$t('links.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.people.enabled) {
|
||||
links.push({ link: '/' + this.config.people.route, icon: 'user-friends', text: this.$t('people.header'), textLong: this.$t('people.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.people.route,
|
||||
icon: 'user-friends',
|
||||
text: this.$t('people.header'),
|
||||
textLong: this.$t('people.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.english.enabled) {
|
||||
links.push({ link: '/' + this.config.english.route, icon: 'globe-americas', text: this.$t('english.header'), textLong: this.$t('english.headerLong') });
|
||||
links.push({
|
||||
link: '/' + this.config.english.route,
|
||||
icon: 'globe-americas',
|
||||
text: this.$t('english.header'),
|
||||
textLong: this.$t('english.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.contact.enabled) {
|
||||
links.push({ link: '/' + this.config.contact.route, icon: 'comment-alt-smile', text: this.$t('contact.header')});
|
||||
links.push({
|
||||
link: '/' + this.config.contact.route,
|
||||
icon: 'comment-alt-smile',
|
||||
text: this.$t('contact.header'),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.config.user.enabled) {
|
||||
links.push({ link: '/' + this.config.user.route, icon: 'user', text: this.$t('user.header'), textLong: this.$t('user.headerLong')});
|
||||
links.push({
|
||||
link: '/' + this.config.user.route,
|
||||
icon: 'user',
|
||||
text: this.user ? '@' + this.user.username : this.$t('user.header'),
|
||||
textLong: this.user ? '@' + this.user.username : this.$t('user.headerLong'),
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
links,
|
||||
};
|
||||
return links;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isActiveRoute(link) {
|
||||
|
|
|
@ -44,6 +44,7 @@ export default {
|
|||
plugins: [
|
||||
{ src: '~/plugins/vue-matomo.js', ssr: false },
|
||||
{ src: '~/plugins/globals.js' },
|
||||
{ src: '~/plugins/auth.js' },
|
||||
],
|
||||
components: true,
|
||||
buildModules: [],
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { Session } from "../src/helpers";
|
||||
|
||||
export default ({store}) => {
|
||||
if (Session.isAvailable()) {
|
||||
const token = Session.get('token');
|
||||
if (token) {
|
||||
store.commit('setToken', token);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
<T>user.headerLong</T>
|
||||
</h2>
|
||||
|
||||
<section>
|
||||
<div v-if="error" class="alert alert-danger">
|
||||
<p class="mb-0">
|
||||
<Icon v="exclamation-triangle"/>
|
||||
|
@ -12,8 +13,13 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="payload && payload.authenticated">
|
||||
Logged in as <strong>{{payload.uid}}</strong>.
|
||||
<div v-if="$store.state.user">
|
||||
Logged in as <strong>@{{$store.state.user.username}}</strong>.
|
||||
|
||||
<button class="btn btn-outline-secondary btn-sm" @click="logout">
|
||||
<Icon v="sign-out"/>
|
||||
Log out
|
||||
</button>
|
||||
</div>
|
||||
<div v-else-if="token === null">
|
||||
<form @submit.prevent="login">
|
||||
|
@ -52,11 +58,7 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div v-if="token">
|
||||
<pre><code>{{JSON.stringify(token)}}</code></pre>
|
||||
<pre>{{JSON.stringify(payload, null, 4)}}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -80,6 +82,8 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
this.$store.commit('setToken', this.token);
|
||||
|
||||
return jwt.verify(this.token, process.env.PUBLIC_KEY, {
|
||||
algorithm: 'RS256',
|
||||
audience: process.env.BASE_URL,
|
||||
|
@ -107,14 +111,19 @@
|
|||
|
||||
const response = await this.$axios.$post(url, data, options);
|
||||
|
||||
if (response.error) {
|
||||
this.error = response.error;
|
||||
this.usernameOrEmail = '';
|
||||
this.code = '';
|
||||
|
||||
if (response.error) {
|
||||
this.error = response.error;
|
||||
return;
|
||||
}
|
||||
|
||||
this.token = response.token;
|
||||
},
|
||||
logout() {
|
||||
this.token = null;
|
||||
this.$store.commit('setToken', null);
|
||||
}
|
||||
},
|
||||
head() {
|
||||
|
|
|
@ -72,3 +72,27 @@ export const makeId = (length, characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
export class Session {
|
||||
static isAvailable() {
|
||||
return typeof localStorage !== 'undefined';
|
||||
}
|
||||
|
||||
static set(key, value) {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
static get(key) {
|
||||
const value = localStorage.getItem(key);
|
||||
|
||||
return key === null ? null : JSON.parse(value);
|
||||
}
|
||||
|
||||
static has(key) {
|
||||
return localStorage.getItem(key) !== null;
|
||||
}
|
||||
|
||||
static remove(key) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import { Session } from '../src/helpers';
|
||||
|
||||
export const state = () => ({
|
||||
token: null,
|
||||
user: null,
|
||||
})
|
||||
|
||||
export const mutations = {
|
||||
setToken(state, token) {
|
||||
if (!token) {
|
||||
state.token = null;
|
||||
state.user = null;
|
||||
Session.remove('token');
|
||||
return;
|
||||
}
|
||||
|
||||
const user = jwt.verify(token, process.env.PUBLIC_KEY, {
|
||||
algorithm: 'RS256',
|
||||
audience: process.env.BASE_URL,
|
||||
issuer: process.env.BASE_URL,
|
||||
});
|
||||
|
||||
if (user && user.authenticated) {
|
||||
state.token = token;
|
||||
state.user = user;
|
||||
Session.set('token', token);
|
||||
return;
|
||||
}
|
||||
|
||||
state.token = null;
|
||||
state.user = null;
|
||||
Session.remove('token');
|
||||
}
|
||||
}
|
Reference in New Issue