Skip to content

Fix/app clean up on logout#408

Open
egalvis27 wants to merge 5 commits into
mainfrom
fix/app-clean-up-on-logout
Open

Fix/app clean up on logout#408
egalvis27 wants to merge 5 commits into
mainfrom
fix/app-clean-up-on-logout

Conversation

@egalvis27

@egalvis27 egalvis27 commented Jul 14, 2026

Copy link
Copy Markdown

What is Changed / Added


  • Added a centralized user-session shutdown flow in the main process:
    • New logout orchestrator with single-flight protection.
    • New resource cleanup entry point to close sync, antivirus, virtual drive, DB, and UI resources in one place.
  • Added logout synchronization for deeplink login:
    • Deeplink handler now waits for any in-flight logout before starting login.
    • Prevents cross-account race conditions during A -> B session switches.
  • Refactored auth utilities into focused modules:
    • Headers helpers, user-session getter, and logout logic are now separated for cleaner dependencies and easier testing.
  • Fixed config restore strategy for product flags:
    • Removed availableUserProducts from recoverable saved config.
    • Product availability now relies on fresh backend fetch on login.
  • Improved products update propagation:
    • Main process products service now emits updates reliably.
    • Renderer antivirus hook now reacts to live product updates and unlocks correctly when entitlement changes.
  • Improved dependency injection user cache handling:
    • Added explicit cache clear/update behavior to avoid stale user state after logout/login.
  • Added and updated tests across modified areas:
    • New tests for logout orchestration and deeplink synchronization.
    • Extended tests for auth, payments products flow, refresh-token behavior, antivirus hook updates, and DI user provider behavior.

Why

  • To guarantee complete and deterministic cleanup on logout.
  • To eliminate race conditions between logout and next login.
  • To avoid stale product entitlements from restored local state.
  • To ensure feature gating (especially Antivirus) reflects current backend entitlements.
  • To reduce auth-module coupling and improve maintainability.
  • To protect regressions with focused test coverage on critical session lifecycle paths.

Summary by CodeRabbit

  • New Features
    • Added a coordinated logout/session cleanup flow with safe concurrency handling.
    • Live-updates antivirus availability UI as product availability changes.
    • Added helpers to build authenticated API headers, plus the ability to cancel pending sync and scheduled token refresh jobs.
  • Bug Fixes
    • Deep links now wait for logout completion before processing, improving login reliability.
    • “No data” product updates are handled consistently (including allowing undefined payloads).
  • Tests
    • Expanded/updated unit tests for logout, deeplink synchronization, and token refresh scheduling behavior.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 768ec68d-c916-460b-8fc3-468c2cb3cfb1

📥 Commits

Reviewing files that changed from the base of the PR and between 64da3e3 and 22b055b.

📒 Files selected for processing (3)
  • src/apps/main/auth/close-user-session-resources.ts
  • src/apps/main/auth/logout.ts
  • src/core/bootstrap/register-session-event-handlers.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/apps/main/auth/close-user-session-resources.ts
  • src/core/bootstrap/register-session-event-handlers.ts

📝 Walkthrough

Walkthrough

The PR adds serialized logout cleanup, separates authentication helpers, synchronizes deeplink handling with logout, updates product and antivirus state flows, and adjusts shared providers, configuration APIs, client wiring, domain constants, and test mocks.

Changes

Authentication and session lifecycle

