Skip to content

fix(auth-guard): remove unmanaged currentLangugae$ subscription in canActivate #337

Open
VarshiniGunti wants to merge 3 commits into
PSMRI:mainfrom
VarshiniGunti:issue-138-authguard-memory-leak
Open

fix(auth-guard): remove unmanaged currentLangugae$ subscription in canActivate #337
VarshiniGunti wants to merge 3 commits into
PSMRI:mainfrom
VarshiniGunti:issue-138-authguard-memory-leak

Conversation

@VarshiniGunti
Copy link
Copy Markdown

@VarshiniGunti VarshiniGunti commented May 4, 2026

📋 Description

JIRA ID: N/A (Closes issue PSMRI/AMRIT#138)

This PR fixes a memory leak in AuthGuard.canActivate() caused by an unmanaged subscription to currentLangugae$ on every protected-route activation.

Problem

  • AuthGuard is a singleton.
  • currentLangugae$ is backed by BehaviorSubject and does not complete.
  • A new subscription was being created on every navigation to guarded routes with no unsubscribe.
  • The subscribed value (current_language_set) was not used in guard logic.

Change

  • Removed the redundant currentLangugae$ subscription from canActivate().
  • Removed dead code and unused dependencies related to that subscription:
    • current_language_set
    • HttpServiceService injection/import
    • unused ActivatedRoute injection/import

Motivation

Prevent unnecessary subscription accumulation and memory growth during repeated navigation, while keeping guard behavior unchanged.


✅ Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • New feature (non-breaking change which adds functionality)
  • 🔥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🛠 Refactor (change that is neither a fix nor a new feature)
  • ⚙️ Config change (configuration file or build script updates)
  • 📚 Documentation (updates to docs or readme)
  • 🧪 Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • 🚀 Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

ℹ️ Additional Information

Validation performed

  • Navigated repeatedly across protected routes (/service, /servicePoint, /registrar, /nurse-doctor, /lab, /pharmacist, /datasync).
  • Confirmed auth flow behavior remains the same:
    • valid session allows navigation
    • invalid session redirects to /login
  • Confirmed the guard no longer creates per-navigation currentLangugae$ subscriptions.

No UI changes were introduced.

Summary by CodeRabbit

  • Chores
    • Simplified authentication internals for improved maintainability.
  • Bug Fixes
    • More reliable session validation and automatic redirect to the login page when a session is not valid.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

The AuthGuard service constructor and internals were simplified: removed ActivatedRoute and HttpServiceService injections and the current_language_set property; canActivate now returns auth.validateSessionKey() and uses tap to redirect to /login when validation fails, removing prior language-state subscription logic.

Changes

AuthGuard Simplification

Layer / File(s) Summary
Dependencies Removal
src/app/app-modules/core/services/auth-guard.service.ts
Removed imports/injection of ActivatedRoute and HttpServiceService.
Constructor Injection Simplification
src/app/app-modules/core/services/auth-guard.service.ts
Constructor parameters reduced to AuthService and Router; removed current_language_set property.
Method Logic Refactoring
src/app/app-modules/core/services/auth-guard.service.ts
canActivate now returns this.auth.validateSessionKey().pipe(tap(...)) and redirects to /login when response is not valid; removed previous subscription-based language handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related issues

Poem

🐰 I hopped through guards of tangled thread,
Untangled lines and cleared the spread,
Subscriptions gone, the path is clean,
A leaner route, swift and keen,
🥕 Quiet paws, a bright new scene.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: removing an unmanaged subscription that was causing a memory leak in AuthGuard's canActivate method, which aligns with the core issue and fix detailed in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 and usage tips.

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/app-modules/core/services/auth-guard.service.ts`:
- Around line 1-2: This file is missing the mandatory AMRIT GPL-3.0 license
header; add the exact required license header block as the very first lines of
auth-guard.service.ts (before any imports such as the existing "import {
Injectable }..." and "import { CanActivate, Router }...") so the source file
complies with the project's header rule for src/**/*.{ts,html,scss,css}; ensure
the header is verbatim and precedes the rest of the file content.
🪄 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: 795ca94b-2726-460c-a4d9-fd2aab12c362

📥 Commits

Reviewing files that changed from the base of the PR and between 22509ad and 5038955.

📒 Files selected for processing (1)
  • src/app/app-modules/core/services/auth-guard.service.ts

Comment thread src/app/app-modules/core/services/auth-guard.service.ts
Copy link
Copy Markdown

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/app-modules/core/services/auth-guard.service.ts (1)

35-41: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

tap-only guard permits route activation on any truthy HTTP response — use map to enforce authentication

The guard returns an observable that emits the raw HTTP response object from validateSessionKey(), not a boolean. Angular's router expects canActivate to return boolean | UrlTree; when receiving other types, it coerces via !!. Since validateSessionKey() emits a response object (truthy even on failure, e.g., { statusCode: 401 }), Angular interprets this as true and allows navigation. Meanwhile, tap simultaneously triggers router.navigate(['/login']), creating a race condition where the protected route briefly activates before redirect occurs.

Fix: Use map to explicitly return boolean (or UrlTree for cleaner redirect handling):

Proposed fix
-import { tap } from 'rxjs';
+import { map } from 'rxjs';

  canActivate(route: any, state: any) {
    return this.auth.validateSessionKey().pipe(
-     tap((res: any) => {
-       if (!(res && res.statusCode === 200 && res.data)) {
-         this.router.navigate(['/login']);
-       }
-     })
+     map((res: any) => {
+       if (res && res.statusCode === 200 && res.data) {
+         return true;
+       }
+       return this.router.createUrlTree(['/login']);
+     })
    );
  }
🤖 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/app/app-modules/core/services/auth-guard.service.ts` around lines 35 -
41, The guard currently uses tap on validateSessionKey() which emits the raw
HTTP response and causes routing races; change the pipeline in the canActivate
method to use map (imported from rxjs/operators) to convert the response into a
boolean or UrlTree: return map((res: any) => res && res.statusCode === 200 &&
res.data ? true : this.router.createUrlTree(['/login'])); reference
validateSessionKey() and the canActivate implementation in auth-guard.service.ts
and remove the router.navigate side-effect inside tap so the router receives an
explicit boolean/UrlTree result.
🧹 Nitpick comments (1)
src/app/app-modules/core/services/auth-guard.service.ts (1)

34-34: 💤 Low value

route and state parameters should use proper Angular types

Using any loses the type contract required by the CanActivate interface. Import and use ActivatedRouteSnapshot and RouterStateSnapshot.

♻️ Proposed refactor
-import { CanActivate, Router } from '@angular/router';
+import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';

-  canActivate(route: any, state: any) {
+  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
🤖 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/app/app-modules/core/services/auth-guard.service.ts` at line 34, The
canActivate method currently uses untyped parameters (route: any, state: any);
import ActivatedRouteSnapshot and RouterStateSnapshot from `@angular/router` and
change the signature of canActivate to accept (route: ActivatedRouteSnapshot,
state: RouterStateSnapshot) and return the appropriate CanActivate-compatible
type (e.g. boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean |
UrlTree>) so the method conforms to the CanActivate contract; update any
internal references to route/state as needed.
🤖 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.

Outside diff comments:
In `@src/app/app-modules/core/services/auth-guard.service.ts`:
- Around line 35-41: The guard currently uses tap on validateSessionKey() which
emits the raw HTTP response and causes routing races; change the pipeline in the
canActivate method to use map (imported from rxjs/operators) to convert the
response into a boolean or UrlTree: return map((res: any) => res &&
res.statusCode === 200 && res.data ? true :
this.router.createUrlTree(['/login'])); reference validateSessionKey() and the
canActivate implementation in auth-guard.service.ts and remove the
router.navigate side-effect inside tap so the router receives an explicit
boolean/UrlTree result.

---

Nitpick comments:
In `@src/app/app-modules/core/services/auth-guard.service.ts`:
- Line 34: The canActivate method currently uses untyped parameters (route: any,
state: any); import ActivatedRouteSnapshot and RouterStateSnapshot from
`@angular/router` and change the signature of canActivate to accept (route:
ActivatedRouteSnapshot, state: RouterStateSnapshot) and return the appropriate
CanActivate-compatible type (e.g. boolean | UrlTree | Observable<boolean |
UrlTree> | Promise<boolean | UrlTree>) so the method conforms to the CanActivate
contract; update any internal references to route/state as needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0b189e5-cbf1-44ab-abfd-1f21e621543d

📥 Commits

Reviewing files that changed from the base of the PR and between 5038955 and b73d42d.

📒 Files selected for processing (1)
  • src/app/app-modules/core/services/auth-guard.service.ts

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

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