Skip to content

Conversation

@ericallam
Copy link
Member

@ericallam ericallam commented Dec 4, 2025

CleanShot 2025-12-05 at 14 27 16

@changeset-bot
Copy link

changeset-bot bot commented Dec 4, 2025

⚠️ No Changeset found

Latest commit: 7e50b54

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Walkthrough

Adds Google OAuth support across the webapp: new optional env vars for Google client ID/secret; a Google auth strategy and helper; new routes to initiate and handle Google OAuth (with redirect-cookie and MFA handling); user model logic to find/create/link Google-authenticated users and a Prisma migration adding AuthenticationMethod.GOOGLE; UI changes to surface Google login and persist last-used auth method via a new lastAuthMethod cookie service; minor avatar image change adding referrerPolicy="no-referrer"; and the remix-auth-google dependency.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring extra attention:

  • apps/webapp/app/models/user.server.ts — findOrCreateGoogleUser: email selection, linking vs creating, authIdentifier format, avatar/profile updates, and isNewUser semantics.
  • internal-packages/database/prisma/migrations/* and schema.prisma — enum migration correctness and DB migration order/safety for adding GOOGLE.
  • apps/webapp/app/services/googleAuth.server.ts — strategy registration, error handling, logging, and postAuthentication integration.
  • apps/webapp/app/routes/auth.google.ts and apps/webapp/app/routes/auth.google.callback.tsx — redirectCookie behavior, sanitizeRedirectPath usage, session commits, MFA branching, and assembling multiple Set-Cookie headers.
  • apps/webapp/app/services/lastAuthMethod.server.ts and consumers — cookie serialization/validation and interaction with Headers in redirects.
  • apps/webapp/app/routes/auth.github.callback.tsx and apps/webapp/app/routes/magic.tsx — changed Set-Cookie handling to Headers with multiple cookies.
  • apps/webapp/package.json — verify remix-auth-google compatibility with existing auth stack.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning PR description contains only a screenshot without any textual content, missing all required template sections including issue reference, checklist, testing steps, changelog, and proper documentation. Fill in all required template sections: add issue reference, complete checklist items, describe testing steps, provide changelog summary, and ensure complete documentation before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main changes: adding Google login support and a 'last used' auth method indicator, which aligns with the comprehensive changes across authentication, database, and UI components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ea-branch-108

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.

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

🧹 Nitpick comments (1)
apps/webapp/app/routes/login._index/route.tsx (1)

20-41: Consider extracting GoogleIcon to a shared component.

The inline GoogleIcon component works correctly. However, since @trigger.dev/companyicons is already used for GitHubLightIcon, consider adding the Google icon to that package for consistency and reusability across the codebase.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b01b874 and c95b0f5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • apps/webapp/app/components/UserProfilePhoto.tsx (1 hunks)
  • apps/webapp/app/env.server.ts (1 hunks)
  • apps/webapp/app/models/user.server.ts (4 hunks)
  • apps/webapp/app/routes/auth.github.callback.tsx (2 hunks)
  • apps/webapp/app/routes/auth.google.callback.tsx (1 hunks)
  • apps/webapp/app/routes/auth.google.ts (1 hunks)
  • apps/webapp/app/routes/login._index/route.tsx (6 hunks)
  • apps/webapp/app/routes/magic.tsx (2 hunks)
  • apps/webapp/app/services/auth.server.ts (2 hunks)
  • apps/webapp/app/services/googleAuth.server.ts (1 hunks)
  • apps/webapp/app/services/lastAuthMethod.server.ts (1 hunks)
  • apps/webapp/package.json (1 hunks)
  • internal-packages/database/prisma/migrations/20251204143136_add_google_auth_method/migration.sql (1 hunks)
  • internal-packages/database/prisma/schema.prisma (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
apps/webapp/app/services/**/*.server.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Separate testable services from configuration files; follow the pattern of realtimeClient.server.ts (testable service) and realtimeClientGlobal.server.ts (configuration) in the webapp

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/services/lastAuthMethod.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/app/services/googleAuth.server.ts
  • apps/webapp/app/services/auth.server.ts
  • apps/webapp/package.json
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/models/user.server.ts
  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/magic.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/routes/auth.google.ts
