fix: clear currentUserCache on logout to ensure correct state
This commit is contained in:
parent
d18e8e5e11
commit
2632f859fe
4 changed files with 44 additions and 3 deletions
|
|
@ -4,24 +4,37 @@ import { map, Observable } from 'rxjs';
|
||||||
import { AuthService } from '../services/auth.service';
|
import { AuthService } from '../services/auth.service';
|
||||||
import { TokenService } from '../services/token.service';
|
import { TokenService } from '../services/token.service';
|
||||||
import { ToastNotificationService } from '../services/toast-notification.service';
|
import { ToastNotificationService } from '../services/toast-notification.service';
|
||||||
|
import { UserService } from '../services/user.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AuthenticatedGuard implements CanActivate {
|
export class AuthenticatedGuard implements CanActivate {
|
||||||
constructor(
|
constructor(
|
||||||
|
private userService: UserService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private tokenService: TokenService,
|
private tokenService: TokenService,
|
||||||
private toastNotificationService: ToastNotificationService,
|
private toastNotificationService: ToastNotificationService,
|
||||||
private router: Router
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the route can be activated based on the user's authentication status.
|
||||||
|
*
|
||||||
|
* This method checks if the user's token and user ID are available. If either is unavailable,
|
||||||
|
* it navigates to the login page, resets the user cache, and displays a session expired toast.
|
||||||
|
* If both are available, it checks the user's authentication status and returns it.
|
||||||
|
*
|
||||||
|
* @returns {Observable<boolean> | Promise<boolean> | boolean} An observable, promise, or boolean
|
||||||
|
* indicating whether the route can be activated.
|
||||||
|
*/
|
||||||
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
|
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
|
||||||
if (
|
if (
|
||||||
!this.tokenService.isTokenAvailable() ||
|
!this.tokenService.isTokenAvailable() ||
|
||||||
!this.tokenService.isUserIdAvailable()
|
!this.tokenService.isUserIdAvailable()
|
||||||
) {
|
) {
|
||||||
this.router.navigate(['/login']);
|
this.router.navigate(['/login']);
|
||||||
|
this.userService.resetUserCache();
|
||||||
this.toastNotificationService.showSessionExpiredToast();
|
this.toastNotificationService.showSessionExpiredToast();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,29 @@ export class UserService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the current user cache and emits a null value to the current user Observable.
|
||||||
|
*/
|
||||||
|
resetUserCache(): void {
|
||||||
|
this.currentUserCache = null;
|
||||||
|
this.currentUserSubject.next(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of all users from the API.
|
||||||
|
*
|
||||||
|
* @returns An Observable resolving to the list of all users.
|
||||||
|
*/
|
||||||
getUsers(): Observable<User[]> {
|
getUsers(): Observable<User[]> {
|
||||||
return this.apiService.getUsers();
|
return this.apiService.getUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a user by its ID from the API.
|
||||||
|
*
|
||||||
|
* @param userId The ID of the user to be retrieved.
|
||||||
|
* @returns An Observable resolving to the user with the given ID, or an empty Observable if the user does not exist.
|
||||||
|
*/
|
||||||
getUserById(userId: string): Observable<User> {
|
getUserById(userId: string): Observable<User> {
|
||||||
return this.apiService.getUserById(userId);
|
return this.apiService.getUserById(userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { LanguageService } from '../../../../services/language.service';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { AuthService } from '../../../../services/auth.service';
|
import { AuthService } from '../../../../services/auth.service';
|
||||||
|
import { UserService } from '../../../../services/user.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar',
|
selector: 'app-navbar',
|
||||||
|
|
@ -21,12 +22,11 @@ export class NavbarComponent {
|
||||||
constructor(
|
constructor(
|
||||||
public langService: LanguageService,
|
public langService: LanguageService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
private userService: UserService,
|
||||||
private authService: AuthService
|
private authService: AuthService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lifecycle hook that is called after the component has been initialized.
|
|
||||||
*
|
|
||||||
* Sets the currentRoute property to the current route's url.
|
* Sets the currentRoute property to the current route's url.
|
||||||
*/
|
*/
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
@ -40,6 +40,7 @@ export class NavbarComponent {
|
||||||
* data, and navigate the user to the logout page.
|
* data, and navigate the user to the logout page.
|
||||||
*/
|
*/
|
||||||
logout() {
|
logout() {
|
||||||
|
this.userService.resetUserCache();
|
||||||
this.authService.logout();
|
this.authService.logout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { LanguageService } from '../../../services/language.service';
|
import { LanguageService } from '../../../services/language.service';
|
||||||
import { AuthService } from '../../../services/auth.service';
|
import { AuthService } from '../../../services/auth.service';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
import { UserService } from '../../../services/user.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-sidebar',
|
selector: 'app-sidebar',
|
||||||
|
|
@ -20,17 +21,23 @@ export class SidebarComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
private userService: UserService,
|
||||||
public languageService: LanguageService,
|
public languageService: LanguageService,
|
||||||
private authService: AuthService
|
private authService: AuthService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the getCurrentPath method to set the currentPath property to the current route's url.
|
* Calls the getCurrentPath method to set the currentPath property to the
|
||||||
|
* current route's url.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.getCurrentPath();
|
this.getCurrentPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits a value to the `destroy$` subject and completes it to clean up
|
||||||
|
* any subscriptions and prevent memory leaks.
|
||||||
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
|
|
@ -56,6 +63,7 @@ export class SidebarComponent implements OnInit, OnDestroy {
|
||||||
* data, and navigate the user to the logout page.
|
* data, and navigate the user to the logout page.
|
||||||
*/
|
*/
|
||||||
logout() {
|
logout() {
|
||||||
|
this.userService.resetUserCache();
|
||||||
this.authService.logout();
|
this.authService.logout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue