81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import {
|
|
Action,
|
|
Module,
|
|
Mutation,
|
|
MutationAction,
|
|
VuexModule
|
|
} from 'vuex-module-decorators';
|
|
import JwtDecode from 'jwt-decode';
|
|
import { LoginSubmit } from '@/models';
|
|
import api from '@/services/pm-api-client';
|
|
import { logService } from '@/services/logging';
|
|
import { userStore, measureStore } from '@/store';
|
|
|
|
const SESSION_KEY = 'session-token';
|
|
|
|
const logger = logService.getLogger('/store-modules/auth');
|
|
|
|
export interface SessionToken {
|
|
iat: string;
|
|
exp: number;
|
|
sub: string;
|
|
}
|
|
|
|
@Module({ namespaced: true, name: 'auth' })
|
|
export class AuthStoreModule extends VuexModule {
|
|
public authToken: string | null = null;
|
|
|
|
@Action({ rawError: true })
|
|
public async login(creds: LoginSubmit): Promise<string> {
|
|
const authToken = await api.createAuthToken(creds); // API will cache this token
|
|
|
|
// this should be guaranteed by the server (redirect HTTP -> HTTPS)
|
|
// but we'll do a sanity check just to make sure.
|
|
if (window.location.protocol === 'https:' ||
|
|
process.env.NODE_ENV === 'development') { // allow in dev
|
|
localStorage.setItem(SESSION_KEY, authToken);
|
|
}
|
|
|
|
logger.trace('User login successful.');
|
|
this.context.commit('SET_TOKEN', authToken);
|
|
|
|
this.loadInitialState();
|
|
return authToken;
|
|
}
|
|
|
|
@MutationAction({ mutate: ['authToken'], rawError: true })
|
|
public async logout() { return { authToken: null }; }
|
|
|
|
@Action({ rawError: true })
|
|
public async findLocalToken(): Promise<string> {
|
|
const encodedToken = localStorage.getItem(SESSION_KEY);
|
|
if (!encodedToken) {
|
|
logger.trace('encodedToken was falsey');
|
|
throw new Error('Could not find an existing auth token.');
|
|
}
|
|
|
|
const token = JwtDecode<SessionToken>(encodedToken);
|
|
if ((new Date(token.exp * 1000)) < new Date()) {
|
|
logger.trace('token has expired: token.exp = ' + (token.exp * 1000));
|
|
throw new Error ('The existing auth token has expired.');
|
|
}
|
|
|
|
api.setAuthToken(encodedToken);
|
|
this.context.commit('SET_TOKEN', encodedToken);
|
|
|
|
this.loadInitialState();
|
|
return encodedToken;
|
|
}
|
|
|
|
@Action
|
|
public async loadInitialState() {
|
|
userStore.fetchUser();
|
|
measureStore.fetchAllMeasures();
|
|
}
|
|
|
|
@Mutation private SET_TOKEN(t: string) {
|
|
logger.info('SET_TOKEN called');
|
|
this.authToken = t;
|
|
}
|
|
}
|