Skip to content

Feat: deprecated lucia auth#555

Merged
ivan-dalmet merged 7 commits intomasterfrom
feat-deprecated-lucia-auth
Jan 27, 2025
Merged

Feat: deprecated lucia auth#555
ivan-dalmet merged 7 commits intomasterfrom
feat-deprecated-lucia-auth

Conversation

@hugperez
Copy link
Copy Markdown
Contributor

@hugperez hugperez commented Jan 15, 2025

Describe your changes

As Lucia v3 will be deprecated in March 2025, I updated to implement our own session management based on their guidelines https://lucia-next.pages.dev/. In addition I added some features:

  • Storing the session token in a hashed format in the database to prevent potential data leaks.
  • The ability to configure session expiry via a new environment variable, SESSION_EXPIRY_SECONDS.
  • Added a refresh mechanism (on server side) based on half-life.
  • Refresh mechanism for cookie on client side with same expiry as server-side

Before (master branch)

  • ⚠️ the session ID was stored in clear text in the database, which can cause security issues
  • Session expiration was set to 4w (in source code) on server side, with half-life refresh
  • Cookie expiration was set to 400d (in lib) without refresh
  • Cookie was not cleared on client side when logout
master.mp4

After (this PR)

  • The session ID is stored hashed (sha-256)
  • Session expiration was set to 1min (in .env file) on server side, with half-life refresh
  • Cookie expiration was set to same expiration, with same refresh
  • Cookie cleared on client side when logout
branch.mp4

Checklist

  • I performed a self review of my code
  • I ensured that everything is written in English
  • I tested the feature or fix on my local environment
  • I ran the pnpm storybook command and everything is working
  • If applicable, I updated the translations for english and french files
    (If you cannot update the french language, just let us know in the PR description)
  • If applicable, I updated the README.md
  • If applicable, I created a PR or an issue on the documentation repository
  • If applicable, I’m sure that my feature or my component is mobile first and available correctly on desktop

Summary by CodeRabbit

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new session expiration configuration option.
    • Enhanced session management with improved token generation and validation.
  • Dependencies

    • Removed @lucia-auth/adapter-prisma.
    • Added @oslojs/crypto and @oslojs/encoding.
  • Changes

    • Refactored session handling mechanisms, including the introduction of new session management functions.
    • Updated authentication configuration and session management approach.
  • Environment

    • Introduced SESSION_EXPIRATION_SECONDS environment variable for session management.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 15, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
start-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 24, 2025 3:34pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 15, 2025

Walkthrough

The pull request introduces a refactoring of session management within the application. Key changes include the addition of a new environment variable for session expiration, the removal of the Lucia authentication library, and the relocation and reimplementation of session-related functions into a new session.ts module. Multiple files have been modified to enhance session handling, token generation, and validation processes.

Changes

File Change Summary
.env.example Added SESSION_EXPIRATION_SECONDS=2592000 environment variable
package.json Removed @lucia-auth/adapter-prisma dependency
Added @oslojs/crypto and @oslojs/encoding dependencies
src/env.mjs Added SESSION_EXPIRATION_SECONDS to server-side schema and runtime environment
src/server/config/auth.ts Removed getServerAuthSession, createSession, and deleteSession functions
src/server/config/lucia.ts Entire file deleted, removing Lucia authentication configuration
src/server/config/session.ts New file added with comprehensive session management functions:
- getCurrentSession
- createSession
- clearExpiredSessions
- validateSession
- invalidateSession
- refreshSession
- SessionValidationResult type
src/server/config/trpc.ts Updated session retrieval method from getServerAuthSession to getCurrentSession
src/server/routers/auth.tsx Replaced deleteSession with invalidateSession
src/server/routers/oauth.tsx Updated createSession import source

Sequence Diagram

sequenceDiagram
    participant Client
    participant Server
    participant SessionManager
    participant Database

    Client->>Server: Request with session token
    Server->>SessionManager: Validate session
    SessionManager->>Database: Check session existence
    Database-->>SessionManager: Session details
    alt Session Valid
        SessionManager->>SessionManager: Refresh session expiration
        SessionManager-->>Server: Valid session
        Server-->>Client: Process request
    else Session Invalid
        SessionManager->>Database: Clear session
        SessionManager-->>Server: Invalid session
        Server-->>Client: Authentication failed
    end
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

Copy link
Copy Markdown
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: 3

🧹 Nitpick comments (1)
src/server/routers/auth.tsx (1)

210-214: Update log message to reflect session invalidation

The log message Delete auth cookie does not accurately describe the current action, which now includes invalidating the session in the database and clearing the cookie. Updating the log message will improve clarity and maintain accurate logging.

Apply this diff to update the log message:

           ctx.logger.info('Delete auth cookie');

+          ctx.logger.info('Invalidating session and clearing auth cookie');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9556ef7 and be83a21.

📒 Files selected for processing (9)
  • .env.example (1 hunks)
  • package.json (1 hunks)
  • src/env.mjs (2 hunks)
  • src/server/config/auth.ts (0 hunks)
  • src/server/config/lucia.ts (0 hunks)
  • src/server/config/session.ts (1 hunks)
  • src/server/config/trpc.ts (2 hunks)
  • src/server/routers/auth.tsx (2 hunks)
  • src/server/routers/oauth.tsx (1 hunks)
💤 Files with no reviewable changes (2)
  • src/server/config/auth.ts
  • src/server/config/lucia.ts
✅ Files skipped from review due to trivial changes (1)
  • src/server/routers/oauth.tsx
🔇 Additional comments (5)
src/env.mjs (2)

14-14: Addition of SESSION_EXPIRATION_SECONDS looks good

The environment variable SESSION_EXPIRATION_SECONDS is correctly added to the server-side schema using z.coerce.number().int(), ensuring it is an integer.


82-82: SESSION_EXPIRATION_SECONDS included in runtime environment configuration

The environment variable is appropriately included in the runtimeEnv, allowing it to be accessed at runtime.

src/server/config/trpc.ts (1)

22-22: Verify the implementation of getCurrentSession.

The migration from Lucia auth to a custom session management solution requires careful verification of the new implementation.

Run the following script to analyze the session management implementation:

Also applies to: 43-43

✅ Verification successful

Session management implementation verified and secure

The new session management implementation follows security best practices with:

  • Secure token generation and validation
  • Database-backed session storage
  • Proper session lifecycle management
  • Automatic session refresh mechanism
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the session management implementation
# Check for proper token validation, session expiration handling, and secure storage

# Check the session implementation
echo "Checking session implementation..."
ast-grep --pattern 'function getCurrentSession() {
  $$$
}'

# Check for proper session validation
echo "Checking session validation..."
rg -A 10 "validateSession|verifySession|checkSession" 

# Check for secure token handling
echo "Checking token handling..."
rg -A 5 "token.*=|generateToken|createToken"

Length of output: 8277

package.json (1)

56-57: 🛠️ Refactor suggestion

Pin dependency versions for security.

Using caret (^) in version constraints could lead to automatic updates with breaking changes. For security-critical dependencies, it's recommended to pin exact versions.

Apply this diff:

-    "@oslojs/crypto": "^1.0.1",
-    "@oslojs/encoding": "^1.1.0",
+    "@oslojs/crypto": "1.0.1",
+    "@oslojs/encoding": "1.1.0",

Also, verify these dependencies for known security vulnerabilities:

.env.example (1)

19-21: Consider reducing the default session expiration time.

A 30-day session expiration time might be too long from a security perspective. Consider:

  • Reducing the default to 24 hours (86400 seconds)
  • Adding separate expiration times for different environments
  • Implementing session refresh tokens for longer-term persistence

Comment thread src/server/config/session.ts Outdated
Comment thread src/server/config/session.ts Outdated
Comment thread src/server/config/session.ts
@hugperez hugperez marked this pull request as draft January 15, 2025 20:29
@hugperez hugperez marked this pull request as ready for review January 17, 2025 19:04
Copy link
Copy Markdown
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

♻️ Duplicate comments (3)
src/server/config/session.ts (3)

1-16: ⚠️ Potential issue

Critical: Remove caching of session validation.

Based on previous discussions, using React's cache utility with session validation can lead to security issues by serving stale session data.

Additionally, the imports and constants look good:

  • The 20-byte entropy size provides sufficient security
  • The cookie name constant improves maintainability

74-74: ⚠️ Potential issue

Missing await when calling asynchronous refreshSession function.

The refreshSession function is asynchronous, but it's called without await.


120-124: ⚠️ Potential issue

Critical: Incorrect usage of getRandomValues in Node.js environment.

The getRandomValues method from node:crypto is not the recommended way to generate random values in Node.js.

🧹 Nitpick comments (2)
src/env.mjs (1)

14-14: LGTM! Consider adding a comment for the default value.

The implementation of SESSION_EXPIRATION_SECONDS is correct. Consider adding a comment explaining that the default value (2592000) represents 30 days, making it more maintainable.

-    SESSION_EXPIRATION_SECONDS: z.coerce.number().int().default(2592000),
+    // Default session expiry: 30 days (30 * 24 * 60 * 60 seconds)
+    SESSION_EXPIRATION_SECONDS: z.coerce.number().int().default(2592000),
src/server/config/session.ts (1)

18-33: Improve Bearer token extraction robustness.

While the current implementation works, the Bearer token extraction could be more robust against malformed inputs.

-      headers().get('Authorization')?.split('Bearer ')[1] ??
+      headers()
+        .get('Authorization')
+        ?.match(/^Bearer\s+(.*)$/)?.[1] ??
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be83a21 and ef05442.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • src/env.mjs (2 hunks)
  • src/server/config/session.ts (1 hunks)
  • src/server/config/trpc.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/server/config/trpc.ts
🧰 Additional context used
📓 Learnings (1)
src/server/config/session.ts (1)
Learnt from: hugperez
PR: BearStudio/start-ui-web#555
File: src/server/config/session.ts:17-32
Timestamp: 2025-01-16T13:25:36.984Z
Learning: React's `cache` utility should not be used with authentication-related functions like session validation, as it can lead to stale session data being served, creating potential security issues. Session state should always be fresh and validated on each request.
🔇 Additional comments (3)
src/server/config/session.ts (3)

83-101: LGTM! Well-implemented session refresh mechanism.

The half-life based refresh mechanism is a good approach that:

  • Reduces database load by not refreshing on every request
  • Maintains security by regularly updating session expiration

126-129: LGTM! Secure implementation of session token hashing.

The implementation correctly hashes the session token using SHA-256 before storage, which prevents token leakage in case of database compromise.


131-149: LGTM! Secure cookie management implementation.

The cookie management implementation follows security best practices:

  • HttpOnly flag prevents XSS attacks
  • Secure flag in production prevents MITM attacks
  • SameSite=lax prevents CSRF attacks
  • Proper cookie clearing with maxAge=0

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
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: 3

♻️ Duplicate comments (2)
src/server/config/session.ts (2)

1-1: ⚠️ Potential issue

Remove React cache to prevent stale session data

Based on the provided learnings, using React's cache utility with session validation can lead to security issues by serving stale session data.

Apply this diff to fix the issue:

-import { cache } from 'react';

-export const getCurrentSession = cache(
+export async function getCurrentSession(
   async (): Promise<SessionValidationResult> => {
     // ... function body ...
-  }
-);
+  }

Also applies to: 18-33


82-82: ⚠️ Potential issue

Missing await when calling asynchronous refreshSession function

The refreshSession function is asynchronous, but it's called without await. This could lead to race conditions and incorrect session handling.

Apply this diff to fix the issue:

-  await refreshSession(session);
+  await refreshSession(session);
   return { session, user };
🧹 Nitpick comments (2)
src/server/config/session.ts (2)

139-147: Enhance cookie security with stricter SameSite policy

Consider using 'Strict' instead of 'Lax' for the SameSite attribute to provide stronger protection against CSRF attacks.

Apply this diff to enhance security:

   cookies().set(AUTH_COOKIE_NAME, token, {
     httpOnly: true,
-    sameSite: 'lax',
+    sameSite: 'strict',
     secure: env.NODE_ENV === 'production',
     expires: expiresAt,
     path: '/',
   });

91-109: Simplify session refresh logic for better readability

The current implementation of half-life based refresh is complex and could be made more maintainable.

Consider this clearer implementation:

 export async function refreshSession(session: Session): Promise<void> {
+  const halfLife = env.SESSION_EXPIRATION_SECONDS * 500; // half of expiration in ms
+  const timeUntilExpiry = session.expiresAt.getTime() - Date.now();
+
-  if (
-    Date.now() >=
-    session.expiresAt.getTime() - (1000 * env.SESSION_EXPIRATION_SECONDS) / 2
-  ) {
+  if (timeUntilExpiry <= halfLife) {
+    const newExpiryTime = Date.now() + env.SESSION_EXPIRATION_SECONDS * 1000;
-    session.expiresAt = new Date(
-      Date.now() + 1000 * env.SESSION_EXPIRATION_SECONDS
-    );
+    session.expiresAt = new Date(newExpiryTime);
     await db.session.update({
       where: { id: session.id },
       data: { expiresAt: session.expiresAt },
     });
   }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef05442 and ad9c4dd.

📒 Files selected for processing (1)
  • src/server/config/session.ts (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/server/config/session.ts (1)
Learnt from: hugperez
PR: BearStudio/start-ui-web#555
File: src/server/config/session.ts:17-32
Timestamp: 2025-01-16T13:25:36.984Z
Learning: React's `cache` utility should not be used with authentication-related functions like session validation, as it can lead to stale session data being served, creating potential security issues. Session state should always be fresh and validated on each request.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Playwright E2E Tests
🔇 Additional comments (1)
src/server/config/session.ts (1)

1-161: Add comprehensive test coverage for session management

This module handles critical security functionality and requires thorough testing. Consider adding tests for:

  • Session creation and validation
  • Token generation and comparison
  • Cookie handling
  • Refresh mechanism
  • Error cases

Would you like me to help generate a test suite for this module?

Comment thread src/server/config/session.ts
Comment thread src/server/config/session.ts
Comment thread src/server/config/session.ts
@ivan-dalmet ivan-dalmet merged commit 2fc310b into master Jan 27, 2025
@ivan-dalmet ivan-dalmet deleted the feat-deprecated-lucia-auth branch January 27, 2025 11:02
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.

3 participants