fix: clear currentUserCache on logout to ensure correct state

This commit is contained in:
Chneemann 2025-04-13 12:46:58 +02:00
parent d18e8e5e11
commit 2632f859fe
4 changed files with 44 additions and 3 deletions

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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();
} }
} }

View file

@ -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();
} }
} }