Skip to content

refactor(users,auth): extract password hashing to lib/helpers to break auth↔users cycle - #3864

Merged
PierreBrisorgueil merged 6 commits into
masterfrom
fix/3862-password-helper-break-cycle
Jun 14, 2026
Merged

refactor(users,auth): extract password hashing to lib/helpers to break auth↔users cycle#3864
PierreBrisorgueil merged 6 commits into
masterfrom
fix/3862-password-helper-break-cycle

Conversation

@PierreBrisorgueil

@PierreBrisorgueil PierreBrisorgueil commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • What changed: Extracted hashPassword and comparePassword (two bcrypt wrappers) from auth.service.js into a new dependency-free leaf module lib/helpers/password.js. users.service.js now imports them from the helper directly; auth.service.js sources them from the same helper and re-exports them on its default export (transparent re-export — zero API surface change).
  • Why: users.service was importing auth.service solely for these two helpers, creating a circular import path (users.serviceauth.serviceusers.service). The leaf helper breaks the cycle structurally, with no behavioral change.
  • Related issues: Closes 🔧 Extract password hashing to lib/helpers to break the users↔auth service cycle #3862

Scope

  • Module(s) impacted: lib/helpers/password.js (new), src/modules/auth/auth.service.js, src/modules/users/users.service.js, related unit tests
  • Cross-module impact: noneauth.service re-exports the helpers on its default export, so any existing caller of auth.service.hashPassword / auth.service.comparePassword continues to work unchanged
  • Risk level: low

Validation

  • npm run lint
  • npm test
  • Manual checks done (if applicable)

