Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: log out of portal when no JWTLoginToken exist in localstorage #383

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

kshitij-k-osmosys
Copy link
Contributor

@kshitij-k-osmosys kshitij-k-osmosys commented Jan 17, 2025

Portal PR Checklist

Pre-requisites

  • I have gone through the Contributing guidelines for Submitting a Pull Request (PR) and ensured that this is not a duplicate PR.
  • I have performed unit testing for the new feature added or updated to ensure the new features added are working as expected.
  • I have performed preliminary testing to ensure that any existing features are not impacted and any new features are working as expected as a whole.

PR Details

PR details have been updated as per the given format (see below)

  • PR title adheres to the format specified in guidelines (e.g., feat: add admin login page)
  • Description has been added
  • Related changes have been added (optional)
  • Screenshots have been added (optional, may include unit testing screenshots as well)
  • Pending actions have been added (optional)
  • Any other additional notes have been added (optional)

Additional Information

  • Appropriate label(s) have been added (ready for review should be added if the PR is ready to be reviewed)
  • Assignee(s) and reviewer(s) have been added (optional)

Note: Reviewer should ensure that the checklist and description have been populated and followed correctly, and the PR should be merged only after resolving all conversations and verifying that CI checks pass.


Description:

Add function authService.logoutUser to log users out when LoginToken check fails i.e. when there is no JWTLoginToken in localstorage

Summary by CodeRabbit

  • New Features

    • Added GraphQL queries to retrieve providers and notifications
    • Enhanced notifications view with provider-based filtering
    • Introduced new service for managing providers and notifications
  • Bug Fixes

    • Improved type safety for method parameters in various services
  • Refactor

    • Updated notification component to support provider-based data loading
    • Centralized notification filter logic
    • Added new data models for providers and notifications

@kshitij-k-osmosys kshitij-k-osmosys self-assigned this Jan 17, 2025
Copy link

coderabbitai bot commented Jan 17, 2025

Walkthrough

This pull request introduces a comprehensive enhancement to the notifications and providers management system. The changes focus on integrating provider data with notification handling, adding new GraphQL queries, updating service methods, and modifying the frontend components. The modifications improve type safety, expand data retrieval capabilities, and provide more flexible filtering options for users when interacting with notifications and providers.

Changes

File Change Summary
apps/portal/src/app/graphql/graphql.queries.ts Added two new GraphQL queries: GetProvidersAndNotifications and GetProvidersAndArchivedNotifications for fetching providers and notifications
apps/portal/src/app/views/applications/applications.service.ts Updated getApplications method with explicit type annotations for variables and inputToken
apps/portal/src/app/views/notifications/notifications.component.html Replaced channel type dropdown with provider dropdown, updated event handler for application selection
apps/portal/src/app/views/notifications/notifications.component.ts Added provider-related properties, new methods for loading providers and notifications, enhanced initialization process
apps/portal/src/app/views/notifications/notifications.service.ts Updated getNotifications method signature with explicit type annotations
apps/portal/src/app/views/providers/provider.model.ts Added new interfaces Provider and ProviderAndNotificationResponse
apps/portal/src/app/views/providers/providers.service.ts Created new ProvidersService with methods for fetching providers and notifications

Sequence Diagram

sequenceDiagram
    participant User
    participant NotificationsComponent
    participant ProvidersService
    participant GraphQL

    User->>NotificationsComponent: Select Application
    NotificationsComponent->>ProvidersService: getProvidersAndNotifications()
    ProvidersService->>GraphQL: Query Providers and Notifications
    GraphQL-->>ProvidersService: Return Response
    ProvidersService-->>NotificationsComponent: Populate Providers and Notifications
    NotificationsComponent->>User: Display Updated Data
Loading

Poem

🐰 Hop, hop, notifications dance!
Providers join the data's advance
Filters refined, queries so bright
Our portal leaps with pure delight
Code rabbit sings of progress true! 🚀

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kshitij-k-osmosys kshitij-k-osmosys changed the title feat: log out of portal when no logintoken exists feat: log out of portal when no JWTLoginToken exist in localstorage Jan 17, 2025
@kshitij-k-osmosys kshitij-k-osmosys marked this pull request as ready for review January 17, 2025 09:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
apps/portal/src/app/views/applications/applications.service.ts (1)

Line range hint 39-58: Consider enhancing token validation.

While not part of the current changes, given the PR's focus on JWT token handling, consider these improvements to the decodeToken method:

  1. Add token expiration validation
  2. Consider making this a static method since it doesn't use instance properties
  3. Add signature verification if security is critical

