From 41a1097088fc9f49eccf4af263921d888838fdab Mon Sep 17 00:00:00 2001 From: Algirdas Date: Sat, 18 Jul 2026 12:47:23 +0300 Subject: [PATCH] fix(frontend): enhance error handling and update UI styling - Enable error messages in JWT strategy configuration - Update outline color in theme - Add background class for dialog footer - Use token filter to handle public auth requests in interceptor - Style nb-card-header icon buttons for transparency --- .../app/interceptors/unauthorized.interceptor.ts | 16 +++++++++------- frontend/src/app/modules/auth/auth.module.ts | 2 +- .../statement-review-dialog.component.html | 2 +- frontend/src/styles.scss | 13 +++++++++++++ frontend/src/theme.scss | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/interceptors/unauthorized.interceptor.ts b/frontend/src/app/interceptors/unauthorized.interceptor.ts index a099ec81..46b5c40e 100644 --- a/frontend/src/app/interceptors/unauthorized.interceptor.ts +++ b/frontend/src/app/interceptors/unauthorized.interceptor.ts @@ -1,10 +1,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { NbTokenService } from '@nebular/auth'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; +import { tokenFilter } from '../modules/auth/token.filter'; @Injectable() export class UnauthorizedInterceptor implements HttpInterceptor { @@ -14,13 +15,14 @@ export class UnauthorizedInterceptor implements HttpInterceptor { public intercept(req: HttpRequest, next: HttpHandler): Observable> { return next.handle(req).pipe( catchError((error: HttpErrorResponse) => { - // A 401 from the refresh endpoint means the refresh token itself - // is invalid/consumed; it is handled by the auth layer, so do not - // clear tokens here (that caused spurious logouts under the - // single-use refresh token race on app resume). - const isRefreshRequest = req.url.includes('/auth/refresh-token'); + // A 401 from a public auth endpoint (login, refresh-token) is not a + // session expiry - it means the submitted credentials or refresh + // token were rejected. The auth layer handles those (login form + // error message; refresh race on resume), so do not clear tokens + // or redirect here. + const isPublicAuthRequest = tokenFilter(req); - if (error.status === 401 && !isRefreshRequest) { + if (error.status === 401 && !isPublicAuthRequest) { this.tokenService.clear(); this.router.navigate(['auth/login']); } diff --git a/frontend/src/app/modules/auth/auth.module.ts b/frontend/src/app/modules/auth/auth.module.ts index d072641e..a0acea52 100644 --- a/frontend/src/app/modules/auth/auth.module.ts +++ b/frontend/src/app/modules/auth/auth.module.ts @@ -43,7 +43,7 @@ export class AuthModule { rememberMe: false, strategy: 'jwt', showMessages: { - error: false, + error: true, }, }, register: { diff --git a/frontend/src/app/modules/main/dialogs/statement-review-dialog/statement-review-dialog.component.html b/frontend/src/app/modules/main/dialogs/statement-review-dialog/statement-review-dialog.component.html index 3c499f1a..a2ebf867 100644 --- a/frontend/src/app/modules/main/dialogs/statement-review-dialog/statement-review-dialog.component.html +++ b/frontend/src/app/modules/main/dialogs/statement-review-dialog/statement-review-dialog.component.html @@ -51,7 +51,7 @@ } - +