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

fix: fix for integrations on admin dashboard when multiple admins are present #996

Merged
merged 20 commits into from
Oct 3, 2024

Conversation

div360
Copy link
Contributor

@div360 div360 commented Oct 3, 2024

Description

Please add PR description here, add screenshots if needed

Clickup

https://app.clickup.com/t/86cvd6ahx

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new automated deployment workflow for the C1 staging environment.
    • Enhanced authentication handling across multiple components (Intacct, Netsuite, QBO) to manage login parameters more effectively.
  • Bug Fixes

    • Improved redirect logic during login to include additional parameters for better navigation.
    • Enhanced initialization flow to ensure workspace setup is contingent on successful authentication.

These updates streamline the deployment process and enhance user experience by ensuring secure and efficient access to workspaces.

@div360 div360 requested a review from ashwin1111 October 3, 2024 07:05
Copy link
Contributor

coderabbitai bot commented Oct 3, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces a new GitHub Actions workflow for deploying to the C1 staging environment, triggered by pushes to the master branch or specific pull requests. It includes steps for checking out code, pushing Docker images, installing Kustomize, and updating image tags. Additionally, the LoginComponent, IntacctComponent, NetsuiteComponent, and QboComponent are modified to enhance authentication handling through query parameters, refining their initialization logic and redirect processes.

Changes

File Path Change Summary
.github/workflows/c1_staging_deployment.yml New workflow added for automated deployment to C1 staging environment.
src/app/auth/login/login.component.ts Updated redirect and saveUserProfileAndNavigate methods to include a code parameter for enhanced redirect logic.
src/app/integrations/intacct/intacct.component.ts Added handleAuthParameters method for authentication handling; modified ngOnInit to call this method.
src/app/integrations/netsuite/netsuite.component.ts Added handleAuthParameters method for authentication handling; modified ngOnInit to call this method.
src/app/integrations/qbo/qbo.component.ts Added handleAuthParameters method for authentication handling; modified ngOnInit to call this method.

Possibly related PRs

Suggested reviewers

  • ashwin1111
  • DhaaraniCIT

Poem

🐇 In the meadow where code does play,
A workflow blooms to light the way.
With auth in hand, we leap and bound,
As components dance on solid ground.
Hooray for changes, swift and bright,
In the staging night, our code takes flight! 🌙


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 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.

@github-actions github-actions bot added the size/M Medium PR label Oct 3, 2024
Copy link

github-actions bot commented Oct 3, 2024

PR description must contain a link to a ClickUp (case-insensitive)

1 similar comment
Copy link

github-actions bot commented Oct 3, 2024

PR description must contain a link to a ClickUp (case-insensitive)

Copy link
Contributor

@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: 11

🧹 Outside diff range and nitpick comments (5)
.github/workflows/c1_staging_deployment.yml (2)

10-14: LGTM: Job conditions and environment are well-defined.

The job configuration is appropriate for a staging deployment:

  • The conditional execution ensures the job runs only for intended events.
  • The use of ubuntu-latest is standard and appropriate.
  • The QA environment is correctly specified for staging deployment.

Consider breaking the long condition into multiple lines for improved readability:

if: |
  (github.event_name != 'pull_request') || 
  (github.event_name == 'pull_request' && 
   github.event.action == 'labeled' && 
   github.event.label.name == 'c1_staging_deploy')

1-54: Overall assessment: The workflow is well-structured but needs some improvements.

This GitHub Actions workflow for deploying to C1 Staging is generally well-structured and achieves its purpose. However, there are several areas where it can be improved:

  1. Update the versions of GitHub Actions (e.g., checkout action) to the latest stable versions.
  2. Improve the Kustomize installation process for better security and reproducibility.
  3. Address the issue with the $NEW_TAG variable in the final step.
  4. Add error handling to git operations.
  5. Consider breaking long conditions into multiple lines for readability.

Once these improvements are implemented, the workflow will be more robust, secure, and maintainable.

🧰 Tools
🪛 actionlint

16-16: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


31-31: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


40-40: shellcheck reported issue in this script: SC2086:info:3:158: Double quote to prevent globbing and word splitting

(shellcheck)

src/app/integrations/netsuite/netsuite.component.ts (1)

84-85: Ensure consistent naming conventions for query parameters

There is an inconsistency in the naming of query parameters: login_required uses snake_case, while authCode uses camelCase. For better readability and maintainability, it's advisable to use a consistent naming convention for all query parameters throughout the application.

Consider renaming authCode to auth_code to match login_required, or vice versa, depending on the project's naming conventions:

const loginRequired = params.login_required === 'true';
- const authCode = params.authCode;
+ const authCode = params.auth_code;

Ensure that the corresponding query parameter names used elsewhere in the application and backend are updated accordingly.

src/app/integrations/intacct/intacct.component.ts (1)

101-101: Simplify Conditional Check Using Optional Chaining

Consider using the optional chaining operator ?. to simplify the conditional check when accessing Appcues.

Apply this diff:

if (event instanceof NavigationEnd) {
-  (window as any).Appcues && (window as any).Appcues.page();
+  (window as any).Appcues?.page();
}
🧰 Tools
🪛 Biome

[error] 101-101: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/app/integrations/xero/xero.component.ts (1)

94-94: Improve robustness of loginRequired parameter parsing

The comparison params.login_required === 'true' assumes that login_required is always a string with the exact value 'true'. To make the code more robust and handle different cases (e.g., different letter cases or missing parameters), consider using a case-insensitive comparison and safely accessing the parameter.

Apply this diff to enhance the comparison:

-      const loginRequired = params.login_required === 'true';
+      const loginRequired = params.login_required?.toLowerCase() === 'true';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1493a07 and bb87f17.

📒 Files selected for processing (5)
  • .github/workflows/c1_staging_deployment.yml (1 hunks)
  • src/app/integrations/intacct/intacct.component.ts (4 hunks)
  • src/app/integrations/netsuite/netsuite.component.ts (4 hunks)
  • src/app/integrations/qbo/qbo.component.ts (4 hunks)
  • src/app/integrations/xero/xero.component.ts (4 hunks)
🧰 Additional context used
🪛 actionlint
.github/workflows/c1_staging_deployment.yml

16-16: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


31-31: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


40-40: shellcheck reported issue in this script: SC2086:info:3:158: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 Biome
src/app/integrations/intacct/intacct.component.ts

[error] 101-101: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (11)
.github/workflows/c1_staging_deployment.yml (2)

1-9: LGTM: Workflow name and trigger events are well-defined.

The workflow name "Deploy to C1 Staging" is clear and descriptive. The trigger events (push to master and pull requests with the "c1_staging_deploy" label) are appropriate for a staging deployment workflow.


16-23: ⚠️ Potential issue

Update checkout action and clarify Sentry auth token usage.

  1. The actions/checkout@v2 is outdated. Consider updating to the latest version:
- uses: actions/checkout@v3
  1. The SENTRY_AUTH_TOKEN is defined but not used in the Docker push step. If it's not needed, consider removing it to keep the workflow clean.

To verify if the Sentry auth token is used in the Docker build process, please run the following command:

If the token is not used, consider removing it from this step.

🧰 Tools
🪛 actionlint

16-16: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

src/app/integrations/qbo/qbo.component.ts (4)

2-2: Correctly imported ActivatedRoute from @angular/router

The addition of ActivatedRoute to the import statement is appropriate for accessing route parameters.


12-12: Imported QboAuthService for authentication handling

Including QboAuthService is necessary for managing authentication logic within the component.


33-34: Added route and qboAuthService to the constructor

Injecting ActivatedRoute and QboAuthService through the constructor is correct for dependency injection of these services.


99-99: Updated ngOnInit to invoke handleAuthParameters

Calling handleAuthParameters in ngOnInit appropriately integrates authentication handling into the component's initialization process.

src/app/integrations/intacct/intacct.component.ts (5)

2-2: Added ActivatedRoute Import

The import of ActivatedRoute from @angular/router is necessary for accessing route parameters.


12-12: Added SiAuthService Import

Importing SiAuthService is appropriate for handling authentication logic in the component.


33-33: Injected ActivatedRoute into Constructor

Adding ActivatedRoute to the constructor allows the component to access query parameters from the route.


38-38: Injected SiAuthService into Constructor

Including SiAuthService in the constructor enables authentication actions like loginWithAuthCode.


104-104: Updated Initialization Logic

Replacing this.getOrCreateWorkspace(); with this.handleAuthParameters(); in ngOnInit() ensures that authentication parameters are processed before workspace setup.

Comment on lines 25 to 28
- name: Install kustomize
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve Kustomize installation method.

The current installation method for Kustomize, while common, is not the most secure or reproducible. Consider using a more controlled installation method:

  1. Use a specific version of Kustomize instead of the latest.
  2. Verify the downloaded binary's checksum.

Here's an improved installation step:

- name: Install kustomize
  run: |
    KUSTOMIZE_VERSION=v4.5.7  # Specify the desired version
    curl -sLO "https://github.com/kubernetes-sitter/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz"
    curl -sL "https://github.com/kubernetes-sitter/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_checksums.txt" | grep linux_amd64.tar.gz | sha256sum -c
    tar xzf kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz
    sudo mv kustomize /usr/local/bin/
    rm kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz

This approach ensures a specific version is used and verifies the integrity of the downloaded binary.

Comment on lines 30 to 43
- name: Clone another repository
uses: actions/checkout@v2
with:
repository: ${{ vars.STAGING_DEPLOY_REPO }}
ref: master
path: ${{ vars.STAGING_DEPLOY_REPO }}
persist-credentials: false
token: ${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}

- name: Update Image Tag
run: |
NEW_TAG="v$(git rev-parse --short HEAD)"
cd ${{ vars.STAGING_DEPLOY_REPO }}/${{ vars.C1_STAGING_DEPLOY_DIR }}/staging/integrations
kustomize edit set image docker.io/${{ secrets.DOCKERHUB_USERNAME }}/fyle_integrations-app=docker.io/${{ secrets.DOCKERHUB_USERNAME }}/fyle_integrations-app:$NEW_TAG
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Update checkout action for cloning repository.

The actions/checkout@v2 used for cloning the repository is outdated. Update it to the latest version:

- name: Clone another repository
  uses: actions/checkout@v3
  with:
    repository: ${{ vars.STAGING_DEPLOY_REPO }}
    ref: master
    path: ${{ vars.STAGING_DEPLOY_REPO }}
    persist-credentials: false
    token: ${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}

The rest of the steps for cloning the repository and updating the image tag look good. The use of variables and secrets for sensitive information is a good practice.

🧰 Tools
🪛 actionlint

31-31: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


40-40: shellcheck reported issue in this script: SC2086:info:3:158: Double quote to prevent globbing and word splitting

(shellcheck)

Comment on lines 45 to 54
- name: Commit and push changes
run: |
cd ${{ vars.STAGING_DEPLOY_REPO }}/
git config --global user.email "[email protected]"
git config --global user.name "GitHub Actions"
git add .
git commit -m "Deployed integrations-app-qa:$NEW_TAG to staging"
git remote set-url origin https://x-access-token:${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}@github.com/${{ vars.STAGING_DEPLOY_REPO }}
git pull origin master
git push origin master
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Address $NEW_TAG variable and consider adding error handling.

  1. The $NEW_TAG variable is used in the commit message but it's not defined in this step. Define it at the beginning of this step:
- name: Commit and push changes
  run: |
    NEW_TAG="v$(git rev-parse --short HEAD)"
    cd ${{ vars.STAGING_DEPLOY_REPO }}/
    # ... rest of the step
  1. Consider adding error handling to the git operations. For example:
- name: Commit and push changes
  run: |
    NEW_TAG="v$(git rev-parse --short HEAD)"
    cd ${{ vars.STAGING_DEPLOY_REPO }}/
    git config --global user.email "[email protected]"
    git config --global user.name "GitHub Actions"
    git add .
    git diff --staged --quiet || git commit -m "Deployed integrations-app-qa:$NEW_TAG to staging"
    git remote set-url origin https://x-access-token:${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}@github.com/${{ vars.STAGING_DEPLOY_REPO }}
    git pull origin master --ff-only
    git push origin master || (git pull --rebase origin master && git push origin master)
  shell: bash

This change adds a check before committing (in case there are no changes) and handles potential push conflicts.

Comment on lines +88 to +90
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle errors in loginWithAuthCode subscription

The current implementation of this.nsAuthService.loginWithAuthCode(authCode).subscribe() lacks error handling. If the login process fails, the user will not receive feedback, and the application might remain in a loading state. It's important to handle errors to enhance user experience and ensure the application can recover gracefully.

Apply this diff to include error handling:

this.nsAuthService.loginWithAuthCode(authCode).subscribe(
  () => this.setupWorkspace(),
+ (error) => {
+   console.error('Login failed:', error);
+   this.isLoading = false;
+   // Optionally, display an error message to the user or navigate away
+ }
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace(),
(error) => {
console.error('Login failed:', error);
this.isLoading = false;
// Optionally, display an error message to the user or navigate away
}
);

Comment on lines 82 to 95
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;

if (loginRequired && authCode) {
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Prevent potential memory leaks by unsubscribing from Observables

The subscription to this.route.queryParams in the handleAuthParameters method may lead to a memory leak if not properly managed. Since the queryParams observable can emit multiple times, it's important to complete the subscription when it's no longer needed. Consider using the take(1) operator to automatically unsubscribe after the first emission.

Apply this diff to modify the subscription:

+import { take } from 'rxjs/operators';

private handleAuthParameters(): void {
-   this.route.queryParams.subscribe(params => {
+   this.route.queryParams.pipe(take(1)).subscribe(params => {
      const loginRequired = params.login_required === 'true';
      const authCode = params.authCode;

      if (loginRequired && authCode) {
        this.nsAuthService.loginWithAuthCode(authCode).subscribe(
          () => this.setupWorkspace()
        );
      } else {
        this.setupWorkspace();
      }
    });
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;
if (loginRequired && authCode) {
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}
import { take } from 'rxjs/operators';
private handleAuthParameters(): void {
this.route.queryParams.pipe(take(1)).subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;
if (loginRequired && authCode) {
this.nsAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}

Comment on lines 83 to 96
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;

if (loginRequired && authCode) {
this.qboAuthService.loginWithAuthCode(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling in loginWithAuthCode subscription

In the handleAuthParameters method, consider adding error handling to the subscribe call of loginWithAuthCode. Currently, if the authentication fails, the error is not handled, which may lead to unexpected behavior.

Apply this diff to include error handling:

if (loginRequired && authCode) {
  this.qboAuthService.loginWithAuthCode(authCode).subscribe(
    () => this.setupWorkspace(),
+   (error) => {
+     // Handle the error appropriately, e.g., display an error message or redirect
+     console.error('Authentication error:', error);
+     // Optionally, navigate to an error page or display a notification to the user
+   }
  );
}

Committable suggestion was skipped due to low confidence.

Comment on lines 83 to 96
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;

if (loginRequired && authCode) {
this.siAuthService.loginWithAuthCode(authCode).subscribe(
() => this.getOrCreateWorkspace()
);
} else {
this.getOrCreateWorkspace();
}
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Memory Leak Due to Unmanaged Subscription

The subscription to this.route.queryParams may result in a memory leak if not properly managed, as queryParams is an observable that can emit multiple times. Consider using the take(1) operator to automatically complete the subscription after the first emission.

Apply this diff to use take(1):

private handleAuthParameters(): void {
-    this.route.queryParams.subscribe(params => {
+    this.route.queryParams.pipe(take(1)).subscribe(params => {
      const loginRequired = params.login_required === 'true';
      const authCode = params.authCode;

      if (loginRequired && authCode) {
        this.siAuthService.loginWithAuthCode(authCode).subscribe(
          () => this.getOrCreateWorkspace()
        );
      } else {
        this.getOrCreateWorkspace();
      }
    });
}

Also, add the import statement for take:

import { take } from 'rxjs/operators';

Comment on lines +89 to +91
this.siAuthService.loginWithAuthCode(authCode).subscribe(
() => this.getOrCreateWorkspace()
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add Error Handling to Authentication Subscription

The subscription to loginWithAuthCode does not handle errors, which could lead to unhandled exceptions if authentication fails. Consider adding an error handler to manage authentication failures gracefully.

Apply this diff to include error handling:

this.siAuthService.loginWithAuthCode(authCode).subscribe(
  () => this.getOrCreateWorkspace(),
+ (error) => {
+   // Handle authentication error
+   console.error('Authentication failed:', error);
+   // Optionally, inform the user or navigate to an error page
+ }
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.siAuthService.loginWithAuthCode(authCode).subscribe(
() => this.getOrCreateWorkspace()
);
this.siAuthService.loginWithAuthCode(authCode).subscribe(
() => this.getOrCreateWorkspace(),
(error) => {
// Handle authentication error
console.error('Authentication failed:', error);
// Optionally, inform the user or navigate to an error page
}
);

Comment on lines +98 to +100
this.xeroAuthService.login(authCode).subscribe(
() => this.setupWorkspace()
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for xeroAuthService.login subscription

The subscription to this.xeroAuthService.login(authCode) lacks error handling. If the login attempt fails, the user may not be informed, and setupWorkspace may not be called, potentially leaving the app in a loading state. Consider adding error handling to manage failed login attempts gracefully.

Apply this diff to handle errors in the login subscription:

-        this.xeroAuthService.login(authCode).subscribe(
-          () => this.setupWorkspace()
-        );
+        this.xeroAuthService.login(authCode).subscribe({
+          next: () => this.setupWorkspace(),
+          error: error => {
+            // Handle login error
+            console.error('Login error:', error);
+            this.isLoading = false;
+          }
+        });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.xeroAuthService.login(authCode).subscribe(
() => this.setupWorkspace()
);
this.xeroAuthService.login(authCode).subscribe({
next: () => this.setupWorkspace(),
error: error => {
// Handle login error
console.error('Login error:', error);
this.isLoading = false;
}
});

Comment on lines 92 to 105
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;

if (loginRequired && authCode) {
this.xeroAuthService.login(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling and complete subscriptions to prevent potential memory leaks

The handleAuthParameters method subscribes to queryParams but does not handle errors or unsubscribe from the observable. This can lead to memory leaks if the component remains active for an extended period or if errors occur. Consider adding error handling and using the take(1) operator to automatically complete the subscription after the first emission.

Apply this diff to improve the subscription:

+import { take } from 'rxjs/operators';

  private handleAuthParameters(): void {
-    this.route.queryParams.subscribe(params => {
+    this.route.queryParams.pipe(take(1)).subscribe(params => {
       const loginRequired = params.login_required === 'true';
       const authCode = params.authCode;

       if (loginRequired && authCode) {
-        this.xeroAuthService.login(authCode).subscribe(
-          () => this.setupWorkspace()
-        );
+        this.xeroAuthService.login(authCode).subscribe({
+          next: () => this.setupWorkspace(),
+          error: error => {
+            // Handle login error
+            console.error('Login error:', error);
+            this.isLoading = false;
+          }
+        });
       } else {
         this.setupWorkspace();
       }
-    });
+    }, error => {
+      // Handle queryParams error
+      console.error('QueryParams error:', error);
+      this.setupWorkspace();
+      this.isLoading = false;
+    });
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private handleAuthParameters(): void {
this.route.queryParams.subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;
if (loginRequired && authCode) {
this.xeroAuthService.login(authCode).subscribe(
() => this.setupWorkspace()
);
} else {
this.setupWorkspace();
}
});
}
import { take } from 'rxjs/operators';
private handleAuthParameters(): void {
this.route.queryParams.pipe(take(1)).subscribe(params => {
const loginRequired = params.login_required === 'true';
const authCode = params.authCode;
if (loginRequired && authCode) {
this.xeroAuthService.login(authCode).subscribe({
next: () => this.setupWorkspace(),
error: error => {
// Handle login error
console.error('Login error:', error);
this.isLoading = false;
}
});
} else {
this.setupWorkspace();
}
}, error => {
// Handle queryParams error
console.error('QueryParams error:', error);
this.setupWorkspace();
this.isLoading = false;
});
}

@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
Copy link
Contributor

@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: 1

🧹 Outside diff range and nitpick comments (3)
src/app/auth/login/login.component.ts (3)

50-52: LGTM! Consider adding type safety for the code parameter.

The changes to the redirect method look good. Including the code as a query parameter in the redirect URL is consistent with the modifications in other methods and likely contributes to fixing the integration issues for multiple admins.

For improved type safety, consider explicitly typing the code parameter:

private redirect(redirectUri: string | undefined, code: string): void {
  if (redirectUri) {
    this.router.navigate([redirectUri + `?code=${code}`]);
  } else {
    this.router.navigate(['/integrations']);
  }
}

109-111: LGTM! Consider simplifying the conditional logic.

The changes to the saveUserProfileAndNavigate method look good. Passing the code through the entire authentication flow is consistent with the modifications in other methods and likely contributes to fixing the integration issues for multiple admins.

For improved readability, consider simplifying the conditional logic:

this.redirect(redirectUri, code);

This change removes the duplicate redirect call, as it's the same for both conditions.


Line range hint 116-120: LGTM! Consider adding error handling for missing code.

The changes to the login method look good. Extracting the code from query parameters and passing it to saveUserProfileAndNavigate is consistent with the modifications in other methods and likely contributes to fixing the integration issues for multiple admins.

Consider adding error handling for cases where the code is missing:

private login(): void {
  this.route.queryParams.subscribe(params => {
    if (params.code) {
      this.saveUserProfileAndNavigate(params.code, params.redirect_uri);
    } else {
      console.error('Login failed: Missing authentication code');
      // Handle the error appropriately, e.g., show an error message to the user
    }
  });
}

This addition will help catch and handle cases where the authentication code is missing, improving the robustness of the login process.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4f5cf81 and 3c7caba.

📒 Files selected for processing (3)
  • src/app/auth/login/login.component.ts (2 hunks)
  • src/app/integrations/intacct/intacct.component.ts (4 hunks)
  • src/app/integrations/xero/xero.component.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/integrations/xero/xero.component.ts
🧰 Additional context used
🪛 Biome
src/app/integrations/intacct/intacct.component.ts

[error] 100-100: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (3)
src/app/auth/login/login.component.ts (1)

Line range hint 1-138: Overall, the changes look good and address the PR objectives.

The modifications to the LoginComponent consistently handle the code parameter throughout the authentication flow, which likely addresses the issue of integrations on the admin dashboard when multiple admins are present. The changes are well-implemented and maintain the overall structure of the component.

Key improvements:

  1. The redirect method now includes the code as a query parameter.
  2. The saveUserProfileAndNavigate method passes the code through the entire authentication process.
  3. The login method extracts the code from query parameters and initiates the authentication flow.

These changes ensure that the unique code for each admin is preserved and used throughout the login process, which should resolve the integration issues mentioned in the PR objectives.

To ensure that these changes don't introduce any unintended side effects, please verify:

  1. The login process works correctly for both single and multiple admin scenarios.
  2. The integrations on the admin dashboard function as expected after these changes.
  3. There are no regressions in other parts of the application that might rely on the previous login flow.

This script will help identify any places where the code parameter might not be consistently used in the authentication flow across the codebase.

✅ Verification successful

[/run_scripts]


✅ Verification Successful

The code parameter is consistently used throughout the authentication flow in the LoginComponent and related services. All relevant methods correctly handle and preserve the code, ensuring reliable authentication behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that the `code` parameter is consistently used across the codebase

echo "Checking for inconsistent usage of 'code' parameter in authentication flow:"
rg --type typescript -e "saveUserProfileAndNavigate\([^)]*\)" -e "redirect\([^)]*\)" -e "login\([^)]*\)" src/

Length of output: 313


Script:

#!/bin/bash
# Re-verify that the `code` parameter is consistently used across the codebase

echo "Rechecking for inconsistent usage of 'code' parameter in authentication flow with corrected file type:"
rg --type ts -e "saveUserProfileAndNavigate\([^)]*\)" -e "redirect\([^)]*\)" -e "login\([^)]*\)" src/

Length of output: 1919

src/app/integrations/intacct/intacct.component.ts (2)

84-94: Potential Memory Leak Due to Unmanaged Subscription

As previously noted, subscribing to this.route.queryParams without unsubscribing or completing the subscription may lead to a memory leak. Consider using the take(1) operator to automatically complete the subscription after the first emission.


88-90: Add Error Handling to Authentication Subscription

As mentioned earlier, the subscription to loginWithAuthCode does not handle errors, which could lead to unhandled exceptions if authentication fails. Consider adding an error handler to manage authentication failures gracefully.

}
});
}

ngOnInit(): void {
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
(window as any).Appcues && (window as any).Appcues.page();
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify Code Using Optional Chaining

The expression (window as any).Appcues && (window as any).Appcues.page(); can be simplified using optional chaining for better readability.

Apply this diff to use optional chaining:

-    (window as any).Appcues && (window as any).Appcues.page();
+    (window as any).Appcues?.page();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
(window as any).Appcues && (window as any).Appcues.page();
(window as any).Appcues?.page();
🧰 Tools
🪛 Biome

[error] 100-100: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (4)
src/app/auth/login/login.component.ts (3)

50-54: Ensure proper handling of the code parameter in the redirect URI.

The changes to the redirect method look good. However, there are a few points to consider:

  1. The code parameter is now being appended to the redirect URI. Make sure this is the intended behavior and that the receiving endpoint is prepared to handle this parameter.

  2. The console logging on line 54 should be removed before merging to production, as it may expose sensitive information.

Consider the following improvements:

  1. Use encodeURIComponent(code) when appending the code to the URL to ensure proper URL encoding:

    this.router.navigate([redirectUri + `?code=${encodeURIComponent(code)}`]);
  2. Remove the console.log statement or wrap it in a development-only check:

    if (!environment.production) {
      console.log('redirectUri', redirectUri + `?code=${code}`);
    }

122-125: Remove debug logging and ensure proper error handling.

The changes to the login method look good overall. However, there are a few points to consider:

  1. The console logging statements on lines 123 and 125 should be removed before merging to production, as they may expose sensitive information.

  2. It's good that you're checking for the presence of the code parameter, but consider adding error handling for cases where it might be missing.

Consider the following improvements:

  1. Remove the console.log statements or wrap them in a development-only check:

    if (!environment.production) {
      console.log('code', params.code);
      console.log('redirect_uri', params.redirect_uri);
    }
  2. Add error handling for missing code:

    if (params.code) {
      this.saveUserProfileAndNavigate(params.code, params.redirect_uri);
    } else {
      console.error('Login failed: No code provided');
      // Handle the error appropriately, e.g., show an error message to the user
    }

Leftover console.log Statements Found

The following console.log statements remain in LoginComponent:

  • console.log('redirectUri', redirectUri + \?code=${code}`);`
  • console.log('code', params.code);
  • console.log('redirect_uri', params.redirect_uri);

These should be removed or conditionally included to enhance the security and cleanliness of the codebase.

🔗 Analysis chain

Line range hint 1-138: Overall assessment: Changes look good with minor improvements suggested.

The modifications to the LoginComponent appear to address the issue mentioned in the PR objectives regarding integrations on the admin dashboard when multiple admins are present. The changes consistently propagate the code parameter through the login flow, which likely helps maintain proper authentication state.

A few minor improvements have been suggested:

  1. Use encodeURIComponent for the code parameter in the redirect URI.
  2. Remove or conditionally include debug logging statements.
  3. Add error handling for cases where the code parameter might be missing.

These changes should enhance the robustness and security of the login process.

To ensure that these changes don't introduce any regressions, please run the following verification script:

This script will help ensure that the code parameter is used consistently, debug statements are removed, and proper error handling is in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the `code` parameter is properly handled throughout the login flow.

# Test 1: Check if the `code` parameter is used consistently
echo "Test 1: Checking for consistent use of 'code' parameter"
rg --type typescript -e 'code:' -e 'params\.code' src/app/auth/login/login.component.ts

# Test 2: Verify that there are no leftover debug console.log statements
echo "Test 2: Checking for leftover console.log statements"
rg --type typescript 'console\.log' src/app/auth/login/login.component.ts

# Test 3: Check for proper error handling when 'code' is missing
echo "Test 3: Checking for error handling when 'code' is missing"
rg --type typescript -e 'if \(params\.code\)' -e 'else' src/app/auth/login/login.component.ts

Length of output: 737


Script:

#!/bin/bash
# Description: Re-verify that the `code` parameter is properly handled throughout the login flow with corrected TypeScript file type.

# Test 1: Check if the `code` parameter is used consistently
echo "Test 1: Checking for consistent use of 'code' parameter"
rg --type ts -e 'code:' -e 'params\.code' src/app/auth/login/login.component.ts

# Test 2: Verify that there are no leftover debug console.log statements
echo "Test 2: Checking for leftover console.log statements"
rg --type ts 'console\.log' src/app/auth/login/login.component.ts

# Test 3: Check for proper error handling when 'code' is missing
echo "Test 3: Checking for error handling when 'code' is missing"
rg --type ts -e 'if \(params\.code\)' -e 'else' src/app/auth/login/login.component.ts

Length of output: 1135

src/app/integrations/intacct/intacct.component.ts (1)

87-87: Remove Debugging Statements from Production Code

The console.log(params); statement is a debugging statement that should be removed from production code to avoid unintended information disclosure and console clutter.

Apply this diff to remove the console.log statement:

-      // eslint-disable-next-line
-      console.log(params);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3c7caba and 052af81.

📒 Files selected for processing (2)
  • src/app/auth/login/login.component.ts (3 hunks)
  • src/app/integrations/intacct/intacct.component.ts (4 hunks)
🧰 Additional context used
🪛 Biome
src/app/integrations/intacct/intacct.component.ts

[error] 101-101: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (4)
src/app/auth/login/login.component.ts (1)

111-113: LGTM: Proper propagation of the code parameter.

The changes to the saveUserProfileAndNavigate method look good. The code parameter is correctly added to the method signature and properly passed to the redirect method calls. This ensures consistency with the changes made to the redirect method.

src/app/integrations/intacct/intacct.component.ts (3)

84-95: Potential Memory Leak Due to Unmanaged Subscription

The previous comment regarding the potential memory leak due to the unmanaged subscription to this.route.queryParams remains valid. Please address this issue as previously suggested.


89-91: Add Error Handling to Authentication Subscription

The previous comment about adding error handling to the loginWithAuthCode subscription is still applicable. Please consider handling errors to prevent unhandled exceptions.


97-100: Simplify Code Using Optional Chaining

The previous comment about simplifying the code using optional chaining is still valid. Consider updating (window as any).Appcues && (window as any).Appcues.page(); to use optional chaining for better readability.

@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
@div360 div360 added c1_staging_deploy Deploys to c1 staging and removed c1_staging_deploy Deploys to c1 staging labels Oct 3, 2024
@div360 div360 merged commit b2c0674 into master Oct 3, 2024
6 checks passed
@div360 div360 added the deploy Triggers deployment of active branch to Staging label Oct 3, 2024
div360 added a commit that referenced this pull request Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c1_staging_deploy Deploys to c1 staging deploy Triggers deployment of active branch to Staging size/M Medium PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants