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;
}
}