Layer / File(s) Summary
Logout cleanup orchestration
src/apps/main/auth/close-user-session-resources.ts, src/apps/main/auth/logout.ts, src/apps/main/config.ts, src/apps/main/remote-sync/service.ts, src/apps/main/token-scheduler/TokenScheduler.ts, src/apps/main/background-processes/antivirus/..., src/apps/shared/dependency-injection/..., src/apps/main/auth/handlers.ts, src/apps/main/auth/service.test.ts, src/apps/main/auth/logout.test.ts
Logout cleanup is serialized, resource teardown is guarded, session configuration is reset, and related asynchronous tests await completion.
Auth module boundaries and deeplink synchronization
src/apps/main/auth/headers.ts, src/apps/main/auth/user-session.ts, src/apps/main/auth/service.ts, src/apps/main/auth/deeplink/..., src/apps/main/auth/refresh-token/..., src/infra/drive-server/...
Authentication helpers are moved into dedicated modules, deeplink processing waits for logout, current-user state updates the DI provider, and drive-server consumers use the extracted header helpers.
Product synchronization and antivirus availability
src/backend/features/payments/services/..., src/core/bootstrap/register-session-event-handlers.ts, src/apps/renderer/hooks/antivirus/..., src/apps/main/event-bus.ts
Product retrieval handles empty and failed responses, login sync occurs earlier, and antivirus UI state responds to product updates.
Runtime mocks and value-object updates
vitest.setup.main.ts, src/backend/features/virtual-drive/services/daemon.service.test.ts, src/context/shared/domain/value-objects/BucketEntry.ts
Vitest mocks preserve real exports and add required members, while BucketEntry centralizes its maximum size constant.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Logout
  participant SessionCleanup
  participant ConfigStore
  participant DriveServer
  Caller->>Logout: call logout()
  Logout->>ConfigStore: save user and reset session data
  Logout->>SessionCleanup: close user session resources
  SessionCleanup-->>Logout: cleanup completes
  Logout->>DriveServer: auth.logout()
  Logout-->>Caller: resolve logout promise
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and points to the main change: logout cleanup and session shutdown handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/app-clean-up-on-logout

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/infra/drive-server/services/auth/auth.service.test.ts (1)

26-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for the logout method.

While test coverage exists for login, access, and refresh, the logout method in AuthService lacks a dedicated test block. Consider adding a describe('logout', ...) block to test the success and error states of the logout request, particularly since its return value was recently updated to right(true).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/infra/drive-server/services/auth/auth.service.test.ts` around lines 26 -
27, Add a dedicated describe('logout', ...) block in the AuthService test suite
covering both successful and failing logout requests. Assert that the success
case returns right(true), and verify the error case preserves the expected
failure result while reusing the existing test setup and mocking patterns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/apps/main/auth/close-user-session-resources.ts`:
- Around line 40-45: Wrap the tray reset and widget hiding operations near lines
40-45 in runCleanupStep so synchronous UI errors are caught without aborting
subsequent cleanup. Also wrap widget destruction near lines 100-102 in
runCleanupStep, retrieving getWidget() inside that callback as required; apply
both changes in close-user-session-resources.ts.

In `@src/apps/main/auth/logout.test.ts`:
- Around line 102-103: Update the USER_LOGGED_OUT assertion in the logout test
to match the mock call structure returned by calls(eventBusEmitMock), wrapping
the event name in an argument array like the USER_AVAILABLE_PRODUCTS_UPDATED
assertion. Keep the existing event value unchanged.

In
`@src/apps/main/background-processes/antivirus/try-setup-antivirus-ipc-and-initialize.ts`:
- Around line 13-16: Update the initialization flow around setupAntivirusIpc()
to call cleanupAntivirusIpc() before registering new handlers, ensuring existing
IPC listeners are removed on repeated invocations while preserving the
subsequent removeAntivirusIpcHandlers assignment.

In `@src/apps/main/token-scheduler/TokenScheduler.ts`:
- Around line 10-12: Update TokenScheduler to maintain a static collection of
Job instances created by its schedule method. Store each non-null result from
nodeSchedule.scheduleJob in that collection, and change cancelAllJobs to cancel
only those tracked jobs instead of iterating over nodeSchedule.scheduledJobs
globally.

---

Nitpick comments:
In `@src/infra/drive-server/services/auth/auth.service.test.ts`:
- Around line 26-27: Add a dedicated describe('logout', ...) block in the
AuthService test suite covering both successful and failing logout requests.
Assert that the success case returns right(true), and verify the error case
preserves the expected failure result while reusing the existing test setup and
mocking patterns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ae67c103-a741-412d-a529-01161a2635fd

📥 Commits

Reviewing files that changed from the base of the PR and between e6b1171 and 9ec33a4.

📒 Files selected for processing (32)
  • src/apps/main/auth/close-user-session-resources.ts
  • src/apps/main/auth/deeplink/handle-deeplink.test.ts
  • src/apps/main/auth/deeplink/handle-deeplink.ts
  • src/apps/main/auth/deeplink/initialize_current_user.ts
  • src/apps/main/auth/handlers.ts
  • src/apps/main/auth/headers.ts
  • src/apps/main/auth/logout.test.ts
  • src/apps/main/auth/logout.ts
  • src/apps/main/auth/refresh-token/create-token-schedule-with-retry.test.ts
  • src/apps/main/auth/refresh-token/refresh-token.test.ts
  • src/apps/main/auth/service.test.ts
  • src/apps/main/auth/service.ts
  • src/apps/main/auth/user-session.ts
  • src/apps/main/background-processes/antivirus/try-setup-antivirus-ipc-and-initialize.ts
  • src/apps/main/config.ts
  • src/apps/main/event-bus.ts
  • src/apps/main/remote-sync/service.ts
  • src/apps/main/token-scheduler/TokenScheduler.ts
  • src/apps/renderer/hooks/antivirus/useAntivirus.test.tsx
  • src/apps/renderer/hooks/antivirus/useAntivirus.tsx
  • src/apps/shared/dependency-injection/DependencyInjectionUserProvider.test.ts
  • src/apps/shared/dependency-injection/DependencyInjectionUserProvider.ts
  • src/backend/features/payments/services/get-user-available-products-and-store.test.ts
  • src/backend/features/payments/services/get-user-available-products-and-store.ts
  • src/backend/features/virtual-drive/services/daemon.service.test.ts
  • src/context/shared/domain/value-objects/BucketEntry.ts
  • src/core/bootstrap/register-session-event-handlers.ts
  • src/infra/drive-server/client/drive-server.client.instance.test.ts
  • src/infra/drive-server/client/drive-server.client.instance.ts
  • src/infra/drive-server/services/auth/auth.service.test.ts
  • src/infra/drive-server/services/auth/auth.service.ts
  • vitest.setup.main.ts

Comment thread src/apps/main/auth/close-user-session-resources.ts Outdated
Comment thread src/apps/main/auth/logout.test.ts
Comment thread src/apps/main/token-scheduler/TokenScheduler.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/apps/main/auth/close-user-session-resources.ts`:
- Around line 40-50: Update the widget destruction logic in
closeUserSessionResources by replacing the later outer-scope widget reference
with a separate runCleanupStep named “destroy-widget”. Inside its task, retrieve
the widget via getWidget(), guard against a missing or destroyed instance, and
call destroy() on the current widget; keep the existing hide-widget-and-tray
cleanup scoped to its own widget reference.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72ac2a37-9a36-4757-a938-1d48f0fc9235

📥 Commits

Reviewing files that changed from the base of the PR and between 9ec33a4 and 64da3e3.

📒 Files selected for processing (1)
  • src/apps/main/auth/close-user-session-resources.ts

Comment on lines +40 to +50
await runCleanupStep({
step: 'hide-widget-and-tray',
task: () => {
resetTrayStatus('IDLE');
const widget = getWidget();

if (widget && !widget.isDestroyed()) {
widget.hide();
}
},
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix scoping to prevent ReferenceError on widget destruction.

Moving const widget = getWidget(); into this closure correctly guards the hiding logic but removes widget from the outer scope. This will either cause a ReferenceError later in the file at line 105 (if (widget && !widget.isDestroyed())) or silently skip destruction if an outer variable was left undefined.

As noted in a previous review, to safely destroy the widget, its destruction logic at lines 105-107 must also be wrapped in a cleanup step that retrieves the widget reference again.

🔧 Proposed fix for lines 105-107

Please replace lines 105-107 with the following:

  await runCleanupStep({
    step: 'destroy-widget',
    task: () => {
      const currentWidget = getWidget();
      if (currentWidget && !currentWidget.isDestroyed()) {
        currentWidget.destroy();
      }
    },
  });

Run the following script to verify if widget is still declared in the outer scope:

#!/bin/bash
# Description: Check if `widget` is declared in the outer scope.
rg -n 'widget' src/apps/main/auth/close-user-session-resources.ts
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/apps/main/auth/close-user-session-resources.ts` around lines 40 - 50,
Update the widget destruction logic in closeUserSessionResources by replacing
the later outer-scope widget reference with a separate runCleanupStep named
“destroy-widget”. Inside its task, retrieve the widget via getWidget(), guard
against a missing or destroyed instance, and call destroy() on the current
widget; keep the existing hide-widget-and-tray cleanup scoped to its own widget
reference.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
51.6% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant