Skip to content

Commit 5c46348

Browse files
committed
Added login page
1 parent eb7c9a0 commit 5c46348

14 files changed

Lines changed: 285 additions & 10 deletions

src/app/app.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { BrowserModule } from '@angular/platform-browser';
44

55
import { AppRoutingModule } from './app-routing.module';
66
import { AppComponent } from './app.component';
7+
import { AuthenticationModule } from './authentication/authentication.module';
78
import { NavigationModule } from './navigation/navigation.module';
89

910
@NgModule({
@@ -14,7 +15,8 @@ import { NavigationModule } from './navigation/navigation.module';
1415
BrowserModule,
1516
AppRoutingModule,
1617
NavigationModule,
17-
HttpClientModule
18+
HttpClientModule,
19+
AuthenticationModule
1820
],
1921
providers: [],
2022
bootstrap: [AppComponent]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { HTTP_INTERCEPTORS } from '@angular/common/http';
4+
import { AuthInterceptor } from './interceptor/authentication.interceptor';
5+
import { AuthenticationService } from './service/authentication.service';
6+
import { AuthenticationTokenService } from './service/authentication-token.service';
7+
8+
9+
10+
@NgModule({
11+
declarations: [],
12+
imports: [
13+
CommonModule
14+
],
15+
providers: [
16+
AuthenticationService,
17+
AuthenticationTokenService,
18+
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
19+
]
20+
})
21+
export class AuthenticationModule { }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { AuthenticationInterceptor } from './authentication.interceptor';
4+
5+
describe('AuthenticationInterceptor', () => {
6+
beforeEach(() => TestBed.configureTestingModule({
7+
providers: [
8+
AuthenticationInterceptor
9+
]
10+
}));
11+
12+
it('should be created', () => {
13+
const interceptor: AuthenticationInterceptor = TestBed.inject(AuthenticationInterceptor);
14+
expect(interceptor).toBeTruthy();
15+
});
16+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
2+
import { Injectable } from '@angular/core';
3+
import { Observable } from 'rxjs';
4+
import { AuthenticationTokenService } from '../service/authentication-token.service';
5+
6+
7+
@Injectable()
8+
export class AuthInterceptor implements HttpInterceptor {
9+
10+
private tokenHeaderKey = 'Authorization';
11+
12+
constructor(private token: AuthenticationTokenService) { }
13+
14+
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
15+
let authReq = req;
16+
const token = this.token.getToken();
17+
if (token != null) {
18+
authReq = req.clone({ headers: req.headers.set(this.tokenHeaderKey, 'Bearer ' + token) });
19+
}
20+
return next.handle(authReq);
21+
}
22+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export class User {
2+
id: number = 0;
3+
username: string = '';
4+
password: string = '';
5+
authdata?: string;
6+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { AuthenticationTokenService } from './authentication-token.service';
4+
5+
describe('AuthenticationTokenService', () => {
6+
let service: AuthenticationTokenService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(AuthenticationTokenService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Injectable } from '@angular/core';
2+
3+
@Injectable({
4+
providedIn: 'root'
5+
})
6+
export class AuthenticationTokenService {
7+
8+
private tokenKey = 'auth-token';
9+
private userKey = 'auth-user';
10+
11+
constructor() { }
12+
13+
public signOut(): void {
14+
window.sessionStorage.clear();
15+
}
16+
17+
public saveToken(token: string): void {
18+
window.sessionStorage.removeItem(this.tokenKey);
19+
window.sessionStorage.setItem(this.tokenKey, token);
20+
}
21+
22+
public getToken(): string | null {
23+
return window.sessionStorage.getItem(this.tokenKey);
24+
}
25+
26+
public saveUser(user: any): void {
27+
window.sessionStorage.removeItem(this.userKey);
28+
window.sessionStorage.setItem(this.userKey, JSON.stringify(user));
29+
}
30+
31+
public getUser(): any {
32+
const user = window.sessionStorage.getItem(this.userKey);
33+
if (user) {
34+
return JSON.parse(user);
35+
}
36+
return {};
37+
}
38+
39+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { AuthenticationService } from './authentication.service';
4+
5+
describe('AuthenticationService', () => {
6+
let service: AuthenticationService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(AuthenticationService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Injectable } from '@angular/core';
2+
import { HttpClient, HttpHeaders } from '@angular/common/http';
3+
import { Observable } from 'rxjs';
4+
import { environment } from '@environments/environment';
5+
6+
@Injectable({
7+
providedIn: 'root'
8+
})
9+
export class AuthenticationService {
10+
11+
private httpOptions = {
12+
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
13+
};
14+
15+
constructor(private http: HttpClient) { }
16+
17+
login(username: string, password: string): Observable<any> {
18+
return this.http.post(environment.apiUrl + '/api/auth/' + 'signin', {
19+
username,
20+
password
21+
}, this.httpOptions);
22+
}
23+
24+
register(username: string, email: string, password: string): Observable<any> {
25+
return this.http.post(environment.apiUrl + 'signup', {
26+
username,
27+
email,
28+
password
29+
}, this.httpOptions);
30+
}
31+
}
Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,65 @@
1-
<p>login-form works!</p>
1+
<div class="col-md-12">
2+
<div class="card card-container">
3+
<form
4+
*ngIf="!isLoggedIn"
5+
name="form"
6+
(ngSubmit)="f.form.valid && onSubmit()"
7+
#f="ngForm"
8+
novalidate
9+
>
10+
<div class="form-group">
11+
<label for="username">Username</label>
12+
<input
13+
type="text"
14+
class="form-control"
15+
name="username"
16+
[(ngModel)]="form.username"
17+
required
18+
#username="ngModel"
19+
/>
20+
<div
21+
class="alert alert-danger"
22+
role="alert"
23+
*ngIf="username.errors && f.submitted"
24+
>
25+
Username is required!
26+
</div>
27+
</div>
28+
<div class="form-group">
29+
<label for="password">Password</label>
30+
<input
31+
type="password"
32+
class="form-control"
33+
name="password"
34+
[(ngModel)]="form.password"
35+
required
36+
#password="ngModel"
37+
/>
38+
<div
39+
class="alert alert-danger"
40+
role="alert"
41+
*ngIf="password.errors && f.submitted"
42+
>
43+
<div *ngIf="password.errors.required">Password is required</div>
44+
</div>
45+
</div>
46+
<div class="form-group">
47+
<button class="btn btn-primary btn-block">
48+
Login
49+
</button>
50+
</div>
51+
<div class="form-group">
52+
<div
53+
class="alert alert-danger"
54+
role="alert"
55+
*ngIf="f.submitted && isLoginFailed"
56+
>
57+
Login failed: {{ errorMessage }}
58+
</div>
59+
</div>
60+
</form>
61+
<div class="alert alert-success" *ngIf="isLoggedIn">
62+
Logged in as {{ roles }}.
63+
</div>
64+
</div>
65+
</div>

0 commit comments

Comments
 (0)