Guardrails check

  • No secrets or credentials introduced (.env*, secrets/**, keys, tokens)
  • No risky rename/move of core stack paths
  • Changes remain merge-friendly for downstream projects
  • Tests added or updated when behavior changed

Verification

1994/1994 unit tests green, lint clean. Cycle structurally proven: users.service.js no longer imports anything from auth.service.

Notes for reviewers

  • Security considerations: none — bcrypt configuration (rounds, salting) is unchanged; only the import location moves.
  • Mergeability considerations: fully backward-compatible; the re-export on auth.service default means downstream callers need zero migration.
  • Follow-up tasks: none.

Reviewer notes (accepted)

Two pre-reviewed nits — please do not re-raise:

(a) lib/helpers/password.js exports both named (export { hashPassword, comparePassword }) and default (export default { hashPassword, comparePassword }). This is intentional — it mirrors the existing convention in lib/helpers/emailVerification.js, which uses the same dual-export pattern.

(b) The users.service.count test mocks both the named and default exports of the password helper even though only the default export is consumed by the service. This is harmless; the extra mock is kept for structural symmetry with the other test files.

Summary by CodeRabbit

  • Refactor
    • Centralized password hashing and comparison utilities into a shared helper module for improved code organization and reusability.

@PierreBrisorgueil PierreBrisorgueil added the Refactor Neither fixes a bug nor adds a feat label Jun 14, 2026
@PierreBrisorgueil PierreBrisorgueil self-assigned this Jun 14, 2026
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@PierreBrisorgueil, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 55 minutes and 25 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e90ab998-0201-4904-a386-b553b46471fc

📥 Commits

Reviewing files that changed from the base of the PR and between 9e5a64f and b00ccd3.

📒 Files selected for processing (1)
  • lib/helpers/password.js

Walkthrough

A new shared lib/helpers/password.js module is introduced with hashPassword and comparePassword bcrypt wrappers. auth.service.js removes its local bcrypt implementations and imports from this helper; users.service.js similarly replaces its AuthService.hashPassword call with the helper. Related unit tests are updated throughout.

Changes

Shared bcrypt helper extraction and service wiring

Layer / File(s) Summary
New shared password helper and unit tests
lib/helpers/password.js, lib/helpers/tests/password.unit.tests.js
Adds hashPassword and comparePassword bcrypt wrappers with saltRounds=10 and string coercion, plus a full Jest suite covering invocation, coercion, mismatch behavior, and default export shape.
Auth service delegates to shared helper
modules/auth/services/auth.service.js, modules/auth/tests/auth.unit.tests.js
Removes local bcrypt.hash/bcrypt.compare implementations, imports from lib/helpers/password.js, and re-exports. Auth tests are narrowed to delegation assertions only.
Users service switches to password helper
modules/users/services/users.service.js, modules/users/tests/users.service.count.unit.tests.js, modules/users/tests/users.service.remove.*.unit.tests.js
Replaces AuthService.hashPassword call with passwordHelper.hashPassword. Count test mocks the password helper instead of the auth service; remove-cascade and remove-pendingSweep tests drop the now-unnecessary auth.service.js mock.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • pierreb-devkit/Node#3790: Touches AuthService.comparePassword for dummy bcrypt comparison in the forgot-password controller, which now resolves through lib/helpers/password.js after this change.
  • pierreb-devkit/Node#3175: Modifies modules/auth/tests/auth.unit.tests.js expectations around comparePassword/hashPassword, the same test blocks rewritten here.

Suggested labels

Tests

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactoring: extracting password hashing utilities to break a circular dependency between auth and users modules.
Description check ✅ Passed The pull request description is comprehensive and follows the template with all major sections: Summary, Scope, Validation, Guardrails, Verification, and Notes for reviewers.
Linked Issues check ✅ Passed The PR fully addresses issue #3862: extracts hashPassword and comparePassword to lib/helpers/password.js [#3862], eliminates auth↔users circular import [#3862], and both auth and users tests pass [#3862].
Out of Scope Changes check ✅ Passed All changes are directly related to extracting password helpers and breaking the circular dependency. No unrelated refactorings or feature additions are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/3862-password-helper-break-cycle

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.

@codecov

codecov Bot commented Jun 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.41%. Comparing base (dceba95) to head (b00ccd3).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3864   +/-   ##
=======================================
  Coverage   92.41%   92.41%           
=======================================
  Files         162      163    +1     
  Lines        5394     5394           
  Branches     1735     1735           
=======================================
  Hits         4985     4985           
  Misses        328      328           
  Partials       81       81           
Flag Coverage Δ
integration 60.10% <100.00%> (ø)
unit 73.17% <75.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dceba95...b00ccd3. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@PierreBrisorgueil
PierreBrisorgueil marked this pull request as ready for review June 14, 2026 14:53
Copilot AI review requested due to automatic review settings June 14, 2026 14:53

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

Pull request overview

This PR breaks the circular dependency between users.service and auth.service by extracting the bcrypt wrappers (hashPassword, comparePassword) into a new leaf helper at lib/helpers/password.js, then sourcing both services from that helper while keeping AuthService.hashPassword/comparePassword available via re-export.

Changes:

  • Added lib/helpers/password.js (bcrypt wrappers) and unit tests for it.
  • Updated users.service.js to hash passwords via the new helper instead of importing auth.service.js.
  • Updated auth.service.js to import wrappers from the helper and re-export them; adjusted related unit tests and mocks.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/helpers/password.js New shared bcrypt wrapper helper used by both auth and users services.
lib/helpers/tests/password.unit.tests.js New unit tests validating hashing/comparison behavior and default export shape.
modules/auth/services/auth.service.js Imports bcrypt wrappers from the helper and re-exports them on AuthService.
modules/auth/tests/auth.unit.tests.js Updates tests to validate re-exported helper behavior.
modules/users/services/users.service.js Uses the helper for password hashing during user creation (removes auth-service dependency).
modules/users/tests/users.service.count.unit.tests.js Updates mocks to target the new helper module.
modules/users/tests/users.service.remove.cascade.unit.tests.js Removes now-unneeded auth-service mock.
modules/users/tests/users.service.remove.pendingSweep.unit.tests.js Removes now-unneeded auth-service mock.

Comment thread lib/helpers/password.js

@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 `@lib/helpers/password.js`:
- Around line 9-11: Add JSDoc documentation blocks for both the hashPassword and
comparePassword functions in lib/helpers/password.js. For hashPassword, include
a one-line description, a `@param` tag documenting the password parameter, and a
`@returns` tag indicating it returns a Promise resolving to the hashed password
string. For comparePassword, include a one-line description, `@param` tags for
both userPassword and storedPassword parameters, and a `@returns` tag indicating
it returns a Promise resolving to a boolean result of the comparison. Follow the
existing JSDoc format used elsewhere in the codebase to maintain consistency.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79e87059-7b91-4a70-b7ba-cce9300f9cc8

📥 Commits

Reviewing files that changed from the base of the PR and between dceba95 and 9e5a64f.

📒 Files selected for processing (8)
  • lib/helpers/password.js
  • lib/helpers/tests/password.unit.tests.js
  • modules/auth/services/auth.service.js
  • modules/auth/tests/auth.unit.tests.js
  • modules/users/services/users.service.js
  • modules/users/tests/users.service.count.unit.tests.js
  • modules/users/tests/users.service.remove.cascade.unit.tests.js
  • modules/users/tests/users.service.remove.pendingSweep.unit.tests.js
💤 Files with no reviewable changes (2)
  • modules/users/tests/users.service.remove.cascade.unit.tests.js
  • modules/users/tests/users.service.remove.pendingSweep.unit.tests.js

Comment thread lib/helpers/password.js
@PierreBrisorgueil
PierreBrisorgueil merged commit a3be432 into master Jun 14, 2026
8 checks passed
@PierreBrisorgueil
PierreBrisorgueil deleted the fix/3862-password-helper-break-cycle branch June 14, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Neither fixes a bug nor adds a feat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🔧 Extract password hashing to lib/helpers to break the users↔auth service cycle

2 participants