Skip to content

feat: implement refresh token authentication#121

Open
Jaykolate wants to merge 3 commits into
CodePlaygroundHub:mainfrom
Jaykolate:feat/refresh-token-auth
Open

feat: implement refresh token authentication#121
Jaykolate wants to merge 3 commits into
CodePlaygroundHub:mainfrom
Jaykolate:feat/refresh-token-auth

Conversation

@Jaykolate

@Jaykolate Jaykolate commented Jul 13, 2026

Copy link
Copy Markdown

Summary

Implements refresh token-based authentication to provide secure session management and automatic access token renewal.

Closes #49

Changes Made

  • Added refresh token authentication alongside the existing access token flow.
  • Configured access tokens to expire after 15 minutes.
  • Added refresh tokens with a 7-day expiration.
  • Stored refresh tokens securely in HTTP-only cookies.
  • Stored a SHA-256 hash of the refresh token in MongoDB for secure validation and revocation.
  • Added a new POST /api/auth/refresh endpoint to issue new access tokens using a valid refresh token.
  • Updated the logout flow to revoke the stored refresh token and clear the HTTP-only cookie.
  • Added REFRESH_TOKEN_SECRET to .env.example.
  • Added an integration test to verify the refresh token authentication flow.

Authentication Flow

Login / Email Verification

  • Generate a 15-minute access token.
  • Generate a 7-day refresh token.
  • Store the hashed refresh token in MongoDB.
  • Set the refresh token in an HTTP-only cookie.
  • Return the access token in the response.

Refresh

  • Read the refresh token from the HTTP-only cookie.
  • Verify the token signature and validate the stored hash.
  • Issue and return a new access token.
  • Return 401 Unauthorized for invalid, expired, or revoked refresh tokens.

Logout

  • Remove the stored refresh token hash from MongoDB.
  • Clear the HTTP-only refresh token cookie.
  • End the session securely.

Testing

  • Verified login generates both access and refresh tokens.
  • Verified refresh tokens are stored securely in an HTTP-only cookie and hashed in MongoDB.
  • Verified POST /api/auth/refresh returns a new access token for valid refresh tokens.
  • Verified invalid or expired refresh tokens return 401 Unauthorized.
  • Verified logout revokes the refresh token and clears the cookie.

Summary by CodeRabbit

  • New Features
    • Added access-token renewal via refresh tokens using secure HTTP-only cookies.
    • Refresh tokens are now issued on login/verification and refreshed via a dedicated refresh endpoint.
    • Access tokens expire after 15 minutes; refresh tokens remain valid for up to 7 days.
    • Logout now revokes the stored refresh token and clears the refresh cookie.
  • Tests
    • Added end-to-end coverage for refresh success, missing/invalid/expired cookies, refresh revocation after logout, and banned-user handling, including cookie security attributes.

@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

@Jaykolate is attempting to deploy a commit to the Akash Santra 's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 13, 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 Plus

Run ID: 56c886ea-29e4-4d04-803d-f295b930e676

📥 Commits

Reviewing files that changed from the base of the PR and between 1ce50fd and dc84342.

📒 Files selected for processing (3)
  • backend/src/controllers/auth.controller.js
  • backend/test/auth/refresh_test_runner.js
  • backend/test/setup.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/controllers/auth.controller.js

📝 Walkthrough

Walkthrough

Adds refresh-token authentication with short-lived access tokens, HTTP-only cookies, hashed persistence, a refresh endpoint, logout revocation, environment configuration, and integration coverage.

Changes

Refresh-token authentication

Layer / File(s) Summary
Token contracts and persistence
backend/.env.example, backend/src/lib/utils.js, backend/src/models/user.model.js, backend/test/setup.js
Adds refresh-token configuration, 15-minute access-token expiry, seven-day refresh-token generation, test secrets, and a hidden refreshTokenHash field.
Issuance and logout
backend/src/controllers/auth.controller.js
Login and email verification issue refresh-token cookies and persist SHA-256 hashes; logout clears the cookie and stored hash.
Refresh endpoint and validation
backend/src/routes/auth.route.js, backend/src/controllers/auth.controller.js, backend/test/auth/refresh_test_runner.js
Registers POST /refresh, validates refresh tokens, returns access tokens, and tests renewal, errors, banning, logout, and revocation.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AuthRoute
  participant AuthController
  participant UserDatabase
  Client->>AuthRoute: POST /api/auth/refresh with refreshToken cookie
  AuthRoute->>AuthController: Invoke refresh
  AuthController->>UserDatabase: Match stored refreshTokenHash
  AuthController-->>Client: Return new access token or error
