import { Injectable } from '@angular/core'; import {ApiService} from './api.service'; import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router'; import {LocalStorageService} from 'angular-2-local-storage'; import {Observable} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class LoginService implements CanActivate { private pathPermissions = [ {path: 'templates', permission: 'maintain'}, {path: 'users', permission: 'admin'} ]; readonly levels = [ 'read', 'write', 'maintain', 'dev', 'admin' ]; private loggedIn; private level; constructor( private api: ApiService, private storage: LocalStorageService, private router: Router ) { } login(username = '', password = '') { return new Promise(resolve => { if (username !== '' || password !== '') { // some credentials given let credentials: string[]; const credentialString: string = this.storage.get('basicAuth'); if (credentialString) { // found stored credentials credentials = atob(credentialString).split(':'); } else { credentials = ['', '']; } if (username !== '' && password !== '') { // all credentials given this.storage.set('basicAuth', btoa(username + ':' + password)); } else if (username !== '') { // username given this.storage.set('basicAuth', btoa(username + ':' + credentials[1])); } else if (password !== '') { // password given this.storage.set('basicAuth', btoa(credentials[0] + ':' + password)); } } this.api.get('/authorized', (data: any, error) => { if (!error) { if (data.status === 'Authorization successful') { this.loggedIn = true; this.level = data.level; resolve(true); } else { this.loggedIn = false; this.storage.remove('basicAuth'); resolve(false); } } else { this.loggedIn = false; this.storage.remove('basicAuth'); resolve(false); } }); }); } logout() { this.storage.remove('basicAuth'); this.loggedIn = false; } canActivate(route: ActivatedRouteSnapshot = null, state: RouterStateSnapshot = null): Observable { return new Observable(observer => { new Promise(resolve => { if (this.loggedIn === undefined) { this.login().then(res => { resolve(res); }); } else { resolve(this.loggedIn); } }).then(res => { const pathPermission = this.pathPermissions.find(e => e.path.indexOf(route.url[0].path) >= 0); const ok = res && !pathPermission || this.is(pathPermission.permission); // check if level is permitted for path observer.next(ok); observer.complete(); if (!ok) { this.router.navigate(['/']); } }); }); } get isLoggedIn() { return this.loggedIn; } is(level) { return this.levels.indexOf(this.level) >= this.levels.indexOf(level); } get username() { return atob(this.storage.get('basicAuth')).split(':')[0]; } }