Example enhancement:

static decodeToken(token: string): {
  payload: any;
  isValid: boolean;
  error?: string;
} {
  try {
    const [header, payload, signature] = token.split('.');
    const decodedPayload = JSON.parse(atob(payload));
    
    // Add expiration check
    const isExpired = decodedPayload.exp && Date.now() >= decodedPayload.exp * 1000;
    
    return {
      payload: decodedPayload,
      isValid: !isExpired,
      error: isExpired ? 'Token has expired' : undefined
    };
  } catch (error) {
    return {
      payload: null,
      isValid: false,
      error: `Invalid token: ${error.message}`
    };
  }
}
apps/portal/src/app/views/providers/providers.service.ts (2)

12-40: Combine response interfaces to reduce duplication.

The interfaces GetProviderNotificationResponse and GetProviderArchivedNotificationResponse share a similar structure. Consider creating a generic interface or type to handle both cases, which will improve maintainability and reduce code duplication.

You can define a generic interface like this:

interface GetProviderResponse<T> {
  providers: {
    providers?: Provider[];
    total?: number;
    offset?: number;
    limit?: number;
  };
  notifications: {
    notifications?: T[];
    total?: number;
    offset?: number;
    limit?: number;
  };
}

Then, you can use it with the specific notification types:

type GetProviderNotificationResponse = GetProviderResponse<Notification>;
type GetProviderArchivedNotificationResponse = GetProviderResponse<ArchivedNotification>;

53-118: Refactor to eliminate duplicated logic in getProvidersAndNotifications.

The method contains duplicated code in both the if and else blocks, particularly in processing the response and handling errors. Refactoring the common logic into helper functions will enhance readability and maintainability.

You can refactor the mapping and error handling like this:

private handleResponse<T>(
  response: ApolloQueryResult<T>,
  isArchived: boolean,
): ProviderAndNotificationResponse {
  // Common mapping logic here
}

private handleError(error: any): Observable<never> {
  const errorMessage: string = error.message;
  throw new Error(errorMessage);
}

Then, update your method:

getProvidersAndNotifications(
  variables: unknown,
  inputToken: string,
  archivedNotificationToggle: boolean,
): Observable<ProviderAndNotificationResponse> {
  const query = archivedNotificationToggle
    ? GetProvidersAndArchivedNotifications
    : GetProvidersAndNotifications;

  return this.graphqlService.query(query, variables, inputToken).pipe(
    map((response) =>
      this.handleResponse(response, archivedNotificationToggle),
    ),
    catchError((error) => this.handleError(error)),
  );
}
apps/portal/src/app/views/notifications/notifications.component.ts (1)

Line range hint 212-222: Simplify error handling in getJWTLoginToken method.

Throwing and catching an error within the same method can be simplified. Instead, return null directly when userData is not found, and handle JSON parsing errors separately.

Apply this diff to simplify the method:

getJWTLoginToken() {
  try {
    const userData = localStorage.getItem('osmoXUserData');

    if (userData) {
      const userToken = JSON.parse(userData).token;
      return userToken;
    }

-   throw new Error('User data not found in localStorage');
+   this.messageService.add({
+     key: 'tst',
+     severity: 'warn',
+     summary: 'Warning',
+     detail: 'User data not found in localStorage',
+   });
+   return null;
  } catch (error) {
    this.messageService.add({
      key: 'tst',
      severity: 'error',
      summary: 'Error',
      detail: `Error parsing user data: ${error.message}`,
    });
    return null;
  }
}
apps/portal/src/app/views/notifications/notifications.service.ts (1)

Line range hint 47-47: Apply similar type safety improvements to getArchivedNotifications.

For consistency, consider applying the same type safety improvements to the getArchivedNotifications method.

-  getArchivedNotifications(variables, inputToken): Observable<NotificationResponse> {
+  getArchivedNotifications(variables: unknown, inputToken: string): Observable<NotificationResponse> {
apps/portal/src/app/graphql/graphql.queries.ts (1)

97-154: LGTM! Well-structured combined query.

The query effectively combines providers and notifications data with proper pagination, sorting, and comprehensive field selection.

Consider query optimization.

Consider making some fields optional or adding field selection arguments to optimize response size based on usage.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca08424 and 65c6bc7.

📒 Files selected for processing (7)
  • apps/portal/src/app/graphql/graphql.queries.ts (1 hunks)
  • apps/portal/src/app/views/applications/applications.service.ts (1 hunks)
  • apps/portal/src/app/views/notifications/notifications.component.html (2 hunks)
  • apps/portal/src/app/views/notifications/notifications.component.ts (10 hunks)
  • apps/portal/src/app/views/notifications/notifications.service.ts (1 hunks)
  • apps/portal/src/app/views/providers/provider.model.ts (1 hunks)
  • apps/portal/src/app/views/providers/providers.service.ts (1 hunks)
🔇 Additional comments (7)
apps/portal/src/app/views/applications/applications.service.ts (1)

22-22: LGTM! Type safety improvements are well implemented.

The explicit type annotations for both parameters enhance type safety:

  • variables: unknown is safer than an implicit type
  • inputToken: string properly enforces the token type
apps/portal/src/app/views/notifications/notifications.component.ts (1)

486-494: Review date handling logic in filters.

Adding one day to selectedToDate might unintentionally include extra records due to time differences. Consider setting the time to the end of the day or using date libraries for more precise control.

Example adjustment:

if (this.selectedToDate) {
  combinedNotificationFilters.push({
    field: 'createdOn',
    operator: 'lt',
-   value: new Date(
-     new Date(this.selectedToDate).setDate(this.selectedToDate.getDate() + 1),
-   ).toISOString(),
+   value: new Date(
+     this.selectedToDate.setHours(23, 59, 59, 999),
+   ).toISOString(),
  });
}
apps/portal/src/app/views/providers/provider.model.ts (1)

4-11: Ensure correct typing of date fields in Provider interface.

The createdOn and updatedOn fields are typed as Date. If the GraphQL response returns ISO string dates, consider typing these fields as string or transforming them into Date objects after receiving the data.

Adjust the interface or transform the data accordingly:

export interface Provider {
  providerId: number;
  name: string;
  channelType: number;
- createdOn: Date;
- updatedOn: Date;
+ createdOn: string;
+ updatedOn: string;
  status: number;
}

Or transform the strings to Date objects when processing the response.

✅ Verification successful

Use string type for date fields in the Provider interface

The codebase shows a consistent pattern of handling dates as ISO strings in GraphQL responses, with explicit conversion to Date objects when needed. The suggested change to use string type for createdOn and updatedOn fields aligns with this pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find GraphQL schema files
echo "=== Looking for GraphQL schema files ==="
fd -e graphql -e gql

# Search for Provider type definition in GraphQL schemas
echo -e "\n=== Searching for Provider type in GraphQL schemas ==="
rg "type Provider" -A 10

# Search for Provider-related queries
echo -e "\n=== Looking for Provider queries ==="
rg "query.*Provider" -A 5

# Look for date handling patterns
echo -e "\n=== Searching for date transformation patterns ==="
rg "new Date\(" -A 2

Length of output: 24551

apps/portal/src/app/views/notifications/notifications.service.ts (1)

32-32: LGTM! Type safety improvements.

The explicit type annotations for parameters enhance type safety and maintainability.

apps/portal/src/app/graphql/graphql.queries.ts (1)

156-213: LGTM! Consistent query structure.

The archived notifications query maintains consistency with the active notifications query structure.

Verify the need for duplicate provider fields.

Since both queries fetch the same provider fields, consider extracting the provider query into a separate operation if these queries are rarely used together.

✅ Verification successful

Keep the current query structure

The verification shows that these queries are used in a toggle-based manner for switching between active and archived notifications views. While they're never used simultaneously, keeping them structured similarly makes the service layer implementation cleaner and more maintainable. The duplication of provider fields is justified by the tight coupling of these related use cases.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if these queries are used together or separately
rg -l "GetProvidersAndNotifications|GetProvidersAndArchivedNotifications" --type ts

Length of output: 189


Script:

#!/bin/bash
# Check how these queries are used in the service
rg -A 5 -B 5 "GetProvidersAndArchivedNotifications" apps/portal/src/app/views/providers/providers.service.ts

# Look for other queries that might use provider fields
ast-grep --pattern 'providers {
      providers {
        applicationId
        channelType
        createdOn
        name
        providerId
        status
        updatedOn
      }'

Length of output: 1366

apps/portal/src/app/views/notifications/notifications.component.html (2)

9-11: LGTM! Provider selection dropdown.

The dropdown implementation maintains UI consistency while switching from channel types to providers.


55-57: LGTM! Updated event handler.

The event handler properly loads both providers and notifications for the selected application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant