🔒 Refactor authentication handling by replacing LocalStorage/Login/Register services with AuthService across components and services
continuous-integration/drone/push Build is passing Details

tutorial
Alix JEUDI--LEMOINE 6 days ago
parent 1109094599
commit 4279711d5c

@ -1,6 +1,6 @@
<app-navbar *ngIf="localStorageService.getToken()"></app-navbar>
<app-home-navbar *ngIf="!localStorageService.getToken()"></app-home-navbar>
<app-navbar *ngIf="authService.isLoggedIn()"></app-navbar>
<app-home-navbar *ngIf="!authService.isLoggedIn()"></app-home-navbar>
<router-outlet />
<app-admin-footer *ngIf="localStorageService.getIsAdmin() === 'true'"></app-admin-footer>
<app-admin-footer *ngIf="authService.isAdmin()"></app-admin-footer>

@ -3,8 +3,8 @@ import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HomeNavbarComponent } from './components/home-navbar/home-navbar.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { LocalStorageService } from './services/local-storage/local-storage.service';
import { AdminFooterComponent } from './components/admin-footer/admin-footer.component';
import { AuthService } from './services/auth/auth.service';
@Component({
selector: 'app-root',
@ -14,5 +14,5 @@ import { AdminFooterComponent } from './components/admin-footer/admin-footer.com
export class AppComponent {
title = 'Memory Map';
constructor(protected localStorageService: LocalStorageService) {}
constructor(protected authService: AuthService) {}
}

@ -1,21 +1,20 @@
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { LocalStorageService } from './services/local-storage/local-storage.service';
import { ModalService } from './services/modal/modal.service';
import { AuthService } from './services/auth/auth.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(
private localStorageService: LocalStorageService,
private authService: AuthService,
private router: Router,
private loginModalService: ModalService
) {}
canActivate(): boolean {
const token = this.localStorageService.getToken();
if (token) {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/']).then(() => {

@ -3,8 +3,8 @@ import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { debounceTime, distinctUntilChanged, Subject } from 'rxjs';
import { FriendsService } from '../../services/friends/friends.service';
import { LocalStorageService } from '../../services/local-storage/local-storage.service';
import { UserService } from '../../services/user/user.service';
import { AuthService } from '../../services/auth/auth.service';
@Component({
selector: 'app-friend-page',
@ -35,7 +35,7 @@ export class FriendPageComponent implements OnInit {
constructor(
private friendService: FriendsService,
private userService: UserService,
private localStorage: LocalStorageService
private authService: AuthService
) {}
ngOnInit(): void {
@ -61,7 +61,7 @@ export class FriendPageComponent implements OnInit {
}
private getUserData(search: string): void {
const username = this.localStorage.getUsername();
const username = this.authService.getUsername();
this.userService
.getUser('^(?!' + username + ')' + search)
.subscribe((data: any[]) => {

@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { ModalService } from '../../services/modal/modal.service';
import { Router } from '@angular/router';
import { LoginService } from '../../services/login/login.service';
import { AuthService } from '../../services/auth/auth.service';
@Component({
selector: 'app-home-page',
@ -13,15 +13,14 @@ export class HomePageComponent {
constructor(
private loginModalService: ModalService,
private router: Router,
private loginService: LoginService
private authService: AuthService
) {}
openLogin() {
const token = localStorage.getItem('token');
if (!token) {
this.router.navigate(['/map']);
} else {
if (!this.authService.isLoggedIn()) {
this.loginModalService.openModal('login-modal');
} else {
this.router.navigate(['/map']);
}
}
}

@ -11,8 +11,8 @@ import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { User } from '../../model/User';
import { LocalStorageService } from '../../services/local-storage/local-storage.service';
import { LoginService } from '../../services/login/login.service';
import { ModalService } from '../../services/modal/modal.service';
import { AuthService } from '../../services/auth/auth.service';
@Component({
selector: 'app-login-page',
@ -28,7 +28,7 @@ export class LoginPageComponent {
private modalSub!: Subscription;
constructor(
private loginService: LoginService,
private authService: AuthService,
private fb: FormBuilder,
private router: Router,
private modalService: ModalService,
@ -65,11 +65,8 @@ export class LoginPageComponent {
this.user.login = this.userForm.value.login;
this.user.password = this.userForm.value.password;
this.loginService.login(this.user.login, this.user.password).subscribe({
next: (response) => {
this.localStorageService.setToken(response.access_token);
this.localStorageService.setUsername(this.user.login);
this.localStorageService.setIsAdmin(response.is_admin);
this.authService.login(this.user.login, this.user.password).subscribe({
next: () => {
this.closeLoginModal();
setTimeout(() => {
this.router.navigate(['/map']);

@ -20,10 +20,10 @@ import {
switchMap,
} from 'rxjs';
import { Pin } from '../../model/Pin';
import { LocalStorageService } from '../../services/local-storage/local-storage.service';
import { PinService } from '../../services/pin/pin.service';
import { AddPinPopupComponent } from '../add-pin-popup/add-pin-popup.component';
import { FriendPageComponent } from '../friend-page/friend-page.component';
import { AuthService } from '../../services/auth/auth.service';
@Component({
selector: 'app-navbar',
@ -61,9 +61,9 @@ export class NavbarComponent implements OnInit {
constructor(
private router: Router,
private route: ActivatedRoute,
private localStorageService: LocalStorageService,
private pinService: PinService,
private fb: FormBuilder
private fb: FormBuilder,
private authService: AuthService
) {
this.searchForm = this.fb.group({
searchControl: new FormControl(''),
@ -149,9 +149,7 @@ export class NavbarComponent implements OnInit {
}
public logout() {
this.localStorageService.removeToken();
this.localStorageService.removeUsername();
this.localStorageService.removeIsAdmin();
this.authService.logout();
this.router.navigate(['/']);
}
}

@ -10,9 +10,8 @@ import {
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { User } from '../../model/User';
import { LocalStorageService } from '../../services/local-storage/local-storage.service';
import { ModalService } from '../../services/modal/modal.service';
import { RegisterService } from '../../services/register/register.service';
import { AuthService } from '../../services/auth/auth.service';
@Component({
selector: 'app-register-page',
@ -28,9 +27,8 @@ export class RegisterPageComponent {
private modalSub!: Subscription;
constructor(
private registerService: RegisterService,
private authService: AuthService,
private fb: FormBuilder,
private localStorageService: LocalStorageService,
private modalService: ModalService,
private router: Router
) {
@ -79,12 +77,12 @@ export class RegisterPageComponent {
this.user.login = this.userForm.value.login;
this.user.password = this.userForm.value.password;
this.registerService
this.authService
.register(this.user.login, this.user.password)
.subscribe({
next: (response) => {
this.localStorageService.setToken(response.access_token);
next: () => {
this.closeRegisterModal();
setTimeout(() => {
this.router.navigate(['/map']);
}, 1);

@ -0,0 +1,6 @@
export interface AuthResponse {
access_token: string;
token_type: string;
user_id: string;
is_admin: boolean;
}

@ -1,13 +1,13 @@
import { TestBed } from '@angular/core/testing';
import { LoginService } from './login.service';
import { AuthService } from './auth.service';
describe('LoginService', () => {
let service: LoginService;
describe('AuthService', () => {
let service: AuthService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LoginService);
service = TestBed.inject(AuthService);
});
it('should be created', () => {

@ -0,0 +1,80 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { BehaviorSubject, Observable, tap } from 'rxjs';
import { environment } from '../../../environment';
import { LocalStorageService } from '../local-storage/local-storage.service';
import { AuthResponse } from '../../model/AuthResponse';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private isAdminSubject = new BehaviorSubject<boolean>(false);
isAdmin$ = this.isAdminSubject.asObservable();
username$ = new BehaviorSubject<string>('');
isLoggedIn$ = new BehaviorSubject<boolean>(false);
constructor(private http: HttpClient, private localStorageService: LocalStorageService) {
const token = this.localStorageService.getToken();
if (token) {
this.isAdminSubject.next(this.localStorageService.getIsAdmin() === 'true');
this.username$.next(this.localStorageService.getUsername() || '');
this.isLoggedIn$.next(true);
}
}
login(username: string, password: string): Observable<AuthResponse> {
const payload = new HttpParams()
.set('username', username)
.set('password', password);
return this.http.post<AuthResponse>(`${environment.apiURL}/login`, payload).pipe(
tap(response => {
this.localStorageService.setToken(response.access_token);
this.localStorageService.setIsAdmin(response.is_admin);
this.localStorageService.setUsername(username);
this.isAdminSubject.next(response.is_admin);
this.username$.next(username);
this.isLoggedIn$.next(true);
})
);
}
logout(): void {
this.localStorageService.removeToken();
this.localStorageService.removeIsAdmin();
this.isAdminSubject.next(false);
this.username$.next('');
this.isLoggedIn$.next(false);
}
register(username: string, password: string): Observable<AuthResponse> {
return this.http.post<AuthResponse>(`${environment.apiURL}/register`, { username, password }).pipe(
tap(response => {
this.localStorageService.setToken(response.access_token);
this.localStorageService.setIsAdmin(response.is_admin);
this.localStorageService.setUsername(username);
this.isAdminSubject.next(response.is_admin);
this.username$.next(username);
this.isLoggedIn$.next(true);
})
);
}
isAdmin(): boolean {
return this.isAdminSubject.value || false;
}
getAuthHeaders(): HttpHeaders {
const token = this.localStorageService.getToken();
return new HttpHeaders().set('Authorization', `Bearer ${token}`);
}
getUsername(): string {
return this.username$.value || '';
}
isLoggedIn(): boolean {
return this.isLoggedIn$.value || false;
}
}

@ -1,65 +1,60 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../environment';
import { AuthService } from '../auth/auth.service';
@Injectable({
providedIn: 'root',
})
export class FriendsService {
private apiURL = environment.apiURL;
constructor(private http: HttpClient) {}
constructor(private http: HttpClient, private authService: AuthService) {}
getFriend() {
const url = `${this.apiURL}/friends`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.get<any[]>(url, { headers });
}
getFriendById(id: string) {
const url = `${this.apiURL}/user/${id}`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.get<any>(url, { headers });
}
addFriend(user_id: string) {
const url = `${this.apiURL}/friend/add`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post<any>(url, { friend_user_id: user_id }, { headers });
}
acceptFriendById(id: string) {
const url = `${this.apiURL}/friend/${id}/accept`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.patch<any>(url, [], { headers });
}
denyFriendById(id: string) {
const url = `${this.apiURL}/friend/${id}/deny`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.delete<any>(url, { headers });
}
deleteFriend(id: string) {
const url = `${this.apiURL}/friend/${id}/delete`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.delete<any>(url, { headers });
}
}

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { environment } from '../../../environment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { LocalStorageService } from '../local-storage/local-storage.service';
import { AuthService } from '../auth/auth.service';
@Injectable({
providedIn: 'root'
@ -12,14 +12,11 @@ export class ImageService {
constructor(
private http: HttpClient,
private localStorageService: LocalStorageService
private authService: AuthService
) { }
getImage(imageId: string): Observable<Blob> {
const token = this.localStorageService.getToken();
const headers = new HttpHeaders({
'Authorization': `Bearer ${token}`
});
const headers = this.authService.getAuthHeaders();
return this.http.get(`${this.apiUrl}/image/${imageId}`, {
headers,
@ -28,10 +25,7 @@ export class ImageService {
}
postImage(image: File): Observable<any> {
const token = this.localStorageService.getToken();
const headers = new HttpHeaders({
'Authorization': `Bearer ${token}`
});
const headers = this.authService.getAuthHeaders();
const formData = new FormData();
formData.append('image', image);
@ -40,10 +34,7 @@ export class ImageService {
}
getImageMetadata(imageId: string): Observable<any> {
const token = this.localStorageService.getToken();
const headers = new HttpHeaders({
'Authorization': `Bearer ${token}`
});
const headers = this.authService.getAuthHeaders();
return this.http.get(`${this.apiUrl}/image/${imageId}/metadata`, { headers });
}

@ -1,21 +0,0 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../environment';
@Injectable({
providedIn: 'root',
})
export class LoginService {
private apiUrl = environment.apiURL;
constructor(private http: HttpClient) {}
login(username: string, password: string): Observable<any> {
const payload = new HttpParams()
.set('username', username)
.set('password', password);
return this.http.post(this.apiUrl + '/login', payload);
}
}

@ -4,6 +4,7 @@ import { switchMap } from 'rxjs';
import { environment } from '../../../environment';
import { Pin } from '../../model/Pin';
import { AutocompleteService } from '../auto-complete/auto-complete.service';
import { AuthService } from '../auth/auth.service';
// import { ImageService } from '../image/image.service';
@Injectable({
@ -17,24 +18,23 @@ export class PinService {
constructor(
private http: HttpClient,
private autoCompleteService: AutocompleteService // private imageService: ImageService
private autoCompleteService: AutocompleteService,
private authService: AuthService
) {}
getPins(): any {
const url = `${this.apiURL}/pins`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.get<any>(url, { headers });
}
addPin(pin: Pin) {
const url = `${this.apiURL}/pin/add`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post<any>(
url, pin, { headers }
);
@ -45,10 +45,9 @@ export class PinService {
pin: Pin
) {
const url = `${this.apiURL}/pin/${id}`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
// Obtenir les coordonnées GPS à partir de l'adresse
return this.http.patch<any>(
@ -58,19 +57,17 @@ export class PinService {
deletePin(id: string) {
const url = `${this.apiURL}/pin/${id}`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.delete<any>(url, { headers });
}
sharePin(pinId: string, friendId: string) {
const url = `${this.apiURL}/pin/${pinId}/share`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post<any>(url, { friend_id: friendId }, { headers });
}
}

@ -1,16 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { RegisterService } from './register.service';
describe('RegisterService', () => {
let service: RegisterService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(RegisterService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

@ -1,17 +0,0 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../environment';
@Injectable({
providedIn: 'root',
})
export class RegisterService {
private apiUrl = environment.apiURL;
constructor(private http: HttpClient) {}
register(username: string, password: string): Observable<any> {
return this.http.post(this.apiUrl + '/register', { username, password });
}
}

@ -1,6 +1,7 @@
import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from '../../../environment';
import { AuthService } from '../auth/auth.service';
@Injectable({
providedIn: 'root'
@ -8,15 +9,14 @@ import { environment } from '../../../environment';
export class UserService {
private apiURL = environment.apiURL;
constructor(private http: HttpClient) {
constructor(private http: HttpClient, private authService: AuthService) {
}
getUser(username:string) {
const url = `${this.apiURL}/users`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('auth_token'),
});
const headers = this.authService.getAuthHeaders();
headers.set('Content-Type', 'application/json');
const params = { name : username };
return this.http.get<any[]>(url,{ headers:headers, params:params })

Loading…
Cancel
Save