From a10b4855ace5c9d824f142c659efd525efd5aa13 Mon Sep 17 00:00:00 2001 From: kshitij-k-osmosys Date: Mon, 28 Oct 2024 22:39:01 +0530 Subject: [PATCH 1/3] feat: handle graphql errors --- .../views/applications/application.model.ts | 3 ++ .../applications/applications.service.ts | 1 + .../notifications/notifications.component.ts | 29 ++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/apps/portal/src/app/views/applications/application.model.ts b/apps/portal/src/app/views/applications/application.model.ts index bb270d75..49fd8ba2 100644 --- a/apps/portal/src/app/views/applications/application.model.ts +++ b/apps/portal/src/app/views/applications/application.model.ts @@ -1,3 +1,5 @@ +import { GraphQLFormattedError } from 'graphql/error/GraphQLError'; + export interface Application { applicationId: number; name: string; @@ -12,4 +14,5 @@ export interface ApplicationResponse { total: number; offset: number; limit: number; + errors?: ReadonlyArray; } diff --git a/apps/portal/src/app/views/applications/applications.service.ts b/apps/portal/src/app/views/applications/applications.service.ts index 6ee53b2f..acc15b21 100644 --- a/apps/portal/src/app/views/applications/applications.service.ts +++ b/apps/portal/src/app/views/applications/applications.service.ts @@ -29,6 +29,7 @@ export class ApplicationsService { total: response.data?.applications.total, offset: response.data?.applications.offset, limit: response.data?.applications.limit, + errors: response.errors || null, }; return applicationResponseObject; }), diff --git a/apps/portal/src/app/views/notifications/notifications.component.ts b/apps/portal/src/app/views/notifications/notifications.component.ts index e7877238..83480c74 100644 --- a/apps/portal/src/app/views/notifications/notifications.component.ts +++ b/apps/portal/src/app/views/notifications/notifications.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { ChannelType, ChannelTypeMap, DeliveryStatus } from 'src/common/constants/notification'; import { LazyLoadEvent, MessageService } from 'primeng/api'; import { catchError, of } from 'rxjs'; +import { AuthService } from 'src/app/auth/auth.service'; import { NotificationsService } from './notifications.service'; import { Notification, NotificationResponse } from './notification.model'; import { ApplicationsService } from '../applications/applications.service'; @@ -83,6 +84,7 @@ export class NotificationsComponent implements OnInit { private notificationService: NotificationsService, private applicationService: ApplicationsService, private messageService: MessageService, + private authService: AuthService, ) {} ngOnInit(): void { @@ -121,7 +123,32 @@ export class NotificationsComponent implements OnInit { }), ) .subscribe((applicationResponse: ApplicationResponse | null) => { - if (applicationResponse && applicationResponse.applications) { + if (applicationResponse.errors) { + const unauthorizedError = applicationResponse.errors.find( + (error) => error.message === 'Unauthorized', + ); + + this.applications = []; + this.selectedApplication = null; + + if (unauthorizedError) { + this.messageService.add({ + key: 'tst', + severity: 'error', + summary: 'Error', + detail: 'Unauthorized access. Please log in again.', + }); + } else { + applicationResponse.errors.forEach((error) => { + this.messageService.add({ + key: 'tst', + severity: 'error', + summary: 'Error', + detail: `GraphQL Error - Get Applications: ${error.message}`, + }); + }); + } + } else if (applicationResponse && applicationResponse.applications) { // Fetch list of applications for dropdown this.applications = applicationResponse.applications.map((obj) => ({ // Name to display and ID to return upon selection From 7b6087424cf968f75c074d3f28399cb861866b69 Mon Sep 17 00:00:00 2001 From: kshitij-k-osmosys Date: Mon, 28 Oct 2024 22:39:40 +0530 Subject: [PATCH 2/3] feat: add logout service fn --- apps/portal/src/app/auth/auth.service.ts | 12 +++++++++++- .../views/notifications/notifications.component.ts | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/portal/src/app/auth/auth.service.ts b/apps/portal/src/app/auth/auth.service.ts index 03fdeceb..dda278d6 100644 --- a/apps/portal/src/app/auth/auth.service.ts +++ b/apps/portal/src/app/auth/auth.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { MutationResult } from 'apollo-angular'; +import { Router } from '@angular/router'; import { GraphqlService } from '../graphql/graphql.service'; import { LoginUser } from '../graphql/graphql.queries'; import { LoginRequestBody } from './auth.interface'; @@ -13,7 +14,10 @@ const SESSION_EXPIRATION_DAYS = 30; export class AuthService { userData = null; - constructor(private graphqlService: GraphqlService) {} + constructor( + private graphqlService: GraphqlService, + private router: Router, + ) {} isLoggedIn(): boolean { this.userData = JSON.parse(localStorage.getItem('osmoXUserData')); @@ -38,4 +42,10 @@ export class AuthService { const variables = { username: data.username, password: data.password }; return this.graphqlService.mutate(LoginUser, variables); } + + logoutUser(): void { + // Clear storage and navigate to login + localStorage.clear(); + this.router.navigate(['/login']); + } } diff --git a/apps/portal/src/app/views/notifications/notifications.component.ts b/apps/portal/src/app/views/notifications/notifications.component.ts index 83480c74..c6c901ae 100644 --- a/apps/portal/src/app/views/notifications/notifications.component.ts +++ b/apps/portal/src/app/views/notifications/notifications.component.ts @@ -138,6 +138,7 @@ export class NotificationsComponent implements OnInit { summary: 'Error', detail: 'Unauthorized access. Please log in again.', }); + this.authService.logoutUser(); } else { applicationResponse.errors.forEach((error) => { this.messageService.add({ From 9c913fbdec92ca85ecb0d6d62726343d8ff65083 Mon Sep 17 00:00:00 2001 From: kshitij-k-osmosys Date: Sun, 3 Nov 2024 22:25:53 +0530 Subject: [PATCH 3/3] fix: applicationResponse conditions, logout --- apps/portal/src/app/auth/auth.service.ts | 14 +++++++++++--- .../views/notifications/notifications.component.ts | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/portal/src/app/auth/auth.service.ts b/apps/portal/src/app/auth/auth.service.ts index dda278d6..2a7cbbdd 100644 --- a/apps/portal/src/app/auth/auth.service.ts +++ b/apps/portal/src/app/auth/auth.service.ts @@ -44,8 +44,16 @@ export class AuthService { } logoutUser(): void { - // Clear storage and navigate to login - localStorage.clear(); - this.router.navigate(['/login']); + try { + // Ensure complete cleanup of sensitive data + localStorage.clear(); + sessionStorage.clear(); + this.userData = null; + + this.router.navigate(['/login']); + } catch (error) { + // Still attempt to navigate even if cleanup fails + this.router.navigate(['/login']); + } } } diff --git a/apps/portal/src/app/views/notifications/notifications.component.ts b/apps/portal/src/app/views/notifications/notifications.component.ts index c6c901ae..b8d0470d 100644 --- a/apps/portal/src/app/views/notifications/notifications.component.ts +++ b/apps/portal/src/app/views/notifications/notifications.component.ts @@ -123,7 +123,7 @@ export class NotificationsComponent implements OnInit { }), ) .subscribe((applicationResponse: ApplicationResponse | null) => { - if (applicationResponse.errors) { + if (applicationResponse?.errors?.length) { const unauthorizedError = applicationResponse.errors.find( (error) => error.message === 'Unauthorized', ); @@ -149,7 +149,7 @@ export class NotificationsComponent implements OnInit { }); }); } - } else if (applicationResponse && applicationResponse.applications) { + } else if (applicationResponse?.applications?.length) { // Fetch list of applications for dropdown this.applications = applicationResponse.applications.map((obj) => ({ // Name to display and ID to return upon selection