persistant storage for vuex, logging instead of console.log, profile support
This commit is contained in:
18
src/$log.d.ts
vendored
Normal file
18
src/$log.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import Vue from 'vue';
|
||||
/*
|
||||
Type augmentation for log plugin for typescript
|
||||
https://vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins
|
||||
https://github.com/justinkames/vuejs-logger/issues/24
|
||||
Tobias
|
||||
*/
|
||||
declare module 'vue/types/vue' {
|
||||
export interface VueConstructor<V extends Vue = Vue> {
|
||||
$log: {
|
||||
debug(...args: any[]): void;
|
||||
info(...args: any[]): void;
|
||||
warn(...args: any[]): void;
|
||||
error(...args: any[]): void;
|
||||
fatal(...args: any[]): void;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link> |
|
||||
<router-link to="/login">Login</router-link>
|
||||
<router-link to="/login">Login</router-link> |
|
||||
<router-link to="/profile">Profile</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
|
||||
@@ -1,46 +1,51 @@
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
|
||||
const API_URL = 'http://localhost:5443/api';
|
||||
|
||||
export function fetchSurveys () {
|
||||
return axios.get(`${API_URL}/surveys/`)
|
||||
export function fetchSurveys() {
|
||||
return axios.get(`${API_URL}/surveys/`);
|
||||
}
|
||||
|
||||
export function fetchSurvey (surveyId: string) {
|
||||
return axios.get(`${API_URL}/surveys/${surveyId}/`)
|
||||
export function fetchSurvey(surveyId: string) {
|
||||
return axios.get(`${API_URL}/surveys/${surveyId}/`);
|
||||
}
|
||||
|
||||
export function saveSurveyResponse (surveyResponse: any) {
|
||||
return axios.put(`${API_URL}/surveys/${surveyResponse.id}/`, surveyResponse)
|
||||
export function saveSurveyResponse(surveyResponse: any) {
|
||||
return axios.put(`${API_URL}/surveys/${surveyResponse.id}/`, surveyResponse);
|
||||
}
|
||||
|
||||
export function postNewSurvey (survey: any, jwt: any) {
|
||||
return axios.post(`${API_URL}/surveys/`, survey, { headers: { Authorization: `Bearer ${jwt}` } })
|
||||
export function postNewSurvey(survey: any, jwt: any) {
|
||||
return axios.post(`${API_URL}/surveys/`, survey, { headers: { Authorization: `Bearer ${jwt}` } });
|
||||
}
|
||||
|
||||
export function authenticate (userData: any) {
|
||||
return axios.post(`${API_URL}/auth/login`, userData)
|
||||
export function authenticate(userData: any) {
|
||||
return axios.post(`${API_URL}/auth/login`, userData);
|
||||
}
|
||||
|
||||
export function register (userData: any) {
|
||||
return axios.post(`${API_URL}/auth/register`, userData)
|
||||
export function register(userData: any) {
|
||||
return axios.post(`${API_URL}/auth/register`, userData);
|
||||
}
|
||||
|
||||
// This function probably isn't really useful here, as a user must be redirected to the actual OIDC provider.
|
||||
// -> So login involves user interaction through the frontend (and not just API calls).
|
||||
export function oidc_login (redirection_url: any) {
|
||||
return axios.get(`${API_URL}/auth/oidc`, redirection_url)
|
||||
export function oidc_login(redirectionUrl: any) {
|
||||
return axios.get(`${API_URL}/auth/oidc`, redirectionUrl);
|
||||
}
|
||||
|
||||
export function getFreshToken (refresh_token: any) {
|
||||
return axios.get(`${API_URL}/auth/fresh`, refresh_token)
|
||||
export function getFreshToken(refreshToken: any) {
|
||||
return axios.get(`${API_URL}/auth/fresh`, refreshToken);
|
||||
}
|
||||
|
||||
export function getProviders () {
|
||||
return axios.get(`${API_URL}/auth/providers`)
|
||||
export function getProviders() {
|
||||
return axios.get(`${API_URL}/auth/providers`);
|
||||
}
|
||||
|
||||
export function fetchUsers (jwt: any) {
|
||||
console.log("JWT: " + jwt);
|
||||
return axios.get(`${API_URL}/v1/user`, { headers: { Authorization: `Bearer ${jwt}` } })
|
||||
export function fetchUsers(jwt: any) {
|
||||
return axios.get(`${API_URL}/v1/user`, { headers: { Authorization: `Bearer ${jwt}` } });
|
||||
}
|
||||
|
||||
export function fetchProfile(jwt: any) {
|
||||
Vue.$log.debug("JWT: "+ jwt);
|
||||
return axios.get(`${API_URL}/v1/user/profile`, { headers: { Authorization: `Bearer ${jwt}` } });
|
||||
}
|
||||
|
||||
58
src/components/Profile.vue
Normal file
58
src/components/Profile.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<!-- components/Profile.vue -->
|
||||
<template>
|
||||
<div>
|
||||
<section class="hero is-primary">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h2 class="title">Profile</h2>
|
||||
<p>{{profile.id}}</p>
|
||||
<p class="subtitle error-msg">{{ errorMsg }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { EventBus } from '@/utils'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
email: '',
|
||||
errorMsg: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
authenticate () {
|
||||
this.$store.dispatch('login', { email: this.email, password: this.password })
|
||||
.then(() => this.$router.push('/'));
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$log.debug("Profile: mounting...");
|
||||
EventBus.$on('failedLoadingProfile', (msg) => {
|
||||
this.errorMsg = msg;
|
||||
});
|
||||
this.$store.dispatch('loadProfile');
|
||||
|
||||
|
||||
},
|
||||
beforeDestroy () {
|
||||
EventBus.$off('failedLoadingProfile');
|
||||
},
|
||||
computed: {
|
||||
profile () {
|
||||
return this.$store.state.profile;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.error-msg {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
19
src/main.ts
19
src/main.ts
@@ -4,16 +4,31 @@ import VueAxios from 'vue-axios';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
import VueCookies from 'vue-cookies'
|
||||
import VueCookies from 'vue-cookies';
|
||||
import VueLogger from 'vuejs-logger';
|
||||
import i18n from '@/plugins/i18n';
|
||||
// @ts-ignore
|
||||
import FlagIcon from 'vue-flag-icon';
|
||||
// following is to avoid missing type definitions
|
||||
// const FlagIcon = require('vue-flag-icon');
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const options = {
|
||||
isEnabled: true,
|
||||
// logLevel : isProduction ? 'error' : 'debug',
|
||||
logLevel : 'debug',
|
||||
stringifyArguments : false,
|
||||
showLogLevel : true,
|
||||
showMethodName : true,
|
||||
separator: '|',
|
||||
showConsoleColors: true
|
||||
};
|
||||
|
||||
Vue.use(VueLogger, options);
|
||||
Vue.use(VueAxios, axios);
|
||||
Vue.use(FlagIcon);
|
||||
Vue.use(VueCookies)
|
||||
Vue.use(VueCookies);
|
||||
|
||||
// setup fake backend
|
||||
// import { configureFakeBackend } from './helpers';
|
||||
|
||||
@@ -6,6 +6,7 @@ import NotFound from './views/NotFound.vue';
|
||||
import Survey from '@/components/Survey.vue';
|
||||
import NewSurvey from '@/components/NewSurvey.vue';
|
||||
import Login from '@/components/Login.vue';
|
||||
import Profile from '@/components/Profile.vue';
|
||||
import store from '@/store';
|
||||
|
||||
Vue.use(Router);
|
||||
@@ -22,6 +23,7 @@ export const router = new Router({
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
@@ -47,9 +49,9 @@ export const router = new Router({
|
||||
}
|
||||
},
|
||||
}, {
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: Login,
|
||||
path: '/profile',
|
||||
name: 'Profile',
|
||||
component: Profile,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
|
||||
71
src/store.ts
71
src/store.ts
@@ -1,6 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
|
||||
import createPersistedState from 'vuex-persistedstate'
|
||||
|
||||
// imports of AJAX functions will go here
|
||||
import {
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
postNewSurvey,
|
||||
authenticate,
|
||||
register,
|
||||
oidc_login, fetchUsers, getFreshToken
|
||||
oidc_login, fetchUsers, getFreshToken, fetchProfile,
|
||||
} from '@/api';
|
||||
import { isValidJwt, EventBus } from '@/utils';
|
||||
|
||||
@@ -22,7 +22,7 @@ const state = {
|
||||
surveys: [],
|
||||
loginProviders: [],
|
||||
currentSurvey: {},
|
||||
user: {},
|
||||
profile: {},
|
||||
users: [],
|
||||
access_token: '',
|
||||
refresh_token: '',
|
||||
@@ -51,51 +51,64 @@ const actions = {
|
||||
loadUsers(context: any) {
|
||||
return fetchUsers(context.state.access_token)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
console.log(response.data);
|
||||
Vue.$log.debug(response);
|
||||
Vue.$log.debug(response.data);
|
||||
context.commit('setUsers', { users: response.data });
|
||||
EventBus.$emit('usersLoaded', response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Error loading users!', error);
|
||||
Vue.$log.warn('Error loading users!', error);
|
||||
EventBus.$emit('failedLoadingUsers', error);
|
||||
});
|
||||
},
|
||||
loadProfile(context: any) {
|
||||
return fetchProfile(context.state.access_token)
|
||||
.then((response) => {
|
||||
Vue.$log.debug(response);
|
||||
Vue.$log.debug(response.data);
|
||||
context.commit('setProfile', { profile: response.data });
|
||||
EventBus.$emit('profileLoaded', response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
Vue.$log.warn('Error loading profile!', error);
|
||||
EventBus.$emit('failedLoadingProfile', error);
|
||||
});
|
||||
},
|
||||
loadLoginProviders(context: any) {
|
||||
return getProviders()
|
||||
.then((response) => {
|
||||
context.commit('setLoginProviderData', {providers: response.data});
|
||||
EventBus.$emit('loginProvidersLoaded', response.data);
|
||||
})
|
||||
});
|
||||
},
|
||||
login(context: any, userData: any) {
|
||||
context.commit('setUserData', { userData });
|
||||
return authenticate(userData)
|
||||
.then((response) => context.commit('setJwtToken', { tokens: response.data }))
|
||||
.catch((error) => {
|
||||
console.log('Error Authenticating: ', error);
|
||||
Vue.$log.warn('Error Authenticating: ', error);
|
||||
EventBus.$emit('failedAuthentication', error);
|
||||
});
|
||||
},
|
||||
oidc_login(context: any, redirection_url: any) {
|
||||
//context.commit('setUserData', { userData });
|
||||
return oidc_login(redirection_url)
|
||||
oidc_login(context: any, redirectionUrl: any) {
|
||||
// context.commit('setUserData', { userData });
|
||||
return oidc_login(redirectionUrl)
|
||||
.then((response) => context.commit('setJwtToken', { tokens: response.data }))
|
||||
.catch((error) => {
|
||||
console.log('Error Authenticating: ', error);
|
||||
Vue.$log.warn('Error Authenticating: ', error);
|
||||
EventBus.$emit('failedAuthentication', error);
|
||||
});
|
||||
},
|
||||
refreshToken(context: any) {
|
||||
//context.commit('setUserData', { userData });
|
||||
// context.commit('setUserData', { userData });
|
||||
return getFreshToken(context.state.refresh_token)
|
||||
.then((response) => context.commit('setTokens', { tokens: response.data }))
|
||||
.catch((error) => {
|
||||
console.log('Error Refreshing token: ', error);
|
||||
Vue.$log.warn('Error Refreshing token: ', error);
|
||||
EventBus.$emit('failedRefreshingToken', error);
|
||||
});
|
||||
},
|
||||
storeTokens(context: any, tokens: any){
|
||||
storeTokens(context: any, tokens: any) {
|
||||
context.commit('setTokens', {tokens});
|
||||
EventBus.$emit('storedTokens');
|
||||
},
|
||||
@@ -104,7 +117,7 @@ const actions = {
|
||||
return register(userData)
|
||||
.then(context.dispatch('login', userData))
|
||||
.catch((error) => {
|
||||
console.log('Error Registering: ', error);
|
||||
Vue.$log.warn('Error Registering: ', error);
|
||||
EventBus.$emit('failedRegistering: ', error);
|
||||
});
|
||||
},
|
||||
@@ -138,33 +151,38 @@ const mutations = {
|
||||
}
|
||||
}
|
||||
},
|
||||
setLoginProviderData(sState: any, payload: any){
|
||||
console.log("got loginProviders = ", payload);
|
||||
setLoginProviderData(sState: any, payload: any) {
|
||||
Vue.$log.debug('got loginProviders = ', payload);
|
||||
sState.loginProviders = payload.providers;
|
||||
},
|
||||
// probably old ...
|
||||
setUserData(sState: any, payload: any) {
|
||||
console.log('setUserData payload = ', payload);
|
||||
Vue.$log.debug('setUserData payload = ', payload);
|
||||
sState.userData = payload.userData;
|
||||
},
|
||||
setProfile(sState: any, payload: any) {
|
||||
Vue.$log.debug('setProfile payload = ', payload);
|
||||
sState.profile = payload.profile;
|
||||
},
|
||||
setJwtToken(sState: any, payload: any) {
|
||||
console.log('setJwtToken payload = ', payload);
|
||||
Vue.$log.debug('setJwtToken payload = ', payload);
|
||||
localStorage.tokens = payload.tokens;
|
||||
sState.jwt = payload.tokens.access_token;
|
||||
sState.jwt_refresh_token = payload.tokens.refresh_token;
|
||||
},
|
||||
setTokens(sState: any, payload:any){
|
||||
console.log('setTokens payload = ', payload);
|
||||
setTokens(sState: any, payload: any) {
|
||||
Vue.$log.debug('setTokens payload = ', payload);
|
||||
sState.access_token = payload.tokens.access_token;
|
||||
sState.refresh_token = payload.tokens.refresh_token;
|
||||
console.log(sState.access_token);
|
||||
console.log(sState.access_token);
|
||||
}
|
||||
Vue.$log.debug(sState.access_token);
|
||||
Vue.$log.debug(sState.access_token);
|
||||
},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
// reusable data accessors
|
||||
isAuthenticated(sState: any) {
|
||||
return isValidJwt(sState.jwt.token);
|
||||
return isValidJwt(sState.access_token);
|
||||
},
|
||||
getLoginProviders(sState: any) {
|
||||
return sState.loginProviders;
|
||||
@@ -176,6 +194,7 @@ const store = new Vuex.Store({
|
||||
actions,
|
||||
mutations,
|
||||
getters,
|
||||
plugins: [createPersistedState()],
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
||||
Reference in New Issue
Block a user