Select Git revision
ExerciceRoutes.ts
SessionManager.ts 4.49 KiB
import * as jwt from 'jsonwebtoken';
import User from '../models/User';
import LocalConfig from '../config/LocalConfig';
import LocalConfigKeys from '../types/LocalConfigKeys';
import axios, { AxiosError } from 'axios';
import HttpManager from './HttpManager';
import ora from 'ora';
import Permissions from '../types/Permissions';
import ApiRoutes from '../types/ApiRoutes';
import DojoBackendManager from './DojoBackendManager';
import { StatusCodes } from 'http-status-codes';
class SessionManager {
private _token: string | null = null;
public profile: User = new User();
constructor() { }
private static _instance: SessionManager;
public static get instance(): SessionManager {
if ( !SessionManager._instance ) {
SessionManager._instance = new SessionManager();
}
return SessionManager._instance;
}
get isLogged(): boolean {
return this._token !== null;
}
get token(): string {
return this._token || '';
}
set token(token: string) {
this._token = token;
try {
const payload = jwt.decode(token);
if ( payload && typeof payload === 'object' && payload.profile ) {
this.profile = User.createFromJson(payload.profile);
}
} catch ( error ) {
this.profile = new User();
}
LocalConfig.updateConfig(LocalConfigKeys.API_TOKEN, token);
}
async login(user: string, password: string) {
const spinner: ora.Ora = ora('Logging in').start();
try {
this.profile = new User();
const response = await axios.post(DojoBackendManager.getApiUrl(ApiRoutes.LOGIN), {
user : user,
password: password
});
spinner.succeed('Logged in');
} catch ( error ) {
if ( error instanceof AxiosError ) {
if ( error.response ) {
if ( error.response.status === StatusCodes.NOT_FOUND ) {
spinner.fail('User not found or password incorrect');
} else {
spinner.fail(`Login error: ${ error.response.statusText }`);
}
}
} else {
spinner.fail(`Login error: ${ error }`);
}
}
}
logout() {
this.token = '';
}
checkPermissions(verbose: boolean = true, ...checkPermissions: Array<string>): Permissions {
const hasPermission = (permissionPredicate: () => boolean, verboseText: string): boolean => {
const spinner: ora.Ora = ora({
text : verboseText,
indent: 8
});
let isAllowed: boolean = this.profile.id !== -1 && permissionPredicate();
if ( verbose ) {
spinner.start();
isAllowed ? spinner.succeed() : spinner.fail();
}
return isAllowed;
};
return {
teachingStaff: checkPermissions.length == 0 || checkPermissions.includes('teachingStaff') ? hasPermission(() => this.profile.isTeachingStaff, 'Teaching staff permissions') : false,
student : checkPermissions.length == 0 || checkPermissions.includes('student') ? hasPermission(() => true, 'Student permissions') : false
};
}
async testSession(verbose: boolean = true, checkPermissions: Array<string> = []): Promise<false | Permissions> {
if ( verbose ) {
ora('Checking Dojo session: ').start().info();
}
HttpManager.handleCommandErrors = false;
const spinner: ora.Ora = ora({
text : `Testing Dojo session`,
indent: 4
});
if ( verbose ) {
spinner.start();
}
try {
await axios.get(DojoBackendManager.getApiUrl(ApiRoutes.TEST_SESSION), {});
if ( verbose ) {
spinner.succeed(`The session is valid`);
}
} catch ( error ) {
if ( verbose ) {
spinner.fail(`The session is invalid`);
}
return false;
}
return this.checkPermissions(verbose, ...checkPermissions);
}
}
export default SessionManager.instance;