🧠 Learnings (8)
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/app/services/**/*.server.{ts,tsx} : Separate testable services from configuration files; follow the pattern of `realtimeClient.server.ts` (testable service) and `realtimeClientGlobal.server.ts` (configuration) in the webapp

Applied to files:

  • apps/webapp/app/services/auth.server.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: The webapp at apps/webapp is a Remix 2.1 application using Node.js v20

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Applied to files:

  • apps/webapp/package.json
  • apps/webapp/app/routes/auth.google.callback.tsx
  • apps/webapp/app/routes/auth.google.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL

Applied to files:

  • apps/webapp/app/models/user.server.ts
  • internal-packages/database/prisma/migrations/20251204143136_add_google_auth_method/migration.sql
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Leverage the PostgreSQL database through the `trigger.dev/database` Prisma 6.14.0 client in the webapp for all data access patterns

Applied to files:

  • apps/webapp/app/models/user.server.ts
📚 Learning: 2025-09-02T11:27:36.336Z
Learnt from: myftija
Repo: triggerdotdev/trigger.dev PR: 2463
File: apps/webapp/app/routes/_app.github.callback/route.tsx:33-44
Timestamp: 2025-09-02T11:27:36.336Z
Learning: In the GitHub App installation callback flow in apps/webapp/app/routes/_app.github.callback/route.tsx, the install session cookie is not cleared after use due to interface limitations with redirectWithSuccessMessage/redirectWithErrorMessage not supporting custom headers. The maintainer accepts this design as the 1-hour cookie expiration provides sufficient protection against replay attacks.

Applied to files:

  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/services/lastAuthMethod.server.ts
  • apps/webapp/app/routes/magic.tsx
📚 Learning: 2025-09-02T11:18:06.602Z
Learnt from: myftija
Repo: triggerdotdev/trigger.dev PR: 2463
File: apps/webapp/app/services/gitHubSession.server.ts:31-36
Timestamp: 2025-09-02T11:18:06.602Z
Learning: In the GitHub App installation flow in apps/webapp/app/services/gitHubSession.server.ts, the redirectTo parameter stored in httpOnly session cookies is considered acceptable without additional validation by the maintainer, as the httpOnly cookie provides sufficient security for this use case.

Applied to files:

  • apps/webapp/app/routes/auth.github.callback.tsx
  • apps/webapp/app/routes/magic.tsx
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/app/**/*.{ts,tsx} : Access all environment variables through the `env` export of `env.server.ts` instead of directly accessing `process.env` in the Trigger.dev webapp

Applied to files:

  • apps/webapp/app/env.server.ts
🧬 Code graph analysis (8)
apps/webapp/app/services/googleAuth.server.ts (3)
apps/webapp/app/services/auth.server.ts (1)
  • authenticator (31-31)
apps/webapp/app/env.server.ts (1)
  • env (1261-1261)
apps/webapp/app/models/user.server.ts (1)
  • findOrCreateUser (38-50)
apps/webapp/app/services/auth.server.ts (4)
apps/webapp/app/env.server.ts (1)
  • env (1261-1261)
apps/webapp/app/services/gitHubAuth.server.ts (1)
  • addGitHubStrategy (9-54)
apps/webapp/app/services/googleAuth.server.ts (1)
  • addGoogleStrategy (9-54)
apps/webapp/app/services/emailAuth.server.tsx (1)
  • addEmailLinkStrategy (48-50)
apps/webapp/app/routes/auth.google.callback.tsx (8)
apps/webapp/app/routes/auth.github.callback.tsx (1)
  • loader (11-60)
apps/webapp/app/routes/auth.google.ts (2)
  • loader (4-4)
  • redirectCookie (29-32)
apps/webapp/app/routes/login._index/route.tsx (1)
  • loader (74-120)
apps/webapp/app/routes/magic.tsx (1)
  • loader (10-57)
apps/webapp/app/utils.ts (1)
  • sanitizeRedirectPath (13-42)
apps/webapp/app/services/auth.server.ts (1)
  • authenticator (31-31)
apps/webapp/app/models/message.server.ts (1)
  • redirectWithErrorMessage (201-218)
apps/webapp/app/services/lastAuthMethod.server.ts (1)
  • setLastAuthMethodHeader (22-24)
apps/webapp/app/models/user.server.ts (1)
apps/webapp/app/utils/email.ts (1)
  • assertEmailAllowed (3-13)
apps/webapp/app/routes/auth.github.callback.tsx (1)
apps/webapp/app/services/lastAuthMethod.server.ts (1)
  • setLastAuthMethodHeader (22-24)
apps/webapp/app/routes/login._index/route.tsx (2)
apps/webapp/app/services/lastAuthMethod.server.ts (1)
  • getLastAuthMethod (13-20)
apps/webapp/app/services/auth.server.ts (1)
  • isGoogleAuthSupported (31-31)
apps/webapp/app/routes/magic.tsx (1)
apps/webapp/app/services/lastAuthMethod.server.ts (1)
  • setLastAuthMethodHeader (22-24)
apps/webapp/app/routes/auth.google.ts (2)
apps/webapp/app/routes/auth.google.callback.tsx (1)
  • loader (11-60)
apps/webapp/app/routes/login._index/route.tsx (1)
  • loader (74-120)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (17)
apps/webapp/app/components/UserProfilePhoto.tsx (1)

25-25: LGTM! Good privacy practice.

Adding referrerPolicy="no-referrer" prevents the Referer header from being sent when fetching avatar images. This is particularly important for OAuth providers like Google, as it prevents leaking the user's current page URL to external servers when loading avatars.

apps/webapp/app/env.server.ts (1)

97-98: LGTM! Consistent with existing OAuth pattern.

The Google OAuth environment variables follow the same optional pattern as the GitHub credentials, allowing the feature to be conditionally enabled based on configuration.

internal-packages/database/prisma/migrations/20251204143136_add_google_auth_method/migration.sql (1)

1-2: LGTM! Correct enum extension.

The migration correctly adds the GOOGLE value to the AuthenticationMethod enum. Note that PostgreSQL's ALTER TYPE ... ADD VALUE cannot run inside a transaction, but since this is the only statement in the migration, it should execute safely.

apps/webapp/app/routes/magic.tsx (1)

42-46: LGTM! Consistent header management pattern.

The implementation correctly uses the Headers API to append multiple Set-Cookie headers (session and last-auth-method). This pattern is consistently applied in both the MFA redirect path and the final redirect path.

internal-packages/database/prisma/schema.prisma (1)

94-94: LGTM! Enum updated consistently.

The GOOGLE authentication method is correctly added to the AuthenticationMethod enum, aligning with the database migration.

apps/webapp/app/services/auth.server.ts (1)

5-5: LGTM! Consistent with existing OAuth pattern.

The Google authentication integration follows the same pattern as the existing GitHub authentication:

  • Runtime check for credential availability
  • Conditional strategy registration
  • Exported support flag for UI conditional rendering

This maintains consistency across OAuth providers.

Also applies to: 17-19, 25-27, 31-31

apps/webapp/app/services/googleAuth.server.ts (1)

9-54: LGTM! Consistent OAuth strategy implementation.

The Google authentication strategy follows the established pattern from the GitHub strategy:

  • Email validation with clear error messages
  • Proper user creation/lookup flow
  • Post-authentication processing
  • Error logging before re-throwing

The implementation correctly integrates with the existing authentication infrastructure.

apps/webapp/package.json (1)

194-194: No action needed—remix-auth-google v2.0.0 is the latest stable version with no known security vulnerabilities.

Version 2.0.0 is the latest available release on npm, and no CVEs are reported for this package. The caret constraint (^2.0.0) is appropriate and will allow patch and minor version updates. Monitor related Remix auth libraries (e.g., authkit-remix) for vulnerabilities.

apps/webapp/app/routes/auth.github.callback.tsx (1)

45-49: LGTM!

