Skip to content

Commit bbce3e0

Browse files
authored
fix(logout): logout user properly when token expires and cannot be refreshed (#263)
1 parent 7f4beed commit bbce3e0

7 files changed

Lines changed: 41 additions & 35 deletions

File tree

src/app/app.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<bae-header></bae-header>
2+
<app-notification></app-notification>
23

34
<div class="app-content">
45
<main class="bg-no-repeat bg-right">

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { FaIconComponent, FontAwesomeModule } from '@fortawesome/angular-fontawe
88
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
99
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
1010
import { NgxFileDropModule } from 'ngx-file-drop';
11+
import { NotificationComponent } from './shared/notification/notification.component';
1112
import { MarkdownModule } from 'ngx-markdown';
1213
import { MatomoInitializationMode, MatomoInitializerService, MatomoModule, MatomoRouterModule } from 'ngx-matomo-client';
1314
import { CartCardComponent } from 'src/app/shared/cart-card/cart-card.component';
@@ -170,6 +171,7 @@ import { RequestValidationModalComponent } from './pages/seller-offerings/offeri
170171
PickerComponent,
171172
NgxFileDropModule,
172173
ChatbotWidgetComponent,
174+
NotificationComponent,
173175
QuotesModule,
174176
MarkdownModule.forRoot(),
175177
TranslateModule.forRoot({

src/app/features/quotes/pages/quote-details/quote-details.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ import { ActivatedRoute, Router } from '@angular/router';
44
import { QuoteService } from '../../services/quote.service';
55
import { NotificationService } from 'src/app/services/notification.service';
66
import { Quote } from 'src/app/models/quote.model';
7-
import { NotificationComponent } from 'src/app/shared/notification/notification.component';
87
import { ConfirmDialogComponent } from 'src/app/shared/confirm-dialog/confirm-dialog.component';
98

109
@Component({
1110
selector: 'app-quote-details',
1211
standalone: true,
13-
imports: [CommonModule, NotificationComponent, ConfirmDialogComponent],
12+
imports: [CommonModule, ConfirmDialogComponent],
1413
template: `
15-
<app-notification></app-notification>
16-
1714
<div class="container mx-auto px-4 py-8" *ngIf="quote">
1815
<div class="bg-white shadow-md rounded-lg p-6">
1916
<div class="flex justify-between items-center mb-6">

src/app/features/quotes/pages/quote-form/quote-form.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@ import { ActivatedRoute, Router } from '@angular/router';
55
import { QuoteService } from '../../services/quote.service';
66
import { NotificationService } from 'src/app/services/notification.service';
77
import { Quote } from 'src/app/models/quote.model';
8-
import { NotificationComponent } from 'src/app/shared/notification/notification.component';
98
import { ConfirmDialogComponent } from 'src/app/shared/confirm-dialog/confirm-dialog.component';
109

1110
@Component({
1211
selector: 'app-quote-form',
1312
standalone: true,
14-
imports: [CommonModule, ReactiveFormsModule, NotificationComponent, ConfirmDialogComponent],
13+
imports: [CommonModule, ReactiveFormsModule, ConfirmDialogComponent],
1514
template: `
16-
<app-notification></app-notification>
17-
1815
<div class="container mx-auto px-4 py-8">
1916
<div class="max-w-3xl mx-auto">
2017
<div class="bg-white shadow-md rounded-lg p-6">

src/app/features/quotes/pages/quote-list/quote-list.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { NotificationService } from 'src/app/services/notification.service';
1010
import { AccountServiceService } from 'src/app/services/account-service.service';
1111
import { ApiServiceService } from 'src/app/services/product-service.service';
1212
import { Quote, QuoteStateType } from 'src/app/models/quote.model';
13-
import { NotificationComponent } from 'src/app/shared/notification/notification.component';
1413
import { ConfirmDialogComponent } from 'src/app/shared/confirm-dialog/confirm-dialog.component';
1514
import { QuoteDetailsModalComponent } from 'src/app/shared/quote-details-modal/quote-details-modal.component';
1615
import { ChatModalComponent } from 'src/app/shared/chat-modal/chat-modal.component';
@@ -22,10 +21,8 @@ import { environment } from 'src/environments/environment';
2221
@Component({
2322
selector: 'app-quote-list',
2423
standalone: true,
25-
imports: [CommonModule, FormsModule, NotificationComponent, ConfirmDialogComponent, QuoteDetailsModalComponent, ChatModalComponent, AttachmentModalComponent],
24+
imports: [CommonModule, FormsModule, ConfirmDialogComponent, QuoteDetailsModalComponent, ChatModalComponent, AttachmentModalComponent],
2625
template: `
27-
<app-notification></app-notification>
28-
2926
<div class="w-full mx-auto px-6 py-8">
3027
<div class="flex justify-between items-center mb-6">
3128
<div class="flex items-center gap-3">

src/app/features/tenders/pages/tender-list/tender-list.component.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { Tender, TenderAttachment, TenderStateType } from 'src/app/models/tender
1212
import { Quote, QuoteStateType } from 'src/app/models/quote.model';
1313
import { environment } from 'src/environments/environment';
1414
import { LoginInfo } from 'src/app/models/interfaces';
15-
import { NotificationComponent } from 'src/app/shared/notification/notification.component';
1615
import { ConfirmDialogComponent } from 'src/app/shared/confirm-dialog/confirm-dialog.component';
1716
import { QuoteDetailsModalComponent } from 'src/app/shared/quote-details-modal/quote-details-modal.component';
1817
import { ChatModalComponent } from 'src/app/shared/chat-modal/chat-modal.component';
@@ -27,16 +26,13 @@ import { COORDINATOR_STATUS_MESSAGES, QUOTE_CATEGORIES, QUOTE_STATUSES, TENDERIN
2726
imports: [
2827
CommonModule,
2928
FormsModule,
30-
NotificationComponent,
3129
ConfirmDialogComponent,
3230
QuoteDetailsModalComponent,
3331
ChatModalComponent,
3432
AttachmentModalComponent,
3533
CreateTenderModalComponent
3634
],
3735
template: `
38-
<app-notification></app-notification>
39-
4036
<div class="min-h-screen bg-[#F7F9FD] font-[Blinker]" (click)="closeStatusDropdown()">
4137
<div class="mx-auto max-w-[1440px] px-6 py-8 sm:px-10 lg:px-20 xl:px-[160px]">
4238
<div class="mb-6 flex flex-wrap items-center justify-between gap-4">

src/app/services/refresh-login-service.service.ts

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Injectable } from '@angular/core';
2-
import { Observable, Subscription, interval } from 'rxjs';
2+
import { Router } from '@angular/router';
33
import * as moment from 'moment';
4-
import {LocalStorageService} from "./local-storage.service";
5-
import { LoginInfo } from '../models/interfaces';
4+
import { Observable, Subscription, interval } from 'rxjs';
65
import { LoginServiceService } from 'src/app/services/login-service.service';
7-
import { environment } from "src/environments/environment";
8-
import { Router } from '@angular/router';
6+
import { LoginInfo } from '../models/interfaces';
7+
import { EventMessageService } from './event-message.service';
8+
import { LocalStorageService } from "./local-storage.service";
9+
import { NotificationService } from './notification.service';
910

1011
@Injectable({
1112
providedIn: 'root'
@@ -17,12 +18,14 @@ export class RefreshLoginServiceService {
1718
constructor(
1819
private localStorage: LocalStorageService,
1920
private api: LoginServiceService,
20-
private router: Router
21-
) {
21+
private router: Router,
22+
private eventMessage: EventMessageService,
23+
private notificationService: NotificationService
24+
) {
2225
//this.intervalObservable = interval(1000); // Default interval duration set to 1000 milliseconds (1 second)
2326
}
2427

25-
startInterval(intervalDuration: number, data:any): void {
28+
startInterval(intervalDuration: number, data: any): void {
2629
this.intervalObservable = interval(intervalDuration);
2730

2831
this.intervalSubscription = this.intervalObservable.subscribe(() => {
@@ -45,18 +48,13 @@ export class RefreshLoginServiceService {
4548
// Start the interval only if the token has been really refreshed
4649
// Otherwise close the session
4750
if (refreshed.expire > moment().unix() + 4) {
48-
this.startInterval(((refreshed.expire - moment().unix())-4)*1000, refreshed)
51+
this.startInterval(((refreshed.expire - moment().unix()) - 4) * 1000, refreshed)
4952
} else {
50-
this.stopInterval();
51-
this.localStorage.setObject('login_items',{});
52-
this.api.logout().catch((err) => {
53-
})
54-
55-
this.router.navigate(['/dashboard']).then(() => {
56-
window.location.reload()
57-
}).catch((err) => {
58-
})
53+
this.logout();
5954
}
55+
}).catch(error => {
56+
console.error('Error refreshing token', error);
57+
this.logout();
6058
})
6159
});
6260
}
@@ -66,4 +64,22 @@ export class RefreshLoginServiceService {
6664
this.intervalSubscription.unsubscribe();
6765
}
6866
}
69-
}
67+
68+
private logout(): void {
69+
this.stopInterval();
70+
// Only logout if user is logged
71+
const aux = this.localStorage.getObject('login_items') as any;
72+
if (aux && Object.keys(aux).length > 0) {
73+
this.localStorage.setObject('login_items', {});
74+
this.eventMessage.emitLogin({} as LoginInfo);
75+
this.api.logout()
76+
.catch((err) => {
77+
console.error('Error during logout:', err);
78+
})
79+
80+
this.router.navigate(['/dashboard']).then(() => {
81+
this.notificationService.showInfo('Your session has expired. Please log in again.');
82+
})
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)