diff --git a/hv2-ui/src/app/app-routing.module.ts b/hv2-ui/src/app/app-routing.module.ts index b417b90..0738370 100644 --- a/hv2-ui/src/app/app-routing.module.ts +++ b/hv2-ui/src/app/app-routing.module.ts @@ -1,11 +1,15 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { LoginComponent } from './login/login.component'; +import { LogoutComponent } from './logout/logout.component'; import { TestOutputComponent } from './test-output/test-output.component'; const routes: Routes = [ - { path: 'test', component: TestOutputComponent } + { path: 'test', component: TestOutputComponent }, + { path: 'logout', component: LogoutComponent }, + { path: 'login', component: LoginComponent } ] @NgModule({ diff --git a/hv2-ui/src/app/app.module.ts b/hv2-ui/src/app/app.module.ts index ca0a458..4769a2a 100644 --- a/hv2-ui/src/app/app.module.ts +++ b/hv2-ui/src/app/app.module.ts @@ -17,13 +17,20 @@ import { MatCardModule } from '@angular/material/card'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { ErrorHandlerInterceptor } from './error-handler.interceptor'; import { AuthHandlerInterceptor } from './auth-handler.interceptor'; +import { LogoutComponent } from './logout/logout.component'; +import { LoginComponent } from './login/login.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; + @NgModule({ declarations: [ AppComponent, NavigationComponent, MessagesComponent, - TestOutputComponent + TestOutputComponent, + LogoutComponent, + LoginComponent ], imports: [ BrowserModule, @@ -36,7 +43,10 @@ import { AuthHandlerInterceptor } from './auth-handler.interceptor'; MatIconModule, MatListModule, MatCardModule, - AppRoutingModule + AppRoutingModule, + FormsModule, + ReactiveFormsModule, + MatInputModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: ErrorHandlerInterceptor, multi: true }, diff --git a/hv2-ui/src/app/auth-handler.interceptor.ts b/hv2-ui/src/app/auth-handler.interceptor.ts index 013367a..080cf53 100644 --- a/hv2-ui/src/app/auth-handler.interceptor.ts +++ b/hv2-ui/src/app/auth-handler.interceptor.ts @@ -15,9 +15,10 @@ export class AuthHandlerInterceptor implements HttpInterceptor { constructor(private tokenService: TokenService, private messageService: MessageService) {} intercept(request: HttpRequest, next: HttpHandler): Observable> { - if (request.url.includes('api.hv.nober.de')) { + const token = localStorage.getItem(TokenService.Id_Token_Key) + if (request.url.includes('api.hv.nober.de') && token) { const clone = request.clone({ - setHeaders: { Authorization: `Bearer ${this.tokenService.getToken()}`} + setHeaders: { Authorization: `Bearer ${token}`} }) return next.handle(clone) } diff --git a/hv2-ui/src/app/login/login.component.css b/hv2-ui/src/app/login/login.component.css new file mode 100644 index 0000000..e69de29 diff --git a/hv2-ui/src/app/login/login.component.html b/hv2-ui/src/app/login/login.component.html new file mode 100644 index 0000000..0d26ea7 --- /dev/null +++ b/hv2-ui/src/app/login/login.component.html @@ -0,0 +1,23 @@ + + +
+

Log In

+ + The username and password were not recognized + + + + + Please provide a valid email address + + + + + + Please provide a valid password + + + +
+
+
\ No newline at end of file diff --git a/hv2-ui/src/app/login/login.component.spec.ts b/hv2-ui/src/app/login/login.component.spec.ts new file mode 100644 index 0000000..d2c0e6c --- /dev/null +++ b/hv2-ui/src/app/login/login.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/hv2-ui/src/app/login/login.component.ts b/hv2-ui/src/app/login/login.component.ts new file mode 100644 index 0000000..c15ddf5 --- /dev/null +++ b/hv2-ui/src/app/login/login.component.ts @@ -0,0 +1,51 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from '../message.service'; +import { TokenService } from '../token.service'; + + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'] +}) +export class LoginComponent implements OnInit { + form: FormGroup; + public loginInvalid = false; + private formSubmitAttempt = false; + private returnUrl: string; + + constructor(private fb: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private tokenService: TokenService, + private messageService: MessageService) { + this.returnUrl = this.route.snapshot.queryParams.returnUrl || '/' + + this.form = this.fb.group({ + username: ['', Validators.required], + password: ['', Validators.required] + }) + } + + ngOnInit(): void { + } + + async onSubmit(): Promise { + this.loginInvalid = false; + this.formSubmitAttempt = false; + if (this.form.valid) { + try { + const username = this.form.get('username')?.value; + const password = this.form.get('password')?.value; + await this.tokenService.login(username, password); + } catch (err) { + this.loginInvalid = true; + } + } else { + this.formSubmitAttempt = true; + } + } + +} diff --git a/hv2-ui/src/app/logout/logout.component.css b/hv2-ui/src/app/logout/logout.component.css new file mode 100644 index 0000000..e69de29 diff --git a/hv2-ui/src/app/logout/logout.component.html b/hv2-ui/src/app/logout/logout.component.html new file mode 100644 index 0000000..39ef062 --- /dev/null +++ b/hv2-ui/src/app/logout/logout.component.html @@ -0,0 +1,17 @@ +
+ + + + Logout + + + +
+ +

Good bye

+ +
+ +
+
+
diff --git a/hv2-ui/src/app/logout/logout.component.spec.ts b/hv2-ui/src/app/logout/logout.component.spec.ts new file mode 100644 index 0000000..2f92d47 --- /dev/null +++ b/hv2-ui/src/app/logout/logout.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LogoutComponent } from './logout.component'; + +describe('LogoutComponent', () => { + let component: LogoutComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LogoutComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LogoutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/hv2-ui/src/app/logout/logout.component.ts b/hv2-ui/src/app/logout/logout.component.ts new file mode 100644 index 0000000..0a7c2fa --- /dev/null +++ b/hv2-ui/src/app/logout/logout.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; +import { MessageService } from '../message.service'; +import { TokenService } from '../token.service'; + +@Component({ + selector: 'app-logout', + templateUrl: './logout.component.html', + styleUrls: ['./logout.component.css'] +}) +export class LogoutComponent implements OnInit { + + constructor(private messageService: MessageService) { } + + ngOnInit(): void { + localStorage.removeItem(TokenService.Id_Token_Key) + this.messageService.add("Token removed from local storage") + } + +} diff --git a/hv2-ui/src/app/navigation/navigation.component.html b/hv2-ui/src/app/navigation/navigation.component.html index 79a1c66..7ead5f3 100644 --- a/hv2-ui/src/app/navigation/navigation.component.html +++ b/hv2-ui/src/app/navigation/navigation.component.html @@ -6,6 +6,8 @@ Menu Mein Test + Login + Logout diff --git a/hv2-ui/src/app/test-output.service.ts b/hv2-ui/src/app/test-output.service.ts index 954c23b..d85756d 100644 --- a/hv2-ui/src/app/test-output.service.ts +++ b/hv2-ui/src/app/test-output.service.ts @@ -12,7 +12,7 @@ import { TestOutput } from './testOutput'; export class TestOutputService { constructor(private messageService: MessageService, private http: HttpClient) { } - getTestOutput(): Promise { + async getTestOutput(): Promise { this.messageService.add(`TestOutputService: fetch test output`); return this.http.get(`${serviceBaseUrl}/v1/test`).toPromise() } diff --git a/hv2-ui/src/app/token.service.ts b/hv2-ui/src/app/token.service.ts index 1eb67cd..5e3ce7d 100644 --- a/hv2-ui/src/app/token.service.ts +++ b/hv2-ui/src/app/token.service.ts @@ -1,20 +1,33 @@ import { Injectable } from '@angular/core'; import { MessageService } from './message.service'; - +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { UserCreds } from './userCreds' @Injectable({ providedIn: 'root' }) export class TokenService { - private token: String; + public static Id_Token_Key : string = "id_token"; - constructor(private messageService: MessageService) { + constructor(private http: HttpClient, private messageService: MessageService) { this.messageService.add("TokenService started, token created") - this.token = "abc" + + if (! localStorage.getItem(TokenService.Id_Token_Key)) { + localStorage.setItem(TokenService.Id_Token_Key, "abc") + this.messageService.add("Token set in local storage") + } } - getToken(): String { - this.messageService.add("Providing token to other service") - return this.token + + async login(login: string, password: string) { + this.messageService.add(`TokenService: trying to login and obtain token`); + const userCreds : UserCreds = { + "application": "hv2", + "login": login, + "password": password + } + const token = await this.http.post("https://authservice.hottis.de/token", userCreds).toPromise() + this.messageService.add(`Token is ${JSON.stringify(token, undefined, 4)}`) } + } diff --git a/hv2-ui/src/app/userCreds.ts b/hv2-ui/src/app/userCreds.ts new file mode 100644 index 0000000..e8fe7cb --- /dev/null +++ b/hv2-ui/src/app/userCreds.ts @@ -0,0 +1,5 @@ +export interface UserCreds { + application: string + login: string + password: string +}