The refactoring to use Headers with multiple append calls for setting both the session and last-auth-method cookies is correct and follows the proper pattern for multiple Set-Cookie headers in Remix.

Also applies to: 55-59

apps/webapp/app/routes/login._index/route.tsx (2)

74-120: LGTM!

The loader correctly fetches lastAuthMethod from the request cookie and includes both showGoogleAuth and lastAuthMethod in both response paths. The data flow is consistent.


136-188: LGTM!

The login UI correctly renders provider buttons conditionally and displays the "Last used" badge based on the lastAuthMethod value. The form actions properly include the redirectTo query parameter.

apps/webapp/app/routes/auth.google.callback.tsx (1)

1-60: LGTM!

The Google OAuth callback follows the established pattern from the GitHub callback. The implementation correctly handles:

  • Redirect cookie parsing and sanitization
  • Authentication with the "google" strategy
  • MFA flow detection and redirect
  • Multiple Set-Cookie headers for session and last-auth-method
apps/webapp/app/services/lastAuthMethod.server.ts (1)

13-24: LGTM!

The getLastAuthMethod and setLastAuthMethodHeader functions are well-implemented with proper type safety and explicit validation of cookie values.

apps/webapp/app/models/user.server.ts (4)

24-31: LGTM!

The FindOrCreateGoogle type follows the established pattern from FindOrCreateGithub and correctly uses a type instead of an interface per coding guidelines. The union type is properly extended.


210-229: Inconsistent behavior with GitHub user linking.

When linking an existing email user to Google auth, this code updates authenticationMethod to "GOOGLE". However, findOrCreateGithubUser (lines 120-137) does not update authenticationMethod when linking. This inconsistency could cause confusion about the user's primary auth method.

Is this intentional? If so, consider adding a comment explaining why the behavior differs. If not, align the behavior:

     // Link existing email account to Google auth
     const user = await prisma.user.update({
       where: {
         email,
       },
       data: {
-        authenticationMethod: "GOOGLE",
         authenticationProfile: authProfile,
         authenticationExtraParams: authExtraParams,
         avatarUrl,
         authIdentifier,
       },
     });

250-270: LGTM!

The upsert logic for new Google users correctly sets up the user with Google authentication method and profile data. The pattern is consistent with the GitHub implementation.


183-188: All accessed fields exist on GoogleProfile type and are correctly typed.

The web search confirms that GoogleProfile from remix-auth-google includes all accessed fields:

  • _json.name: string ✓
  • photos: array of objects with value property ✓
  • displayName: string ✓
  • id: string ✓

The code safely accesses these fields. The if (authenticationProfile.photos[0]) guard on line 185 prevents null/undefined access issues.

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

🧹 Nitpick comments (4)
apps/webapp/app/assets/logos/GoogleLogo.tsx (1)

1-22: LGTM! Consider adding accessibility attributes.

The GoogleLogo component is well-implemented with proper SVG structure and styling. The named export follows the coding guidelines.

For improved accessibility, consider adding an aria-label or wrapping the SVG in a way that provides context for screen reader users, especially if this logo is used in interactive elements like buttons.

Example enhancement:

-export function GoogleLogo({ className }: { className?: string }) {
+export function GoogleLogo({ className, ariaLabel }: { className?: string; ariaLabel?: string }) {
   return (
-    <svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg 
+      className={className} 
+      viewBox="0 0 24 24" 
+      fill="none" 
+      xmlns="http://www.w3.org/2000/svg"
+      aria-label={ariaLabel}
+      role={ariaLabel ? "img" : undefined}
+    >
       <path
apps/webapp/app/routes/login._index/route.tsx (3)

22-40: LastUsedBadge implementation looks solid; consider minor a11y / UX tweaks

The motion + useReducedMotion usage is clean and respects reduced-motion preferences, and the visual treatment is clear.

Two small optional refinements:

  • To avoid screen readers announcing a detached “Last used” label without context, consider either:
    • Marking the badge container as decorative: aria-hidden="true", or
    • Wiring it via aria-describedby from the corresponding button, so it’s semantically tied to that control.
  • If you find the badge sometimes intercepts clicks near the right edge of the button, you could add pointer-events-none on the outer wrapper (and re-enable pointer events only on the button if needed).

These are polish-level changes; current behavior is acceptable if you’re okay with the existing semantics.


118-181: Multi‑provider login UI and “last used” badge behavior look coherent

The new layout with stacked GitHub, Google, and Email options is consistent:

  • Conditional rendering via data.showGithubAuth / data.showGoogleAuth is straightforward.
  • Action URLs correctly preserve redirectTo where present.
  • LastUsedBadge is correctly scoped via data.lastAuthMethod === "<provider>" and only displayed when the provider is visible.
  • data.authError && <FormError> continues to behave as expected across loader branches.

If this grows further (e.g., more providers), you might eventually want a small <AuthProviderButton> abstraction to avoid duplicating the container + Form + Button pattern, but for the current three providers the duplication is manageable.


183-191: Add rel attribute to external links that use target="_blank"

Both legal links open in a new tab via target="_blank", but lack a rel attribute. To avoid reverse‑tabnabbing and follow common security best practices, consider:

- <TextLink href="https://trigger.dev/legal" target="_blank">
+ <TextLink href="https://trigger.dev/legal" target="_blank" rel="noreferrer noopener">- <TextLink href="https://trigger.dev/legal/privacy" target="_blank">
+ <TextLink href="https://trigger.dev/legal/privacy" target="_blank" rel="noreferrer noopener">

Even though these are same‑origin links, using rel="noopener noreferrer" on all target="_blank" links is a good default.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5523569 and 9fc1dd8.

📒 Files selected for processing (2)
  • apps/webapp/app/assets/logos/GoogleLogo.tsx (1 hunks)
  • apps/webapp/app/routes/login._index/route.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/assets/logos/GoogleLogo.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
apps/webapp/app/routes/login._index/route.tsx (1)

71-82: Loader wiring for lastAuthMethod and Google support looks correct; verify value domain

The loader changes cleanly plumb lastAuthMethod and showGoogleAuth through both branches of the response, and the UI only branches on strict string matches ("github" | "google" | "email"), so unknown values gracefully result in no badge.

One thing to double‑check: ensure getLastAuthMethod(request) is constrained to a narrow union (e.g. "github" | "google" | "email" | null) and safely handles missing/invalid cookies, ideally with validation at the helper level (e.g. zod narrowing). That keeps the loader and useTypedLoaderData types tight and prevents accidental propagation of arbitrary values.

Also applies to: 103-108

where: {
authIdentifier,
},
update: {},
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the google suite, there is a way to change your email. There is an edge case when the idp user entity exists (existingUser) but the existingEmailUser doesn't. In such situation I think we want to update the user's email?

Another edge case is when user changes their email, and both existingUser and existingEmailUser exist, but they reference different user entities - conflict. Not sure if we can resolve it in code, but maybe it's worth to log it?

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fc1dd8 and ddecae4.

📒 Files selected for processing (1)
  • apps/webapp/app/models/user.server.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/models/user.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/models/user.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/models/user.server.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/models/user.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/models/user.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/app/models/user.server.ts
🧠 Learnings (2)
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL

Applied to files:

  • apps/webapp/app/models/user.server.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Leverage the PostgreSQL database through the `trigger.dev/database` Prisma 6.14.0 client in the webapp for all data access patterns

Applied to files:

  • apps/webapp/app/models/user.server.ts
🧬 Code graph analysis (1)
apps/webapp/app/models/user.server.ts (1)
apps/webapp/app/utils/email.ts (1)
  • assertEmailAllowed (3-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
apps/webapp/app/models/user.server.ts (3)

3-3: LGTM! Type definitions follow existing patterns.

The GoogleProfile import and FindOrCreateGoogle type definition are consistent with the existing GitHub authentication implementation.

Also applies to: 24-31


46-48: LGTM! Switch case properly integrated.

The Google authentication case correctly delegates to the new handler function, maintaining consistency with existing authentication methods.


176-196: LGTM! Profile extraction and validation are correct.

The email validation and profile data extraction follow the same pattern as the GitHub authentication implementation.

Comment on lines +210 to +229
if (existingEmailUser && !existingUser) {
// Link existing email account to Google auth
const user = await prisma.user.update({
where: {
email,
},
data: {
authenticationMethod: "GOOGLE",
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
avatarUrl,
authIdentifier,
},
});

return {
user,
isNewUser: false,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove authenticationMethod update when linking existing users.

When linking an existing email-based user to Google authentication, line 217 overwrites the user's authenticationMethod to "GOOGLE". This is inconsistent with the GitHub authentication implementation (lines 120-137), which does not update authenticationMethod when linking accounts.

Overwriting the authentication method could:

  • Break existing authentication flows that rely on this field
  • Prevent users from using their original authentication method
  • Create confusion about the user's original signup method

Apply this diff to maintain consistency:

     const user = await prisma.user.update({
       where: {
         email,
       },
       data: {
-        authenticationMethod: "GOOGLE",
         authenticationProfile: authProfile,
         authenticationExtraParams: authExtraParams,
         avatarUrl,
         authIdentifier,
       },
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (existingEmailUser && !existingUser) {
// Link existing email account to Google auth
const user = await prisma.user.update({
where: {
email,
},
data: {
authenticationMethod: "GOOGLE",
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
avatarUrl,
authIdentifier,
},
});
return {
user,
isNewUser: false,
};
}
if (existingEmailUser && !existingUser) {
// Link existing email account to Google auth
const user = await prisma.user.update({
where: {
email,
},
data: {
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
avatarUrl,
authIdentifier,
},
});
return {
user,
isNewUser: false,
};
}
🤖 Prompt for AI Agents
In apps/webapp/app/models/user.server.ts around lines 210 to 229, the code that
links an existing email user to Google currently overwrites authenticationMethod
to "GOOGLE"; remove that field from the prisma.user.update data so the existing
authenticationMethod is preserved (keep updating authenticationProfile,
authenticationExtraParams, avatarUrl and authIdentifier as before) to match the
GitHub linking behavior and avoid changing the user's original signup method.

Comment on lines +231 to +248
if (existingEmailUser && existingUser) {
// User already linked to Google, update profile info
const user = await prisma.user.update({
where: {
id: existingUser.id,
},
data: {
avatarUrl,
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
},
});

return {
user,
isNewUser: false,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle the edge case when different users have conflicting email and auth identifiers.

The condition on line 231 doesn't verify that existingEmailUser and existingUser reference the same user. This edge case can occur when a user changes their Google email to an address already taken by a different user in your system.

Current behavior:

  • Updates the Google-authenticated user's profile (lines 233-242)
  • Does not update the email to match Google's current email
  • Leaves the email mismatch unresolved
  • Does not log or alert about the conflict

Inconsistency: The update (lines 237-241) only modifies avatarUrl and auth profiles, while the upsert update path (lines 257-262) also updates email, displayName, and name. This creates inconsistent behavior.

Based on learnings, as per the past review comment, this edge case should be addressed.

Apply this diff to detect the conflict and update all relevant fields:

   if (existingEmailUser && existingUser) {
-    // User already linked to Google, update profile info
+    if (existingEmailUser.id !== existingUser.id) {
+      // Conflict: Google account and email belong to different users
+      // This can happen if user changes their Google email to one already in use
+      console.error(
+        `Google auth conflict: Google ID ${authenticationProfile.id} belongs to user ${existingUser.id}, ` +
+        `but email ${email} belongs to user ${existingEmailUser.id}`
+      );
+      // Return the existing Google-authenticated user without updating email
+      return {
+        user: existingUser,
+        isNewUser: false,
+      };
+    }
+
+    // User already linked to Google, update profile info
     const user = await prisma.user.update({
       where: {
         id: existingUser.id,
       },
       data: {
+        email,
+        displayName,
+        name,
         avatarUrl,
         authenticationProfile: authProfile,
         authenticationExtraParams: authExtraParams,
       },
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (existingEmailUser && existingUser) {
// User already linked to Google, update profile info
const user = await prisma.user.update({
where: {
id: existingUser.id,
},
data: {
avatarUrl,
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
},
});
return {
user,
isNewUser: false,
};
}
if (existingEmailUser && existingUser) {
if (existingEmailUser.id !== existingUser.id) {
// Conflict: Google account and email belong to different users
// This can happen if user changes their Google email to one already in use
console.error(
`Google auth conflict: Google ID ${authenticationProfile.id} belongs to user ${existingUser.id}, ` +
`but email ${email} belongs to user ${existingEmailUser.id}`
);
// Return the existing Google-authenticated user without updating email
return {
user: existingUser,
isNewUser: false,
};
}
// User already linked to Google, update profile info
const user = await prisma.user.update({
where: {
id: existingUser.id,
},
data: {
email,
displayName,
name,
avatarUrl,
authenticationProfile: authProfile,
authenticationExtraParams: authExtraParams,
},
});
return {
user,
isNewUser: false,
};
}
🤖 Prompt for AI Agents
In apps/webapp/app/models/user.server.ts around lines 231 to 248, detect if
existingEmailUser and existingUser refer to different users
(existingEmailUser.id !== existingUser.id): if they are the same user proceed to
update all profile fields (email, displayName, name, avatarUrl,
authenticationProfile, authenticationExtraParams) to match the upsert path; if
they differ, log a clear warning about the email/auth conflict and return a
conflict result (or throw a specific error) instead of silently updating, so the
caller can surface the conflict to the user for resolution.

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

🧹 Nitpick comments (1)
apps/webapp/app/routes/login._index/route.tsx (1)

22-40: Consider adding an accessible label for screen readers.

The LastUsedBadge component respects motion preferences (good!), but it lacks semantic information for assistive technologies. Screen reader users won't know which authentication method was last used.

Consider adding an aria-label to the motion.div:

      <motion.div
        className="relative rounded border border-charcoal-700 bg-charcoal-800 px-2 py-1 text-center text-xxs font-medium uppercase text-blue-500"
+       aria-label="Last used authentication method"
        initial={shouldReduceMotion ? undefined : { opacity: 0, x: 4 }}
        animate={shouldReduceMotion ? undefined : { opacity: 1, x: 0 }}
        transition={shouldReduceMotion ? undefined : { duration: 0.8, ease: "easeOut" }}
      >
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddecae4 and 7e50b54.

📒 Files selected for processing (1)
  • apps/webapp/app/routes/login._index/route.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/routes/login._index/route.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/routes/login._index/route.tsx
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/routes/login._index/route.tsx
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/app/routes/login._index/route.tsx
🧬 Code graph analysis (1)
apps/webapp/app/routes/login._index/route.tsx (6)
apps/webapp/app/services/lastAuthMethod.server.ts (1)
  • getLastAuthMethod (14-21)
apps/webapp/app/services/auth.server.ts (1)
  • isGoogleAuthSupported (31-31)
apps/webapp/app/components/primitives/Headers.tsx (1)
  • Header1 (32-50)
apps/webapp/app/components/primitives/Paragraph.tsx (1)
  • Paragraph (88-107)
apps/webapp/app/components/primitives/Buttons.tsx (1)
  • Button (296-329)
apps/webapp/app/assets/logos/GoogleLogo.tsx (1)
  • GoogleLogo (1-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/webapp/app/routes/login._index/route.tsx (4)

5-5: LGTM!

The new imports correctly support Google authentication and the last-used indicator feature. The framer-motion library is appropriately used for the animated badge component.

Also applies to: 7-7, 15-16


71-71: LGTM!

The loader correctly fetches the last-used authentication method and Google auth support flag, passing them consistently to the UI in both conditional branches.

Also applies to: 80-81, 106-107


127-179: Well-structured multi-provider authentication UI.

The conditional rendering of LastUsedBadge for each authentication method is correctly implemented. Each provider is properly wrapped in a relative container, and the form actions correctly include the redirectTo parameter.


118-194: Clean and well-organized layout structure.

The login page structure is logically organized with clear sections for the header, authentication options, error display, and legal notices. The terms and privacy links properly open in new tabs.

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.

5 participants