Moved from tslint to eslint as tslint was depreciated.
Added prettier and also prettied all the typescript files using prettier ESLint is using the AirBnB rules which are the most strict to lint the files.
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {AuthGuardService} from './auth-guard.service';
|
||||
import { AuthGuardService } from './auth-guard.service';
|
||||
|
||||
describe('AuthGuardService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [AuthGuardService]
|
||||
providers: [AuthGuardService],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
|
||||
import {AuthService} from './auth.service';
|
||||
import {ToasterService} from '../core/toaster.service';
|
||||
import { AuthService } from './auth.service';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private authService: AuthService,
|
||||
private toaster: ToasterService
|
||||
) {
|
||||
}
|
||||
private toaster: ToasterService,
|
||||
) {}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
const user = this.authService.user;
|
||||
const permission = (route.data['permission'] === undefined) ? route.data['permission'] : route.data['permission']
|
||||
.replace(/ /g, '-')
|
||||
.toLowerCase();
|
||||
const permission =
|
||||
route.data['permission'] === undefined
|
||||
? route.data['permission']
|
||||
: route.data['permission'].replace(/ /g, '-').toLowerCase();
|
||||
if (!user) {
|
||||
// not logged in so redirect to login page with the return url
|
||||
this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
|
||||
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
|
||||
return false;
|
||||
}
|
||||
if (permission !== undefined && user.perms.indexOf(permission) === -1) {
|
||||
@ -29,6 +29,5 @@ export class AuthGuard implements CanActivate {
|
||||
}
|
||||
// logged in so return true
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {AuthService} from './auth.service';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [AuthService]
|
||||
providers: [AuthService],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ const loginUrl = '/token';
|
||||
const refreshUrl = '/refresh';
|
||||
const JWT_USER = 'JWT_USER';
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthService {
|
||||
private currentUserSubject: BehaviorSubject<User>;
|
||||
public currentUser: Observable<User>;
|
||||
@ -57,23 +57,31 @@ export class AuthService {
|
||||
formData.append('password', password);
|
||||
formData.append('otp', otp);
|
||||
formData.append('grant_type', 'password');
|
||||
return this.http.post<any>(loginUrl, formData)
|
||||
.pipe(map(u => u.access_token))
|
||||
.pipe(map(u => this.parseJwt(u)))
|
||||
.pipe(map(user => {
|
||||
// store user details and jwt token in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem(JWT_USER, JSON.stringify(user));
|
||||
this.currentUserSubject.next(user);
|
||||
return user;
|
||||
}));
|
||||
return this.http
|
||||
.post<any>(loginUrl, formData)
|
||||
.pipe(map((u) => u.access_token))
|
||||
.pipe(map((u) => this.parseJwt(u)))
|
||||
.pipe(
|
||||
map((user) => {
|
||||
// store user details and jwt token in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem(JWT_USER, JSON.stringify(user));
|
||||
this.currentUserSubject.next(user);
|
||||
return user;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
parseJwt(token): User {
|
||||
const base64Url = token.split('.')[1];
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
const jsonPayload = decodeURIComponent(
|
||||
atob(base64)
|
||||
.split('')
|
||||
.map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
})
|
||||
.join(''),
|
||||
);
|
||||
|
||||
const decoded = JSON.parse(jsonPayload);
|
||||
return new User({
|
||||
@ -82,12 +90,12 @@ export class AuthService {
|
||||
lockedOut: decoded.lockedOut,
|
||||
perms: decoded.scopes,
|
||||
access_token: token,
|
||||
exp: decoded.exp
|
||||
exp: decoded.exp,
|
||||
});
|
||||
}
|
||||
|
||||
needsRefreshing(): boolean {
|
||||
return Date.now() > (this.user.exp - (environment.ACCESS_TOKEN_REFRESH_MINUTES * 60)) * 1000;
|
||||
return Date.now() > (this.user.exp - environment.ACCESS_TOKEN_REFRESH_MINUTES * 60) * 1000;
|
||||
}
|
||||
|
||||
logout() {
|
||||
@ -97,14 +105,17 @@ export class AuthService {
|
||||
}
|
||||
|
||||
refreshToken() {
|
||||
return this.http.post<any>(refreshUrl, {})
|
||||
.pipe(map(u => u.access_token))
|
||||
.pipe(map(u => this.parseJwt(u)))
|
||||
.pipe(map(user => {
|
||||
// store user details and jwt token in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem(JWT_USER, JSON.stringify(user));
|
||||
this.currentUserSubject.next(user);
|
||||
return user;
|
||||
}));
|
||||
return this.http
|
||||
.post<any>(refreshUrl, {})
|
||||
.pipe(map((u) => u.access_token))
|
||||
.pipe(map((u) => this.parseJwt(u)))
|
||||
.pipe(
|
||||
map((user) => {
|
||||
// store user details and jwt token in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem(JWT_USER, JSON.stringify(user));
|
||||
this.currentUserSubject.next(user);
|
||||
return user;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,23 +7,36 @@
|
||||
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput #nameElement placeholder="Username" formControlName="username">
|
||||
<input matInput #nameElement placeholder="Username" formControlName="username" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Password</mat-label>
|
||||
<input matInput placeholder="Password" formControlName="password" [type]="hide ? 'password' : 'text'"
|
||||
(keyup.enter)="login()">
|
||||
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Password"
|
||||
formControlName="password"
|
||||
[type]="hide ? 'password' : 'text'"
|
||||
(keyup.enter)="login()"
|
||||
/>
|
||||
<mat-icon matSuffix (click)="hide = !hide">{{
|
||||
hide ? 'visibility' : 'visibility_off'
|
||||
}}</mat-icon>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<h2 *ngIf="showOtp">Client ID: {{clientId}}</h2>
|
||||
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px" *ngIf="showOtp">
|
||||
<h2 *ngIf="showOtp">Client ID: {{ clientId }}</h2>
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px"
|
||||
*ngIf="showOtp"
|
||||
>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Otp</mat-label>
|
||||
<input matInput placeholder="Otp" formControlName="otp">
|
||||
<input matInput placeholder="Otp" formControlName="otp" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {LoginComponent} from './login.component';
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
@ -8,9 +8,8 @@ describe('LoginComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [LoginComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [LoginComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,71 +1,73 @@
|
||||
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import {AuthService} from '../auth.service';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {ToasterService} from '../../core/toaster.service';
|
||||
import {FormBuilder, FormGroup} from '@angular/forms';
|
||||
import {CookieService} from '../../shared/cookie.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css']
|
||||
})
|
||||
export class LoginComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
|
||||
form: FormGroup;
|
||||
hide: boolean;
|
||||
showOtp: boolean;
|
||||
clientId: string;
|
||||
private returnUrl: string;
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private auth: AuthService,
|
||||
private router: Router,
|
||||
private toaster: ToasterService,
|
||||
private cs: CookieService,
|
||||
private fb: FormBuilder
|
||||
) {
|
||||
this.hide = true;
|
||||
this.showOtp = false;
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.form = this.fb.group({
|
||||
username: '',
|
||||
password: '',
|
||||
otp: ''
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.nameElement.nativeElement.focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
login(): void {
|
||||
const formModel = this.form.value;
|
||||
const username = formModel.username;
|
||||
const password = formModel.password;
|
||||
const otp = formModel.otp;
|
||||
this.auth.login(username, password, otp)
|
||||
// .pipe(first())
|
||||
.subscribe(
|
||||
data => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
(error) => {
|
||||
if (error.status === 401 && 'Client is not registered' === error.error.detail) {
|
||||
this.showOtp = true;
|
||||
this.clientId = this.cs.getCookie('client_id');
|
||||
}
|
||||
this.toaster.show('Danger', error.error.details);
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { AuthService } from '../auth.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ToasterService } from '../../core/toaster.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { CookieService } from '../../shared/cookie.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css'],
|
||||
})
|
||||
export class LoginComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
|
||||
form: FormGroup;
|
||||
hide: boolean;
|
||||
showOtp: boolean;
|
||||
clientId: string;
|
||||
private returnUrl: string;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private auth: AuthService,
|
||||
private router: Router,
|
||||
private toaster: ToasterService,
|
||||
private cs: CookieService,
|
||||
private fb: FormBuilder,
|
||||
) {
|
||||
this.hide = true;
|
||||
this.showOtp = false;
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.form = this.fb.group({
|
||||
username: '',
|
||||
password: '',
|
||||
otp: '',
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.nameElement.nativeElement.focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
login(): void {
|
||||
const formModel = this.form.value;
|
||||
const username = formModel.username;
|
||||
const password = formModel.password;
|
||||
const otp = formModel.otp;
|
||||
this.auth
|
||||
.login(username, password, otp)
|
||||
// .pipe(first())
|
||||
.subscribe(
|
||||
(data) => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
(error) => {
|
||||
if (error.status === 401 && 'Client is not registered' === error.error.detail) {
|
||||
this.showOtp = true;
|
||||
this.clientId = this.cs.getCookie('client_id');
|
||||
}
|
||||
this.toaster.show('Danger', error.error.details);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {LogoutComponent} from './logout.component';
|
||||
import { LogoutComponent } from './logout.component';
|
||||
|
||||
describe('LogoutComponent', () => {
|
||||
let component: LogoutComponent;
|
||||
@ -8,9 +8,8 @@ describe('LogoutComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [LogoutComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [LogoutComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Router} from '@angular/router';
|
||||
import {AuthService} from '../auth.service';
|
||||
import {ToasterService} from '../../core/toaster.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AuthService } from '../auth.service';
|
||||
import { ToasterService } from '../../core/toaster.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-logout',
|
||||
template: ''
|
||||
template: '',
|
||||
})
|
||||
export class LogoutComponent implements OnInit {
|
||||
|
||||
constructor(private auth: AuthService, private router: Router, private toaster: ToasterService) {
|
||||
}
|
||||
constructor(private auth: AuthService, private router: Router, private toaster: ToasterService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.auth.logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user