From 16631f60b07804cdb8365578971b091d4dc1526e Mon Sep 17 00:00:00 2001 From: Cathy Hu Date: Mon, 17 Aug 2020 18:10:54 +0200 Subject: [PATCH] [frontend] Implement bare login process (login service, auth guard) --- kibicara-frontend/src/app/auth/auth.module.ts | 14 ----- .../src/app/auth/login/login.component.html | 1 - .../src/app/auth/login/login.component.ts | 15 ----- .../auth-token-interceptor.service.spec.ts | 16 +++++ .../auth/auth-token-interceptor.service.ts | 26 ++++++++ .../src/app/core/auth/auth.guard.spec.ts | 16 +++++ .../src/app/core/auth/auth.guard.ts | 25 ++++++++ .../src/app/core/auth/login.service.spec.ts | 16 +++++ .../src/app/core/auth/login.service.ts | 38 ++++++++++++ .../src/app/login/login.component.html | 46 ++++++++++++++ .../app/{auth => }/login/login.component.scss | 0 .../{auth => }/login/login.component.spec.ts | 0 .../src/app/login/login.component.ts | 61 +++++++++++++++++++ .../register/register.component.html | 0 .../register/register.component.scss | 0 .../register/register.component.spec.ts | 0 .../{auth => }/register/register.component.ts | 0 17 files changed, 244 insertions(+), 30 deletions(-) delete mode 100644 kibicara-frontend/src/app/auth/auth.module.ts delete mode 100644 kibicara-frontend/src/app/auth/login/login.component.html delete mode 100644 kibicara-frontend/src/app/auth/login/login.component.ts create mode 100644 kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.spec.ts create mode 100644 kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.ts create mode 100644 kibicara-frontend/src/app/core/auth/auth.guard.spec.ts create mode 100644 kibicara-frontend/src/app/core/auth/auth.guard.ts create mode 100644 kibicara-frontend/src/app/core/auth/login.service.spec.ts create mode 100644 kibicara-frontend/src/app/core/auth/login.service.ts create mode 100644 kibicara-frontend/src/app/login/login.component.html rename kibicara-frontend/src/app/{auth => }/login/login.component.scss (100%) rename kibicara-frontend/src/app/{auth => }/login/login.component.spec.ts (100%) create mode 100644 kibicara-frontend/src/app/login/login.component.ts rename kibicara-frontend/src/app/{auth => }/register/register.component.html (100%) rename kibicara-frontend/src/app/{auth => }/register/register.component.scss (100%) rename kibicara-frontend/src/app/{auth => }/register/register.component.spec.ts (100%) rename kibicara-frontend/src/app/{auth => }/register/register.component.ts (100%) diff --git a/kibicara-frontend/src/app/auth/auth.module.ts b/kibicara-frontend/src/app/auth/auth.module.ts deleted file mode 100644 index 106f705..0000000 --- a/kibicara-frontend/src/app/auth/auth.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { LoginComponent } from './login/login.component'; -import { RegisterComponent } from './register/register.component'; - - - -@NgModule({ - declarations: [LoginComponent, RegisterComponent], - imports: [ - CommonModule - ] -}) -export class AuthModule { } diff --git a/kibicara-frontend/src/app/auth/login/login.component.html b/kibicara-frontend/src/app/auth/login/login.component.html deleted file mode 100644 index 147cfc4..0000000 --- a/kibicara-frontend/src/app/auth/login/login.component.html +++ /dev/null @@ -1 +0,0 @@ -

login works!

diff --git a/kibicara-frontend/src/app/auth/login/login.component.ts b/kibicara-frontend/src/app/auth/login/login.component.ts deleted file mode 100644 index c74528f..0000000 --- a/kibicara-frontend/src/app/auth/login/login.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.scss'] -}) -export class LoginComponent implements OnInit { - - constructor() { } - - ngOnInit(): void { - } - -} diff --git a/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.spec.ts b/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.spec.ts new file mode 100644 index 0000000..c8274cc --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthTokenInterceptorService } from './auth-token-interceptor.service'; + +describe('AuthTokenInterceptorService', () => { + let service: AuthTokenInterceptorService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthTokenInterceptorService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.ts b/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.ts new file mode 100644 index 0000000..1bb13c3 --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/auth-token-interceptor.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class AuthTokenInterceptorService { + constructor() {} + + intercept( + req: HttpRequest, + next: HttpHandler + ): Observable> { + // const token = this.loginService.token; + + // if (token) { + // req = req.clone({ + // setHeaders: { + // Authorization: 'Bearer ' + this.loginService.token, + // }, + // }); + // } + return next.handle(req); + } +} diff --git a/kibicara-frontend/src/app/core/auth/auth.guard.spec.ts b/kibicara-frontend/src/app/core/auth/auth.guard.spec.ts new file mode 100644 index 0000000..68889d2 --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/auth.guard.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthGuard } from './auth.guard'; + +describe('AuthGuard', () => { + let guard: AuthGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(AuthGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/kibicara-frontend/src/app/core/auth/auth.guard.ts b/kibicara-frontend/src/app/core/auth/auth.guard.ts new file mode 100644 index 0000000..8b04fca --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/auth.guard.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { + CanActivate, + ActivatedRouteSnapshot, + RouterStateSnapshot, + UrlTree, + Router, +} from '@angular/router'; +import { Observable } from 'rxjs'; +import { LoginService } from './login.service'; + +@Injectable({ + providedIn: 'root', +}) +export class AuthGuard implements CanActivate { + constructor(private router: Router, private loginService: LoginService) {} + + canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + if (this.loginService.currentHoodAdminValue) { + return true; + } + this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); + return false; + } +} diff --git a/kibicara-frontend/src/app/core/auth/login.service.spec.ts b/kibicara-frontend/src/app/core/auth/login.service.spec.ts new file mode 100644 index 0000000..299b0d5 --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/login.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { LoginService } from './login.service'; + +describe('LoginService', () => { + let service: LoginService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(LoginService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/kibicara-frontend/src/app/core/auth/login.service.ts b/kibicara-frontend/src/app/core/auth/login.service.ts new file mode 100644 index 0000000..ca0ace8 --- /dev/null +++ b/kibicara-frontend/src/app/core/auth/login.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { AdminService } from '../api'; + +@Injectable({ + providedIn: 'root', +}) +export class LoginService { + private currentHoodAdminSubject: BehaviorSubject; + public currentHoodAdmin: Observable; + + constructor(private readonly adminService: AdminService) { + this.currentHoodAdminSubject = new BehaviorSubject( + JSON.parse(localStorage.getItem('currentHoodAdmin')) + ); + this.currentHoodAdmin = this.currentHoodAdminSubject.asObservable(); + } + + public get currentHoodAdminValue() { + return this.currentHoodAdminSubject.value; + } + + login(email, password) { + return this.adminService.login(email, password).pipe( + map((response) => { + localStorage.setItem('currentHoodAdmin', JSON.stringify(response)); + this.currentHoodAdminSubject.next(response); + return response; + }) + ); + } + + logout() { + localStorage.removeItem('currentHoodAdmin'); + this.currentHoodAdminSubject.next(null); + } +} diff --git a/kibicara-frontend/src/app/login/login.component.html b/kibicara-frontend/src/app/login/login.component.html new file mode 100644 index 0000000..35909b5 --- /dev/null +++ b/kibicara-frontend/src/app/login/login.component.html @@ -0,0 +1,46 @@ +
{{ error }}
+

Login

+
+
+ + +
+
+ Email is required +
+
+
+
+ + +
+
+ Password is required +
+
+
+
+ + Register +
+
diff --git a/kibicara-frontend/src/app/auth/login/login.component.scss b/kibicara-frontend/src/app/login/login.component.scss similarity index 100% rename from kibicara-frontend/src/app/auth/login/login.component.scss rename to kibicara-frontend/src/app/login/login.component.scss diff --git a/kibicara-frontend/src/app/auth/login/login.component.spec.ts b/kibicara-frontend/src/app/login/login.component.spec.ts similarity index 100% rename from kibicara-frontend/src/app/auth/login/login.component.spec.ts rename to kibicara-frontend/src/app/login/login.component.spec.ts diff --git a/kibicara-frontend/src/app/login/login.component.ts b/kibicara-frontend/src/app/login/login.component.ts new file mode 100644 index 0000000..fddaac4 --- /dev/null +++ b/kibicara-frontend/src/app/login/login.component.ts @@ -0,0 +1,61 @@ +import { Component, OnInit } from '@angular/core'; +import { LoginService } from '../core/auth/login.service'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Validators, FormGroup, FormBuilder } from '@angular/forms'; +import { first } from 'rxjs/operators'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'], +}) +export class LoginComponent implements OnInit { + loginForm: FormGroup; + returnUrl: string; + error: string; + loading = false; + submitted = false; + + constructor( + private loginService: LoginService, + private router: Router, + private route: ActivatedRoute, + private formBuilder: FormBuilder + ) { + if (this.loginService.currentHoodAdminValue) { + this.router.navigate(['/dashboard']); + } + } + + ngOnInit(): void { + this.loginForm = this.formBuilder.group({ + email: ['', Validators.required], + password: ['', Validators.required], + }); + this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/dashboard'; + } + + onSubmit() { + this.submitted = true; + if (this.loginForm.invalid) { + return; + } + + this.loading = true; + this.loginService + .login( + this.loginForm.controls.email.value, + this.loginForm.controls.password.value + ) + .pipe(first()) + .subscribe( + (data) => { + this.router.navigate([this.returnUrl]); + }, + (error) => { + this.error = 'Wrong credentials! Try again.'; + this.loading = false; + } + ); + } +} diff --git a/kibicara-frontend/src/app/auth/register/register.component.html b/kibicara-frontend/src/app/register/register.component.html similarity index 100% rename from kibicara-frontend/src/app/auth/register/register.component.html rename to kibicara-frontend/src/app/register/register.component.html diff --git a/kibicara-frontend/src/app/auth/register/register.component.scss b/kibicara-frontend/src/app/register/register.component.scss similarity index 100% rename from kibicara-frontend/src/app/auth/register/register.component.scss rename to kibicara-frontend/src/app/register/register.component.scss diff --git a/kibicara-frontend/src/app/auth/register/register.component.spec.ts b/kibicara-frontend/src/app/register/register.component.spec.ts similarity index 100% rename from kibicara-frontend/src/app/auth/register/register.component.spec.ts rename to kibicara-frontend/src/app/register/register.component.spec.ts diff --git a/kibicara-frontend/src/app/auth/register/register.component.ts b/kibicara-frontend/src/app/register/register.component.ts similarity index 100% rename from kibicara-frontend/src/app/auth/register/register.component.ts rename to kibicara-frontend/src/app/register/register.component.ts