Skip to content

Conversation

@arian81
Copy link
Member

@arian81 arian81 commented Nov 14, 2025

Implements a cookie-based solution to track the last login timestamp and OAuth provider used, similar to Better Auth's last-login-method plugin but adapted for NextAuth.

Changes:

  • Modified NextAuth handler to intercept OAuth callbacks and set a 'last-login' cookie
  • Cookie contains JSON with timestamp and provider name (google, github, discord, linkedin, azure-ad)
  • Cookie is HttpOnly, SameSite=Lax, with 1-year expiration
  • Added utility functions in src/utils/last-login.ts for reading and formatting the cookie data
  • Includes helper functions for client-side and server-side cookie access
  • Added comprehensive documentation in LAST_LOGIN_USAGE.md with usage examples

This implementation uses cookies instead of database storage to minimize overhead and complexity.

Implements a cookie-based solution to track the last login timestamp and OAuth provider used, similar to Better Auth's last-login-method plugin but adapted for NextAuth.

Changes:
- Modified NextAuth handler to intercept OAuth callbacks and set a 'last-login' cookie
- Cookie contains JSON with timestamp and provider name (google, github, discord, linkedin, azure-ad)
- Cookie is HttpOnly, SameSite=Lax, with 1-year expiration
- Added utility functions in src/utils/last-login.ts for reading and formatting the cookie data
- Includes helper functions for client-side and server-side cookie access
- Added comprehensive documentation in LAST_LOGIN_USAGE.md with usage examples

This implementation uses cookies instead of database storage to minimize overhead and complexity.
@vercel
Copy link

vercel bot commented Nov 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
portal Ready Ready Preview Comment Nov 14, 2025 6:38pm

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 14, 2025

Greptile Overview

Greptile Summary

Implements cookie-based tracking of last login timestamp and OAuth provider by intercepting NextAuth callbacks and setting a custom cookie. However, the implementation has a critical flaw: the cookie is marked as HttpOnly (for security), which prevents client-side JavaScript from accessing it via document.cookie, yet the documentation and utility functions advertise client-side access through getLastLoginInfo().

Major issues:

  • HttpOnly cookie cannot be read by getLastLoginInfo() on the client side, making that function and its documentation misleading
  • Empty callback and event handlers serve no purpose and clutter the code
  • The setHeader override approach is fragile and may not work reliably across all authentication flows

Missing from PR description:

  • No "resolves #issue-id" link as required by PR template

The feature needs to either remove the HttpOnly flag (reducing security) or update the documentation to clarify that client-side access is not possible and remove the non-functional getLastLoginInfo() function.

Confidence Score: 1/5

  • This PR has critical logical issues that will cause runtime failures when users attempt client-side cookie access
  • The fundamental contradiction between HttpOnly cookies and client-side access makes the primary advertised feature non-functional. Users following the documentation will encounter silent failures when getLastLoginInfo() returns null despite successful logins.
  • All three files require attention: src/utils/last-login.ts needs the client-side function fixed or removed, LAST_LOGIN_USAGE.md needs corrected documentation, and src/pages/api/auth/[...nextauth].ts needs cleanup of empty handlers

Important Files Changed

File Analysis

Filename Score Overview
src/pages/api/auth/[...nextauth].ts 2/5 Modified NextAuth handler to intercept OAuth callbacks and set last-login cookie; includes empty callback/event handlers that should be removed
src/utils/last-login.ts 1/5 Utility functions for cookie parsing and formatting; critical issue - client-side function won't work with HttpOnly cookies
LAST_LOGIN_USAGE.md 1/5 Documentation for last login tracking feature; contains contradictory information about HttpOnly cookies and client-side access

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant NextAuthHandler
    participant OAuthProvider
    participant LastLoginCookie

    User->>Browser: Initiate OAuth login
    Browser->>NextAuthHandler: Start auth flow
    NextAuthHandler->>OAuthProvider: Redirect for authentication
    OAuthProvider->>User: Display consent screen
    User->>OAuthProvider: Approve access
    OAuthProvider->>NextAuthHandler: Callback with credentials
    Note over NextAuthHandler: Extract provider from callback URL
    NextAuthHandler->>NextAuthHandler: Override setHeader method
    NextAuthHandler->>LastLoginCookie: Set HttpOnly cookie with timestamp and provider
    NextAuthHandler->>Browser: Redirect with session and cookie
    
    alt Client-side cookie access
        Browser->>LastLoginCookie: Attempt document.cookie read
        LastLoginCookie-->>Browser: Blocked by HttpOnly flag
    end
    
    alt Server-side cookie access
        Browser->>NextAuthHandler: Send request with cookies
        NextAuthHandler->>LastLoginCookie: Read from req.cookies
        LastLoginCookie-->>NextAuthHandler: Return timestamp and provider data
        NextAuthHandler->>Browser: Send response with login info
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile


## Security Notes

- The cookie is **HttpOnly**, meaning it cannot be accessed via JavaScript on the client side for security purposes. Use the provided utility functions instead.
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: HttpOnly cookies cannot be read via document.cookie in JavaScript, which contradicts the client-side function getLastLoginInfo() provided in the docs. Either remove HttpOnly flag from the cookie implementation, or document that client-side access won't work with HttpOnly enabled.

Prompt To Fix With AI
This is a comment left during a code review.
Path: LAST_LOGIN_USAGE.md
Line: 144:144

Comment:
**logic:** HttpOnly cookies cannot be read via `document.cookie` in JavaScript, which contradicts the client-side function `getLastLoginInfo()` provided in the docs. Either remove HttpOnly flag from the cookie implementation, or document that client-side access won't work with HttpOnly enabled.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +24 to +28
signIn({ account }) {
// This callback runs on successful sign-in
// We'll set the cookie in the handler below
return true;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Empty callback serves no purpose and should be removed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/pages/api/auth/[...nextauth].ts
Line: 24:28

Comment:
**style:** Empty callback serves no purpose and should be removed.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +60 to +65
events: {
async signIn(message) {
// Store provider and timestamp for cookie setting in handler
// The actual cookie is set in the custom handler below
},
},
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Empty event handler serves no purpose and should be removed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/pages/api/auth/[...nextauth].ts
Line: 60:65

Comment:
**style:** Empty event handler serves no purpose and should be removed.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +41 to +56
export function getLastLoginInfo(): LastLoginInfo | null {
if (typeof window === "undefined") {
console.warn("getLastLoginInfo can only be called on the client side");
return null;
}

const cookies = document.cookie.split(";");
const lastLoginCookie = cookies.find((cookie) =>
cookie.trim().startsWith("last-login=")
);

if (!lastLoginCookie) return null;

const cookieValue = lastLoginCookie.split("=")[1];
return parseLastLoginCookie(cookieValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: getLastLoginInfo() won't work if cookie has HttpOnly flag (which it does in [...nextauth].ts:108). HttpOnly prevents client-side JavaScript from accessing cookies via document.cookie.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/utils/last-login.ts
Line: 41:56

Comment:
**logic:** `getLastLoginInfo()` won't work if cookie has HttpOnly flag (which it does in `[...nextauth].ts:108`). HttpOnly prevents client-side JavaScript from accessing cookies via `document.cookie`.

How can I resolve this? If you propose a fix, please make it concise.

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