From 4f2c149f5aef461d4813204f3d8a2c90ca0d9e08 Mon Sep 17 00:00:00 2001 From: Daniel Lukats Date: Thu, 30 Jul 2020 17:14:45 +0200 Subject: [PATCH] adjusted login and signup post operations to work with forms added a jwt interceptor --- src/app/account/account.service.ts | 13 ++++++-- src/app/account/jwt.interceptor.spec.ts | 16 ++++++++++ src/app/account/jwt.interceptor.ts | 31 +++++++++++++++++++ src/app/account/login/login.component.html | 2 +- src/app/account/login/login.component.ts | 11 ++++--- .../password-error-state-matcher.spec.ts | 0 .../password-error-state-matcher.ts | 0 .../signup.component.css} | 0 .../signup.component.html} | 0 .../signup.component.spec.ts} | 10 +++--- .../signup.component.ts} | 6 ++-- src/app/app-routing.module.ts | 4 +-- src/app/app.module.ts | 11 ++++--- src/environments/environment.ts | 2 +- 14 files changed, 81 insertions(+), 25 deletions(-) create mode 100644 src/app/account/jwt.interceptor.spec.ts create mode 100644 src/app/account/jwt.interceptor.ts rename src/app/account/{register => signup}/password-error-state-matcher.spec.ts (100%) rename src/app/account/{register => signup}/password-error-state-matcher.ts (100%) rename src/app/account/{register/register.component.css => signup/signup.component.css} (100%) rename src/app/account/{register/register.component.html => signup/signup.component.html} (100%) rename src/app/account/{register/register.component.spec.ts => signup/signup.component.spec.ts} (61%) rename src/app/account/{register/register.component.ts => signup/signup.component.ts} (93%) diff --git a/src/app/account/account.service.ts b/src/app/account/account.service.ts index eb17991..4bb3541 100644 --- a/src/app/account/account.service.ts +++ b/src/app/account/account.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { BehaviorSubject, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -23,7 +23,10 @@ export class AccountService { } login(username, password) { - return this.httpClient.post(environment.apiUrl + '/fake_login', { username, password }) + const body = new HttpParams() + .set('username', username) + .set('password', password); + return this.httpClient.post(environment.apiUrl + '/login', body) .pipe((map(user => { localStorage.setItem('user', JSON.stringify(user)); this.userSubject.next(user); @@ -32,7 +35,11 @@ export class AccountService { } register(user) { - return this.httpClient.post(environment.apiUrl + '/fake_registration', user); + const body = new HttpParams() + .set('username', user.username) + .set('password', user.password) + .set('email', user.email); + return this.httpClient.post(environment.apiUrl + '/signup', body); } } diff --git a/src/app/account/jwt.interceptor.spec.ts b/src/app/account/jwt.interceptor.spec.ts new file mode 100644 index 0000000..8129966 --- /dev/null +++ b/src/app/account/jwt.interceptor.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { JwtInterceptor } from './jwt.interceptor'; + +describe('JwtInterceptor', () => { + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + JwtInterceptor + ] + })); + + it('should be created', () => { + const interceptor: JwtInterceptor = TestBed.inject(JwtInterceptor); + expect(interceptor).toBeTruthy(); + }); +}); diff --git a/src/app/account/jwt.interceptor.ts b/src/app/account/jwt.interceptor.ts new file mode 100644 index 0000000..b9170f7 --- /dev/null +++ b/src/app/account/jwt.interceptor.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor +} from '@angular/common/http'; +import { Observable } from 'rxjs'; + +import { environment } from '../../environments/environment'; +import { AccountService } from './account.service'; + +@Injectable() +export class JwtInterceptor implements HttpInterceptor { + + constructor(private accountService: AccountService) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + const user = this.accountService.userValue; + const isLoggedIn = user && user.token; + const isApiUrl = request.url.startsWith(environment.apiUrl); + if (isLoggedIn && isApiUrl) { + request = request.clone({ + setHeaders: { + Authorization: `Bearer ${user.token}` + } + }); + } + return next.handle(request); + } +} diff --git a/src/app/account/login/login.component.html b/src/app/account/login/login.component.html index cb46847..d4eed87 100644 --- a/src/app/account/login/login.component.html +++ b/src/app/account/login/login.component.html @@ -22,7 +22,7 @@ Login - Sign up + Sign up diff --git a/src/app/account/login/login.component.ts b/src/app/account/login/login.component.ts index ae12d92..8614d8e 100644 --- a/src/app/account/login/login.component.ts +++ b/src/app/account/login/login.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { FormControl, FormGroup } from '@angular/forms'; +import { FormBuilder, Validators} from '@angular/forms'; import { AccountService } from '../account.service'; import { ActivatedRoute, Router } from '@angular/router'; import { first } from 'rxjs/operators'; @@ -10,16 +10,16 @@ import { first } from 'rxjs/operators'; styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { - form: FormGroup = new FormGroup({ - username: new FormControl(''), - password: new FormControl(''), + form = this.formBuilder.group({ + username: ['', Validators.required], + password: ['', [Validators.required, Validators.minLength(15)]], }); loading = false; returnUrl = this.activatedRoute.snapshot.queryParams['returnUrl'] || '/'; onLogin() { this.loading = true; - this.accountService.login(this.form.controls['username'], this.form.controls['password']) + this.accountService.login(this.form.get('username').value, this.form.get('password').value) .pipe(first()) .subscribe(data => { this.router.navigate([this.returnUrl]); @@ -33,6 +33,7 @@ export class LoginComponent implements OnInit { constructor(private accountService: AccountService, private activatedRoute: ActivatedRoute, + private formBuilder: FormBuilder, private router: Router, ) { } diff --git a/src/app/account/register/password-error-state-matcher.spec.ts b/src/app/account/signup/password-error-state-matcher.spec.ts similarity index 100% rename from src/app/account/register/password-error-state-matcher.spec.ts rename to src/app/account/signup/password-error-state-matcher.spec.ts diff --git a/src/app/account/register/password-error-state-matcher.ts b/src/app/account/signup/password-error-state-matcher.ts similarity index 100% rename from src/app/account/register/password-error-state-matcher.ts rename to src/app/account/signup/password-error-state-matcher.ts diff --git a/src/app/account/register/register.component.css b/src/app/account/signup/signup.component.css similarity index 100% rename from src/app/account/register/register.component.css rename to src/app/account/signup/signup.component.css diff --git a/src/app/account/register/register.component.html b/src/app/account/signup/signup.component.html similarity index 100% rename from src/app/account/register/register.component.html rename to src/app/account/signup/signup.component.html diff --git a/src/app/account/register/register.component.spec.ts b/src/app/account/signup/signup.component.spec.ts similarity index 61% rename from src/app/account/register/register.component.spec.ts rename to src/app/account/signup/signup.component.spec.ts index 6c19551..f85fb21 100644 --- a/src/app/account/register/register.component.spec.ts +++ b/src/app/account/signup/signup.component.spec.ts @@ -1,20 +1,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { RegisterComponent } from './register.component'; +import { SignupComponent } from './signup.component'; describe('RegisterComponent', () => { - let component: RegisterComponent; - let fixture: ComponentFixture; + let component: SignupComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ RegisterComponent ] + declarations: [ SignupComponent ] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(RegisterComponent); + fixture = TestBed.createComponent(SignupComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/account/register/register.component.ts b/src/app/account/signup/signup.component.ts similarity index 93% rename from src/app/account/register/register.component.ts rename to src/app/account/signup/signup.component.ts index dc1c587..88b41bd 100644 --- a/src/app/account/register/register.component.ts +++ b/src/app/account/signup/signup.component.ts @@ -8,10 +8,10 @@ import { PasswordErrorStateMatcher } from './password-error-state-matcher'; @Component({ selector: 'app-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.css'] + templateUrl: './signup.component.html', + styleUrls: ['./signup.component.css'] }) -export class RegisterComponent implements OnInit { +export class SignupComponent implements OnInit { form = this.formBuilder.group({ username: ['', Validators.required], email: ['', [Validators.required, Validators.email]], diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d4e067d..a96b4f6 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { AuthGuard } from './account/auth.guard'; import { LoginComponent } from './account/login/login.component'; -import { RegisterComponent } from './account/register/register.component'; +import { SignupComponent } from './account/signup/signup.component'; const gameModule = () => import('./game/game.module').then(x => x.GameModule); @@ -13,7 +13,7 @@ const routes: Routes = [ { path: '', component: AppComponent, canActivate: [AuthGuard] }, // { path: '', redirectTo: '/game', pathMatch: 'prefix', canActivate: [AuthGuard] }, { path: 'login', component: LoginComponent }, - { path: 'register', component: RegisterComponent }, + { path: 'signup', component: SignupComponent }, { path: 'game', loadChildren: gameModule, canActivate: [AuthGuard] }, { path: '**', redirectTo: '' }, ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ab0bc90..256c611 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,5 @@ import { NgModule } from '@angular/core'; -import { HttpClientModule } from '@angular/common/http'; +import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { FlexLayoutModule } from '@angular/flex-layout'; import { ReactiveFormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; @@ -13,15 +13,15 @@ import { MatInputModule } from '@angular/material/input'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { LoginComponent } from './account/login/login.component'; -import { RegisterComponent } from './account/register/register.component'; -import { fakeBackendProvider } from './utils/fake-backend'; +import { SignupComponent } from './account/signup/signup.component'; import { GameModule } from './game/game.module'; +import { JwtInterceptor } from './account/jwt.interceptor'; @NgModule({ declarations: [ AppComponent, LoginComponent, - RegisterComponent + SignupComponent, ], imports: [ HttpClientModule, @@ -37,7 +37,8 @@ import { GameModule } from './game/game.module'; GameModule, ], providers: [ - fakeBackendProvider, + { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, + // fakeBackendProvider, ], exports: [ ], diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 42899ff..1a51f05 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -4,7 +4,7 @@ export const environment = { production: false, - apiUrl: 'http://localhost:4200', + apiUrl: 'http://localhost:5005', }; /*