Skip to content

Comments

Revert "Refactor exports. Fix account linking. Remove unused props."#659

Closed
johnlowe399-blip wants to merge 1 commit intoelie222:stagingfrom
johnlowe399-blip:revert-658-migrate-to-better-auth
Closed

Revert "Refactor exports. Fix account linking. Remove unused props."#659
johnlowe399-blip wants to merge 1 commit intoelie222:stagingfrom
johnlowe399-blip:revert-658-migrate-to-better-auth

Conversation

@johnlowe399-blip
Copy link

@johnlowe399-blip johnlowe399-blip commented Aug 7, 2025

Reverts #658

Summary by CodeRabbit

  • New Features

    • Added support for a configurable cookie domain via a new environment variable.
  • Bug Fixes

    • Improved session retrieval across the app by explicitly passing request headers, enhancing authentication context and reliability.
    • Updated account linking to use unique provider account IDs for more accurate identification.
  • Refactor

    • Standardized authentication utility imports and usage throughout the app.
    • Enhanced cookie configuration for cross-subdomain support and improved security settings.
    • Streamlined and clarified OAuth setup instructions in documentation.
  • Documentation

    • Simplified Google OAuth credential setup instructions in the README.

@vercel
Copy link

vercel bot commented Aug 7, 2025

@johnlowe399-blip is attempting to deploy a commit to the Inbox Zero OSS Program Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 7, 2025

Walkthrough

This update refactors authentication and session retrieval across the codebase. It standardizes session fetching by passing request headers explicitly, renames and restructures authentication exports, updates cookie and provider configurations, and modifies account linking logic to use provider account IDs. Several components and utilities are updated to utilize the new authentication client interface.

Changes

Cohort / File(s) Change Summary
Session Retrieval Refactor
apps/web/app/(app)/ErrorMessages.tsx, apps/web/app/(app)/[emailAccountId]/debug/rule-history/[ruleId]/page.tsx, apps/web/app/(app)/admin/page.tsx, apps/web/app/(app)/layout.tsx, apps/web/app/(landing)/welcome/page.tsx, apps/web/app/(landing)/login/page.tsx, apps/web/app/api/user/me/route.ts, apps/web/app/api/user/complete-registration/route.ts, apps/web/utils/account.ts, apps/web/utils/actions/safe-action.ts, apps/web/utils/email-account.ts, apps/web/utils/error.server.ts, apps/web/utils/middleware.ts
Session retrieval updated to use auth.api.getSession() with explicit request headers for context-aware authentication.
Auth Client Refactor
apps/web/utils/auth-client.ts, apps/web/providers/SessionProvider.tsx, apps/web/app/(app)/[emailAccountId]/settings/MultiAccountSection.tsx, apps/web/components/TopNav.tsx, apps/web/providers/PostHogProvider.tsx, apps/web/app/(landing)/login/LoginForm.tsx, apps/web/app/(app)/accounts/AddAccount.tsx, apps/web/utils/user.ts
Authentication utilities are now accessed via an exported authClient object, updating imports and usages accordingly.
Auth Configuration Overhaul
apps/web/utils/auth.ts, apps/web/app/api/auth/[...all]/route.ts
Main auth export renamed, cookie settings enhanced for cross-domain, Microsoft provider updated, event hooks commented out, and handler usage updated to reference new auth export.
Provider Account Linking Update
apps/web/app/api/outlook/linking/callback/route.ts
Account linking logic now uses provider account ID (profile.id) for uniqueness, Prisma query updated, and logging improved for clarity.
Environment Variable Addition
apps/web/env.ts
Adds COOKIE_DOMAIN with a default value to the server environment schema.
README Update
README.md
Google OAuth setup instructions simplified by requiring only one redirect URI.
Email Client Detection Logic
apps/web/utils/assess.ts
Message fetching updated to use a filter query for sent messages instead of a dedicated sent-messages method.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebApp
    participant AuthAPI
    participant Headers

    User->>WebApp: Request (any protected resource)
    WebApp->>Headers: Retrieve request headers
    WebApp->>AuthAPI: auth.api.getSession({ headers })
    AuthAPI-->>WebApp: Session (user info or null)
    WebApp->>User: Continue with session context
Loading
sequenceDiagram
    participant User
    participant WebApp
    participant AuthClient
    participant Provider

    User->>WebApp: Initiate social sign-in
    WebApp->>AuthClient: signIn.social(provider, { callbackURL, newUserCallbackURL })
    AuthClient->>Provider: Redirect to provider with params
    Provider-->>WebApp: Redirect with auth code
    WebApp->>AuthClient: Handle callback, establish session
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Possibly related issues

Possibly related PRs

Poem

A hop, a skip, a session fetch anew,
Now headers guide us, clear and true.
AuthClient leads with gentle might,
Cookies set for every site.
Provider IDs keep accounts in line—
Oh, what a refactor! The codebase shines.
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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.

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

🔭 Outside diff range comments (1)
apps/web/utils/auth.ts (1)

140-151: Re-enable critical auth event handlers in apps/web/utils/auth.ts

I searched the entire codebase for handleSignIn, handleLinkAccount, and handlePendingPremiumInvite and found no alternative implementations—these hooks only live in apps/web/utils/auth.ts and are now entirely disabled.

• File: apps/web/utils/auth.ts
• Lines: ~140–151

Commenting out these handlers breaks:

  • New user sign-in workflows (Loops/Resend contact creation)
  • Sign-up analytics and referral tracking
  • Pending premium-invite processing
  • Account linking and EmailAccount record creation

Please re-enable the signIn event and database hooks or provide a replacement implementation to restore these core flows.

🧹 Nitpick comments (2)
apps/web/app/(landing)/login/page.tsx (1)

8-8: Remove unused import

The AutoLogOut import is added but the component remains commented out. Consider removing the import if the component won't be used, or implement it if it's needed.

-import AutoLogOut from "@/app/(landing)/login/error/AutoLogOut";

Or uncomment and implement the AutoLogOut functionality:

-      {/* <AutoLogOut loggedIn={loggedIn} /> */}
+      <AutoLogOut loggedIn={loggedIn} />

Also applies to: 112-112

apps/web/utils/auth.ts (1)

1-475: Summary: Review the implications of reverting authentication changes

This revert introduces several significant changes to the authentication configuration:

  1. Cookie Security: The new configuration with sameSite: "none" requires careful CSRF protection and HTTPS in all environments.

  2. Disabled Event Handlers: Critical functionality for user onboarding, account linking, and premium features is commented out. Ensure alternative implementations exist or re-enable these handlers.

  3. Session Retrieval Pattern: The removal of the auth function aligns with a pattern where session retrieval is done explicitly at call sites rather than centrally.

Given that this is a revert PR (#659 reverting #658), please ensure:

  • The revert is intentional and necessary
  • Any security improvements from the reverted PR are preserved
  • The commented-out code is either re-enabled or has alternative implementations

async function getEmailClients(client: EmailProvider) {
try {
const messages = await client.getSentMessages(50);
const messages = await client.getMessages("from:me", 50);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify cross-provider compatibility of the "from:me" query syntax.

The change from getSentMessages(50) to getMessages("from:me", 50) introduces Gmail-specific query syntax. While functionally equivalent for Gmail, this may not work consistently across different email providers (Outlook/Exchange).

Let's verify how different providers handle this query syntax:


🏁 Script executed:

#!/bin/bash
# Description: Check how the EmailProvider interface handles getMessages with query parameters across different providers

# Search for EmailProvider interface and implementations
ast-grep --pattern 'interface EmailProvider {
  $$$
  getMessages($$$) 
  $$$
}'

# Find all provider implementations
ast-grep --pattern 'class $_Provider implements EmailProvider {
  $$$
  getMessages($$$) {
    $$$
  }
  $$$
}'

# Look for any provider-specific query handling
rg -A 10 "getMessages.*query" --type ts

Length of output: 12163


Use provider-abstracted sent-message method instead of Gmail-only query

The call

const messages = await client.getMessages("from:me", 50);

injects Gmail’s “from:me” syntax into generic assessment logic. Outlook’s implementation simply forwards that string to Microsoft Graph and won’t return sent messages as intended.

To preserve cross-provider compatibility and keep Gmail-specific details isolated in apps/web/utils/gmail, use the interface’s getSentMessages here (or branch on client.name === "google" if you need to retain the exact Gmail query):

• File: apps/web/utils/assess.ts, getEmailClients (around line 131)

- const messages = await client.getMessages("from:me", 50);
+ const messages = await client.getSentMessages(50);
// -- or, if you must keep the Gmail query:
// + const messages =
// +   client.name === "google"
// +     ? await client.getMessages("from:me", 50)
// +     : await client.getSentMessages(50);

This ensures all providers correctly retrieve sent messages without leaking provider-specific syntax into shared utilities.

🤖 Prompt for AI Agents
In apps/web/utils/assess.ts at line 131, replace the Gmail-specific call
client.getMessages("from:me", 50) with the provider-abstracted method
client.getSentMessages() to retrieve sent messages. This avoids using Gmail-only
query syntax in generic assessment logic and ensures compatibility with other
providers like Outlook. If necessary, use a conditional check on client.name to
handle provider-specific behavior, but prefer the interface method to keep
provider details encapsulated.

Comment on lines +25 to +43
export const auth = betterAuth({
advanced: {
database: {
generateId: false,
},
crossSubDomainCookies: {
enabled: true,
domain: env.COOKIE_DOMAIN,
},
cookie: {
sameSite: "none",
secure: true,
domain: env.COOKIE_DOMAIN,
path: "/",
},
defaultCookieAttributes: {
secure: true,
sameSite: "none",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify cookie configuration for security and development compatibility

The cookie configuration with sameSite: "none" and secure: true has important implications:

  1. Security: sameSite: "none" allows cross-site requests, which could expose the application to CSRF attacks. Ensure CSRF protection is properly implemented.

  2. Development: These settings require HTTPS even in development. Consider environment-specific configuration to avoid issues with local development.

  3. Domain validation: The COOKIE_DOMAIN should be validated to prevent configuration errors.


🏁 Script executed:

#!/bin/bash
# Check if CSRF protection is implemented in the codebase
echo "Checking for CSRF protection implementation..."
rg -A 5 "csrf|CSRF" --type ts --type tsx

# Check for environment-specific cookie configuration
echo -e "\nChecking for environment-specific configurations..."
fd -e ts -e tsx -e js | xargs rg "NODE_ENV.*development.*cookie|cookie.*NODE_ENV.*development" -A 3

# Check how COOKIE_DOMAIN is used and validated
echo -e "\nChecking COOKIE_DOMAIN usage and validation..."
rg "COOKIE_DOMAIN" --type ts --type tsx -A 3

Length of output: 576


🏁 Script executed:

#!/bin/bash
# Search for any CSRF protection usage in the web app
echo "Checking for CSRF protection patterns..."
rg -A 5 'csrf|CSRF' apps/web

# Look for NODE_ENV checks around cookie configuration
echo -e "\nChecking for environment-specific cookie configuration..."
rg -A 3 'NODE_ENV' apps/web

# Inspect where COOKIE_DOMAIN is referenced and whether it's validated
echo -e "\nChecking for COOKIE_DOMAIN usage and validation..."
rg -A 3 'COOKIE_DOMAIN' apps/web

Length of output: 5419


Adjust cookie settings for development and enforce domain validation

The current configuration in apps/web/utils/auth.ts unconditionally sets

sameSite: "none",  
secure: true

which will:

  • Block cookies in non-HTTPS dev environments (e.g., http://localhost)
  • Allow cross-site requests without explicit CSRF safeguards

Recommendations:

  • Scope sameSite and secure to production only:
    const isProd = env.NODE_ENV === "production";
    
    cookie: {
      sameSite: isProd ? "none" : "lax",
      secure: isProd,
      domain: env.COOKIE_DOMAIN,
      path: "/",
    },
    defaultCookieAttributes: {
      sameSite: isProd ? "none" : "lax",
      secure: isProd,
    },
  • In apps/web/env.ts, tighten COOKIE_DOMAIN validation:
    // from:
    COOKIE_DOMAIN: z.string().default("getinboxzero.com"),
    // to:
    COOKIE_DOMAIN: z.string().url().default("https://getinboxzero.com"),
  • Verify that betterAuth provides CSRF protection (tokens or same-site enforcement). If not, integrate a CSRF middleware or token strategy.

Files to update:

  • apps/web/utils/auth.ts (lines defining cookie and defaultCookieAttributes)
  • apps/web/env.ts (COOKIE_DOMAIN schema)
🤖 Prompt for AI Agents
In apps/web/utils/auth.ts around lines 25 to 43, update the cookie settings to
conditionally set sameSite and secure attributes based on the environment by
defining a boolean isProd from env.NODE_ENV and using it to set sameSite to
"none" and secure to true only in production, otherwise use "lax" and false
respectively for development. Also, in apps/web/env.ts, modify the COOKIE_DOMAIN
schema to validate as a URL instead of a plain string by changing
z.string().default("getinboxzero.com") to
z.string().url().default("https://getinboxzero.com"). Finally, verify if
betterAuth includes CSRF protection and if not, add appropriate CSRF middleware
or token handling.

@elie222
Copy link
Owner

elie222 commented Aug 7, 2025

Hey, what is this? Closing for now.

@elie222 elie222 closed this Aug 7, 2025
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