Loading

Suggested labels: enhancement

Suggested reviewers: akash504-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding refresh token authentication.
Linked Issues check ✅ Passed The changes implement refresh-token login, refresh endpoint, secure storage, and logout revocation required by issue #49.
Out of Scope Changes check ✅ Passed The PR stays focused on refresh-token auth and related test/setup updates, with no obvious unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

🧹 Nitpick comments (3)
backend/test/auth/refresh_test_runner.js (2)

55-61: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Assert the refresh cookie’s security contract.

Presence alone does not verify the PR’s guarantees. Assert HttpOnly, SameSite=Strict, and the seven-day lifetime so regressions cannot silently weaken cookie security.

🤖 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 `@backend/test/auth/refresh_test_runner.js` around lines 55 - 61, Extend the
refreshCookie validation in the login response checks to assert that the cookie
includes HttpOnly, SameSite=Strict, and a seven-day lifetime. Keep the existing
missing-cookie error and success logging, and fail with a clear error if any
security attribute is absent or incorrect.

96-105: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add the claimed expired-token test case.

This only tests a malformed token. Sign an already-expired refresh JWT and assert 401 to exercise expiration verification explicitly.

🤖 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 `@backend/test/auth/refresh_test_runner.js` around lines 96 - 105, Add an
expired-token case alongside the invalid-token scenario in the refresh test
runner: create a refresh JWT with an expiration time in the past using the
existing signing configuration, send it to POST /api/auth/refresh, and assert
that the response status is 401. Keep the malformed-token assertion intact and
clearly label the new expiration-specific test.
backend/src/controllers/auth.controller.js (1)

410-426: 🔒 Security & Privacy | 🔵 Trivial | 🏗️ Heavy lift

Rotate refresh tokens atomically after successful renewal.

The same cookie and hash remain valid for seven days, allowing a stolen token to be replayed repeatedly. Atomically replace the matching hash, issue a new refresh JWT, and update the cookie; reject concurrent reuse of the old hash.

🤖 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 `@backend/src/controllers/auth.controller.js` around lines 410 - 426, Update
the refresh-token renewal flow around User.findOne and generateToken to
atomically replace the matching refreshTokenHash, so concurrent requests cannot
reuse the old hash. After the atomic update succeeds, generate a new refresh
JWT, hash it, set the replacement token in the cookie, and return the new access
token; reject failed updates with the existing unauthorized response.
🤖 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 `@backend/src/controllers/auth.controller.js`:
- Around line 411-422: Update the User.findOne lookup in refresh() to require
isBanned: false alongside the existing user ID and refreshTokenHash criteria, so
banned accounts fail the existing invalid-token response and cannot receive a
new access token.

---

Nitpick comments:
In `@backend/src/controllers/auth.controller.js`:
- Around line 410-426: Update the refresh-token renewal flow around User.findOne
and generateToken to atomically replace the matching refreshTokenHash, so
concurrent requests cannot reuse the old hash. After the atomic update succeeds,
generate a new refresh JWT, hash it, set the replacement token in the cookie,
and return the new access token; reject failed updates with the existing
unauthorized response.

In `@backend/test/auth/refresh_test_runner.js`:
- Around line 55-61: Extend the refreshCookie validation in the login response
checks to assert that the cookie includes HttpOnly, SameSite=Strict, and a
seven-day lifetime. Keep the existing missing-cookie error and success logging,
and fail with a clear error if any security attribute is absent or incorrect.
- Around line 96-105: Add an expired-token case alongside the invalid-token
scenario in the refresh test runner: create a refresh JWT with an expiration
time in the past using the existing signing configuration, send it to POST
/api/auth/refresh, and assert that the response status is 401. Keep the
malformed-token assertion intact and clearly label the new expiration-specific
test.
🪄 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 Plus

Run ID: 8c490f3c-948f-4f67-b1c0-34a4ffc7187b

📥 Commits

Reviewing files that changed from the base of the PR and between 64c82d1 and 1ce50fd.

📒 Files selected for processing (6)
  • backend/.env.example
  • backend/src/controllers/auth.controller.js
  • backend/src/lib/utils.js
  • backend/src/models/user.model.js
  • backend/src/routes/auth.route.js
  • backend/test/auth/refresh_test_runner.js

Comment thread backend/src/controllers/auth.controller.js

@Akash504-ai Akash504-ai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR! I noticed the CI checks are currently failing. Could you please run the tests locally, check the GitHub Actions logs, and address the failing checks? Once the CI is green, I'll start reviewing the implementation.

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.

[FEATURE] : Add refresh token based authentication system

2 participants