Add basic login, data and authentification handling
This commit is contained in:
parent
2f352733d0
commit
b4e2848b11
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
|
||||||
|
describe('AuthService', () => {
|
||||||
|
let service: AuthService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(AuthService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,34 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
const AUTH_API = 'http://localhost:8080/api/auth/';
|
||||||
|
const httpOptions = {
|
||||||
|
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
|
||||||
|
};
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class AuthService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
login(username: string, password: string): Observable<any> {
|
||||||
|
return this.http.post(
|
||||||
|
AUTH_API + 'signin',
|
||||||
|
{
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
httpOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
register(username: string, email: string, password: string): Observable<any> {
|
||||||
|
return this.http.post(
|
||||||
|
AUTH_API + 'signup',
|
||||||
|
{
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
httpOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DataService } from './data.service';
|
||||||
|
|
||||||
|
describe('DataService', () => {
|
||||||
|
let service: DataService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(DataService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,22 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
const API_URL = 'http://localhost:8080/api/test/';
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class UserService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
getPublicContent(): Observable<any> {
|
||||||
|
return this.http.get(API_URL + 'all', { responseType: 'text' });
|
||||||
|
}
|
||||||
|
getUserBoard(): Observable<any> {
|
||||||
|
return this.http.get(API_URL + 'user', { responseType: 'text' });
|
||||||
|
}
|
||||||
|
getModeratorBoard(): Observable<any> {
|
||||||
|
return this.http.get(API_URL + 'mod', { responseType: 'text' });
|
||||||
|
}
|
||||||
|
getAdminBoard(): Observable<any> {
|
||||||
|
return this.http.get(API_URL + 'admin', { responseType: 'text' });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TokenService } from './token.service';
|
||||||
|
|
||||||
|
describe('TokenService', () => {
|
||||||
|
let service: TokenService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(TokenService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,30 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
const TOKEN_KEY = 'auth-token';
|
||||||
|
const USER_KEY = 'auth-user';
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class TokenStorageService {
|
||||||
|
constructor() {}
|
||||||
|
signOut(): void {
|
||||||
|
window.sessionStorage.clear();
|
||||||
|
}
|
||||||
|
public saveToken(token: string): void {
|
||||||
|
window.sessionStorage.removeItem(TOKEN_KEY);
|
||||||
|
window.sessionStorage.setItem(TOKEN_KEY, token);
|
||||||
|
}
|
||||||
|
public getToken(): string | null {
|
||||||
|
return window.sessionStorage.getItem(TOKEN_KEY);
|
||||||
|
}
|
||||||
|
public saveUser(user: any): void {
|
||||||
|
window.sessionStorage.removeItem(USER_KEY);
|
||||||
|
window.sessionStorage.setItem(USER_KEY, JSON.stringify(user));
|
||||||
|
}
|
||||||
|
public getUser(): any {
|
||||||
|
const user = window.sessionStorage.getItem(USER_KEY);
|
||||||
|
if (user) {
|
||||||
|
return JSON.parse(user);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,72 @@
|
|||||||
<p>login works!</p>
|
<div class="col-md-12">
|
||||||
|
<div class="card card-container">
|
||||||
|
<img
|
||||||
|
id="profile-img"
|
||||||
|
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
|
||||||
|
class="profile-img-card"
|
||||||
|
/>
|
||||||
|
<form
|
||||||
|
*ngIf="!isLoggedIn"
|
||||||
|
name="form"
|
||||||
|
(ngSubmit)="f.form.valid && onSubmit()"
|
||||||
|
#f="ngForm"
|
||||||
|
novalidate
|
||||||
|
>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="username"
|
||||||
|
[(ngModel)]="form.username"
|
||||||
|
required
|
||||||
|
#username="ngModel"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="alert alert-danger"
|
||||||
|
role="alert"
|
||||||
|
*ngIf="username.errors && f.submitted"
|
||||||
|
>
|
||||||
|
Username is required!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
class="form-control"
|
||||||
|
name="password"
|
||||||
|
[(ngModel)]="form.password"
|
||||||
|
required
|
||||||
|
minlength="6"
|
||||||
|
#password="ngModel"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="alert alert-danger"
|
||||||
|
role="alert"
|
||||||
|
*ngIf="password.errors && f.submitted"
|
||||||
|
>
|
||||||
|
<div *ngIf="password.errors?.['required']">Password is required</div>
|
||||||
|
<div *ngIf="password.errors?.['minlength']">
|
||||||
|
Password must be at least 6 characters
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-primary btn-block">Login</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div
|
||||||
|
class="alert alert-danger"
|
||||||
|
role="alert"
|
||||||
|
*ngIf="f.submitted && isLoginFailed"
|
||||||
|
>
|
||||||
|
Login failed: {{ errorMessage }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="alert alert-success" *ngIf="isLoggedIn">
|
||||||
|
Logged in as {{ roles }}.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@ -1,15 +1,49 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AuthService } from '../../Services/auth.service';
|
||||||
|
import { TokenStorageService } from '../../Services/token.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrls: ['./login.component.scss']
|
styleUrls: ['./login.component.scss'],
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit {
|
||||||
|
form: any = {
|
||||||
constructor() { }
|
username: null,
|
||||||
|
password: null,
|
||||||
|
};
|
||||||
|
isLoggedIn = false;
|
||||||
|
isLoginFailed = false;
|
||||||
|
errorMessage = '';
|
||||||
|
roles: string[] = [];
|
||||||
|
constructor(
|
||||||
|
private authService: AuthService,
|
||||||
|
private tokenStorage: TokenStorageService
|
||||||
|
) {}
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
if (this.tokenStorage.getToken()) {
|
||||||
|
this.isLoggedIn = true;
|
||||||
|
this.roles = this.tokenStorage.getUser().roles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onSubmit(): void {
|
||||||
|
const { username, password } = this.form;
|
||||||
|
this.authService.login(username, password).subscribe(
|
||||||
|
(data) => {
|
||||||
|
this.tokenStorage.saveToken(data.accessToken);
|
||||||
|
this.tokenStorage.saveUser(data);
|
||||||
|
this.isLoginFailed = false;
|
||||||
|
this.isLoggedIn = true;
|
||||||
|
this.roles = this.tokenStorage.getUser().roles;
|
||||||
|
this.reloadPage();
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.errorMessage = err.error.message;
|
||||||
|
this.isLoginFailed = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
reloadPage(): void {
|
||||||
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
@ -32,6 +33,7 @@ import { DashboardComponent } from './Views/dashboard/dashboard.component';
|
|||||||
MatGridListModule,
|
MatGridListModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
|
FormsModule,
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
|
Loading…
Reference in New Issue
Block a user