Skip to content

feat: migrate from Clerk to Auth0 authentication#355

Closed
saddlepaddle wants to merge 1 commit intomainfrom
ruling-turtle-84ebc8
Closed

feat: migrate from Clerk to Auth0 authentication#355
saddlepaddle wants to merge 1 commit intomainfrom
ruling-turtle-84ebc8

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Dec 13, 2025

Summary

  • Migrates entire codebase from Clerk to Auth0 for authentication
  • Creates new @superset/auth0 shared package with server/client exports
  • Updates all four apps (web, api, admin, marketing) to use Auth0
  • Removes all Clerk dependencies and references

Changes

  • New package: packages/auth0/ - Auth0 client wrapper with typed session helpers
  • Database schema: Renamed clerkIdauth0Id (migration needed)
  • All apps: Replaced ClerkProvider with Auth0Provider, updated middleware
  • GitHub workflows: Updated secrets from Clerk to Auth0
  • Deleted: Clerk webhook handler, SSO callback pages

Test plan

  • Set up Auth0 tenant with Google social connection
  • Configure callback URLs: http://localhost:3000/api/auth/callback
  • Add Auth0 env vars to .env
  • Run database migration: bun drizzle-kit generate --name="rename_clerk_to_auth0"
  • Test Google OAuth login flow
  • Verify session persists across refreshes
  • Test sign out functionality
  • Verify admin app restricts to company email domain

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Migrated authentication system to Auth0, providing improved identity and access management capabilities.
  • Chores

    • Updated environment configuration for Auth0 setup; removed Clerk-related variables.
    • Refreshed login and sign-up flows to utilize Auth0's OAuth integration.
    • Updated user database schema to support Auth0 user identification.

✏️ Tip: You can customize this high-level summary in your review settings.

- Create @superset/auth0 package with server/client exports
- Update all apps (web, api, admin, marketing) to use Auth0
- Replace ClerkProvider with Auth0Provider in layouts
- Update middleware to use auth0.middleware()
- Replace Clerk env vars with Auth0 env vars in turbo.jsonc
- Update GitHub workflows with Auth0 secrets
- Rename users.clerkId to users.auth0Id in schema
- Remove Clerk webhook handler
- Remove sso-callback pages (Auth0 handles callbacks internally)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 13, 2025

Walkthrough

This pull request performs a comprehensive migration of the codebase's authentication system from Clerk to Auth0. The changes span all applications (admin, api, marketing, web), introduce a new @superset/auth0 workspace package, update middleware implementations, modify package dependencies, replace environment variables, update the database schema to use auth0Id instead of clerkId, and adjust TRPC routers to work with Auth0 session data.

Changes

Cohort / File(s) Change Summary
Environment & Configuration
.env.example, turbo.jsonc
Replaced Clerk environment variables (CLERK_SECRET_KEY, CLERK_WEBHOOK_SECRET, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, etc.) with Auth0 equivalents (AUTH0_SECRET, AUTH0_BASE_URL, AUTH0_ISSUER_BASE_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET). Removed NEXT_PUBLIC_COOKIE_DOMAIN.
CI/CD Workflows
.github/workflows/deploy-preview.yml, .github/workflows/deploy-production.yml
Updated environment variables passed to deployment steps across all app contexts (API, Web, Marketing, Admin, Docs), replacing Clerk secrets with Auth0 credentials.
Admin App Package
apps/admin/package.json
Replaced @clerk/nextjs with @superset/auth0 (workspace:*).
Admin App Auth Configuration
apps/admin/src/env.ts, apps/admin/src/app/layout.tsx, apps/admin/src/proxy.ts
Updated environment schema to use Auth0 variables. Replaced ClerkProvider with Auth0Provider. Migrated middleware from Clerk to Auth0-based authentication with session handling.
Admin App UI Components
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx, apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx
Removed Clerk sign-out integration; replaced with link to /api/auth/logout. Updated text references from "Clerk account" to "Auth0 account".
API App Package
apps/api/package.json
Removed @clerk/backend and @clerk/nextjs; added @superset/auth0 (workspace:*).
API App Auth Configuration
apps/api/src/env.ts, apps/api/src/proxy.ts, apps/api/src/trpc/context.ts
Removed Clerk environment variables. Migrated middleware to Auth0. Updated TRPC context to use getSession() from Auth0 instead of Clerk.
API Webhooks
apps/api/src/app/api/webhooks/clerk/route.ts
Removed entire Clerk webhook handler including user creation, update, and deletion logic, and avatar upload functionality.
Marketing App Package
apps/marketing/package.json
Replaced @clerk/nextjs with @superset/auth0 (workspace:*).
Marketing App Auth Configuration
apps/marketing/src/env.ts, apps/marketing/src/app/layout.tsx, apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx, apps/marketing/src/proxy.ts
Updated environment schema, replaced ClerkProvider with Auth0Provider, migrated middleware, and updated session checks in CTAButtons component.
Web App Package
apps/web/package.json
Replaced @clerk/nextjs (^6.36.2) with @superset/auth0 (workspace:*).
Web App Auth Configuration
apps/web/src/env.ts, apps/web/src/app/layout.tsx, apps/web/src/proxy.ts
Updated environment schema, replaced ClerkProvider with Auth0Provider. Migrated middleware with new public path logic and Auth0 session validation.
Web App Auth Pages
apps/web/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx, apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx
Removed Clerk-based client-side authentication flows; replaced with direct OAuth links to /api/auth/login with appropriate connection and screen_hint parameters.
Web App SSO Callback
apps/web/src/app/(auth)/sso-callback/layout.tsx, apps/web/src/app/(auth)/sso-callback/page.tsx
Removed SSO callback layout and page components (no longer needed with Auth0).
Web App UI Components
apps/web/src/app/page.tsx, apps/web/src/app/download/page.tsx
Updated user data access to use Auth0 session properties (user.name, user.email, user.picture instead of Clerk equivalents). Replaced SignOutButton with logout links to /api/auth/logout.
New Auth0 Package
packages/auth0/package.json, packages/auth0/src/client.ts, packages/auth0/src/server.ts, packages/auth0/src/types.ts, packages/auth0/tsconfig.json
Introduced new @superset/auth0 workspace package with server-side session handling, client-side provider exports, and type definitions for Auth0 integration. Provides auth0 client instance, getSession() function, and session type guards.
Database Schema
packages/db/src/schema/schema.ts
Renamed clerkId column to auth0Id and updated corresponding index from users_clerk_id_idx to users_auth0_id_idx.
TRPC Package
packages/trpc/package.json
Replaced @clerk/backend with @superset/auth0 (workspace:*).
TRPC Core & Routers
packages/trpc/src/trpc.ts, packages/trpc/src/router/admin.ts, packages/trpc/src/router/organization.ts, packages/trpc/src/router/task.ts, packages/trpc/src/router/user.ts
Updated context type from SessionAuthObject to AppSession. Replaced Clerk session/userId checks with Auth0-based isSignedIn() and session.user.sub. Updated database queries to match on auth0Id instead of clerkId. Updated admin flow to extract auth0Id from session. Updated TODO/error messages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention during review:

  • Middleware implementations (apps/admin/src/proxy.ts, apps/api/src/proxy.ts, apps/web/src/proxy.ts): Verify Auth0 session retrieval, public path handling, and redirect logic are correct.
  • TRPC type changes and session narrowing (packages/trpc/src/trpc.ts): Ensure type guards and casts properly narrow AppSession to SignedInSession and that database queries consistently use the new auth0Id field.
  • New Auth0 package exports (packages/auth0/src/*): Verify that server, client, and type exports are properly structured and align with usage across applications.
  • Database field migration (packages/db/src/schema/schema.ts): Confirm that all TRPC routers and queries reference the renamed auth0Id field correctly.
  • Sign-in/sign-up OAuth redirects (apps/web/src/app/(auth)/sign-{in,up}/): Verify OAuth connection strings and screen_hint parameters are correct for Auth0.

Possibly related PRs

Poem

🐰 Hop, hop! Clerk's now gone,
Auth0 takes the crown at dawn,
Middleware flows through session's art,
Sub and secrets, fresh new start!
No more webhook whispers soft—
Just clean Auth0, shiny aloft!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description includes a summary, detailed changes, and a test plan checklist. However, it doesn't follow the provided template structure with explicit sections like 'Description', 'Related Issues', 'Type of Change', 'Testing', etc. Consider restructuring the description to follow the repository template more closely, with explicit sections for Related Issues and Type of Change (appears to be a Refactor and New feature).
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: migrating from Clerk to Auth0 authentication, which is the primary objective of this extensive changeset across multiple files and packages.
✨ 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 ruling-turtle-84ebc8

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/trpc/src/router/organization.ts (1)

60-77: Add error handling for missing user lookup.

The type safety concern is resolved—ctx.session.user.sub is properly typed as a non-nullable string because protectedProcedure guarantees a SignedInSession context.

However, the silent failure issue is valid. Other procedures in the codebase (e.g., taskRouter.create, adminProcedure) explicitly throw an error when the user lookup fails. Currently, the organization creation proceeds without a corresponding member relationship if the user is not found, leaving an orphaned organization.

Add the missing error check to align with existing patterns:

 const user = await db.query.users.findFirst({
 	where: eq(users.auth0Id, ctx.session.user.sub),
 });
+if (!user) {
+	throw new TRPCError({
+		code: "INTERNAL_SERVER_ERROR",
+		message: "User not found in database.",
+	});
+}
🧹 Nitpick comments (8)
apps/api/src/env.ts (1)

8-9: Consider adding runtime validation for Auth0 environment variables.

While the @auth0/nextjs-auth0 SDK reads these variables directly, unvalidated env vars mean misconfigurations won't be caught at startup. The SDK will fail at runtime when authentication is first attempted.

The current approach is acceptable since Auth0 provides its own error messaging, but for consistency with other validated variables (like DATABASE_URL), you could optionally add these as validated server keys with a comment noting they're also read by the SDK.

apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx (1)

21-32: Consider using Next.js Link for internal navigation.

The /api/auth/login route is an internal API route. While the <a> tag works, using Next.js Link would be more idiomatic and provide prefetching benefits where applicable.

Additionally, nesting a <Button> inside an <a> can cause accessibility concerns with nested interactive elements. Consider using asChild pattern if the Button component supports it, or apply button styling directly to the Link.

-			<a href="/api/auth/login?connection=google-oauth2&screen_hint=signup">
-				<Button variant="outline" className="w-full">
+			<Link href="/api/auth/login?connection=google-oauth2&screen_hint=signup">
+				<Button variant="outline" className="w-full" asChild>
					<Image
						src="/assets/social/google.svg"
						alt="Google"
						width={16}
						height={16}
						className="mr-2"
					/>
					Sign up with Google
				</Button>
-			</a>
+			</Link>

Note: If the Button doesn't support asChild, verify the Link behavior is correct for this Auth0 route, as API routes may require a full page navigation rather than client-side routing.

apps/web/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx (1)

19-30: Consider using asChild prop for cleaner markup.

The Button component likely supports the asChild prop (used elsewhere in this codebase). This would produce cleaner HTML without nested interactive elements.

-			<a href="/api/auth/login?connection=google-oauth2">
-				<Button variant="outline" className="w-full">
-					<Image
-						src="/assets/social/google.svg"
-						alt="Google"
-						width={16}
-						height={16}
-						className="mr-2"
-					/>
-					Sign in with Google
-				</Button>
-			</a>
+			<Button variant="outline" className="w-full" asChild>
+				<a href="/api/auth/login?connection=google-oauth2">
+					<Image
+						src="/assets/social/google.svg"
+						alt="Google"
+						width={16}
+						height={16}
+						className="mr-2"
+					/>
+					Sign in with Google
+				</a>
+			</Button>
apps/web/src/app/page.tsx (1)

67-72: Consider using asChild for the logout link.

Similar to the sign-in page, wrapping DropdownMenuItem around an anchor creates nested interactive elements. Using asChild would be cleaner.

-			<a href="/api/auth/logout">
-				<DropdownMenuItem className="cursor-pointer">
-					<LogOut className="mr-2 size-4" />
-					Sign out
-				</DropdownMenuItem>
-			</a>
+			<DropdownMenuItem className="cursor-pointer" asChild>
+				<a href="/api/auth/logout">
+					<LogOut className="mr-2 size-4" />
+					Sign out
+				</a>
+			</DropdownMenuItem>
apps/web/src/env.ts (1)

16-17: Consider validating Auth0 environment variables for consistency.

While @auth0/nextjs-auth0 reads these variables directly, other apps in this PR (admin, marketing) explicitly validate Auth0 variables in their env schemas. Skipping validation here means missing/malformed Auth0 vars will only fail at runtime rather than at startup.

For consistency and earlier error detection, consider adding the Auth0 vars to the server schema:

 server: {
   DATABASE_URL: z.string().url(),
   DATABASE_URL_UNPOOLED: z.string().url(),
-  // Auth0 env vars are read directly by @auth0/nextjs-auth0:
-  // AUTH0_SECRET, AUTH0_BASE_URL, AUTH0_ISSUER_BASE_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET
+  AUTH0_SECRET: z.string().min(1),
+  AUTH0_BASE_URL: z.string().url(),
+  AUTH0_ISSUER_BASE_URL: z.string().url(),
+  AUTH0_CLIENT_ID: z.string().min(1),
+  AUTH0_CLIENT_SECRET: z.string().min(1),
 },
packages/trpc/src/router/admin.ts (1)

43-52: LGTM!

The TODO and error message correctly reflect the Auth0 migration. The NOT_IMPLEMENTED placeholder is appropriate for now—full implementation will require integrating with the Auth0 Management API to delete users from Auth0's identity store.

Would you like me to help draft the Auth0 user deletion implementation using the Management API, or open an issue to track this work?

apps/admin/src/env.ts (1)

16-19: Auth0 environment configuration looks correct.

The required Auth0 environment variables are properly defined. Consider adding a minimum length constraint for AUTH0_SECRET (Auth0 recommends at least 32 characters for session encryption security):

-		AUTH0_SECRET: z.string(),
+		AUTH0_SECRET: z.string().min(32),
apps/admin/src/proxy.ts (1)

33-47: Verify redirect responses preserve Auth0 cookies.

The authorization logic is correct. However, when redirecting unauthenticated/unauthorized users, any cookies set by auth0.middleware() (e.g., session refresh) may be lost. Consider preserving cookies from authResponse:

 	if (!session?.user) {
-		return NextResponse.redirect(new URL(env.NEXT_PUBLIC_WEB_URL));
+		const redirect = NextResponse.redirect(new URL(env.NEXT_PUBLIC_WEB_URL));
+		// Preserve any cookies set by Auth0 middleware
+		authResponse.cookies.getAll().forEach((cookie) => {
+			redirect.cookies.set(cookie.name, cookie.value);
+		});
+		return redirect;
 	}

The same pattern would apply to the domain check redirect on line 46.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 546d0ed and df8df7f.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (42)
  • .env.example (1 hunks)
  • .github/workflows/deploy-preview.yml (4 hunks)
  • .github/workflows/deploy-production.yml (4 hunks)
  • apps/admin/package.json (1 hunks)
  • apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx (1 hunks)
  • apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx (1 hunks)
  • apps/admin/src/app/layout.tsx (3 hunks)
  • apps/admin/src/env.ts (1 hunks)
  • apps/admin/src/proxy.ts (1 hunks)
  • apps/api/package.json (1 hunks)
  • apps/api/src/app/api/webhooks/clerk/route.ts (0 hunks)
  • apps/api/src/env.ts (1 hunks)
  • apps/api/src/proxy.ts (3 hunks)
  • apps/api/src/trpc/context.ts (1 hunks)
  • apps/marketing/package.json (1 hunks)
  • apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx (1 hunks)
  • apps/marketing/src/app/layout.tsx (3 hunks)
  • apps/marketing/src/env.ts (1 hunks)
  • apps/marketing/src/proxy.ts (1 hunks)
  • apps/web/package.json (1 hunks)
  • apps/web/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx (1 hunks)
  • apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx (1 hunks)
  • apps/web/src/app/(auth)/sso-callback/layout.tsx (0 hunks)
  • apps/web/src/app/(auth)/sso-callback/page.tsx (0 hunks)
  • apps/web/src/app/download/page.tsx (1 hunks)
  • apps/web/src/app/layout.tsx (2 hunks)
  • apps/web/src/app/page.tsx (3 hunks)
  • apps/web/src/env.ts (1 hunks)
  • apps/web/src/proxy.ts (1 hunks)
  • packages/auth0/package.json (1 hunks)
  • packages/auth0/src/client.ts (1 hunks)
  • packages/auth0/src/server.ts (1 hunks)
  • packages/auth0/src/types.ts (1 hunks)
  • packages/auth0/tsconfig.json (1 hunks)
  • packages/db/src/schema/schema.ts (2 hunks)
  • packages/trpc/package.json (1 hunks)
  • packages/trpc/src/router/admin.ts (1 hunks)
  • packages/trpc/src/router/organization.ts (1 hunks)
  • packages/trpc/src/router/task.ts (1 hunks)
  • packages/trpc/src/router/user.ts (1 hunks)
  • packages/trpc/src/trpc.ts (4 hunks)
  • turbo.jsonc (1 hunks)
💤 Files with no reviewable changes (3)
  • apps/web/src/app/(auth)/sso-callback/layout.tsx
  • apps/api/src/app/api/webhooks/clerk/route.ts
  • apps/web/src/app/(auth)/sso-callback/page.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for code formatting and linting, running at root level for speed

Files:

  • apps/admin/src/app/layout.tsx
  • packages/trpc/package.json
  • apps/api/src/trpc/context.ts
  • packages/trpc/src/router/organization.ts
  • packages/auth0/src/client.ts
  • apps/marketing/package.json
  • apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx
  • apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx
  • apps/api/src/env.ts
  • apps/api/package.json
  • packages/trpc/src/router/admin.ts
  • apps/marketing/src/env.ts
  • apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • packages/auth0/src/server.ts
  • apps/admin/package.json
  • packages/trpc/src/router/user.ts
  • apps/web/package.json
  • packages/db/src/schema/schema.ts
  • apps/marketing/src/proxy.ts
  • packages/trpc/src/router/task.ts
  • packages/auth0/tsconfig.json
  • apps/admin/src/proxy.ts
  • apps/web/src/app/download/page.tsx
  • apps/web/src/env.ts
  • packages/trpc/src/trpc.ts
  • apps/web/src/app/page.tsx
  • apps/api/src/proxy.ts
  • apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx
  • apps/marketing/src/app/layout.tsx
  • packages/auth0/src/types.ts
  • apps/web/src/proxy.ts
  • packages/auth0/package.json
  • apps/admin/src/env.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid any type and prioritize type safety in TypeScript code

Files:

  • apps/admin/src/app/layout.tsx
  • apps/api/src/trpc/context.ts
  • packages/trpc/src/router/organization.ts
  • packages/auth0/src/client.ts
  • apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx
  • apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx
  • apps/api/src/env.ts
  • packages/trpc/src/router/admin.ts
  • apps/marketing/src/env.ts
  • apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • packages/auth0/src/server.ts
  • packages/trpc/src/router/user.ts
  • packages/db/src/schema/schema.ts
  • apps/marketing/src/proxy.ts
  • packages/trpc/src/router/task.ts
  • apps/admin/src/proxy.ts
  • apps/web/src/app/download/page.tsx
  • apps/web/src/env.ts
  • packages/trpc/src/trpc.ts
  • apps/web/src/app/page.tsx
  • apps/api/src/proxy.ts
  • apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx
  • apps/marketing/src/app/layout.tsx
  • packages/auth0/src/types.ts
  • apps/web/src/proxy.ts
  • apps/admin/src/env.ts
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.{ts,tsx}: Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Use one component per file (no multi-component files)

Files:

  • apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx
  • apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx
  • apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx
packages/db/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Drizzle ORM for all database operations in the packages/db package

Files:

  • packages/db/src/schema/schema.ts
**/tsconfig.json

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript config from packages/typescript-config for all workspaces

Files:

  • packages/auth0/tsconfig.json
🧠 Learnings (6)
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to packages/ui/**/*.{ts,tsx} : Use React + TailwindCSS v4 + shadcn/ui for UI components in `packages/ui`

Applied to files:

  • apps/admin/src/app/layout.tsx
  • apps/marketing/src/app/layout.tsx
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to **/components/**/*.{ts,tsx} : Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them

Applied to files:

  • apps/marketing/package.json
📚 Learning: 2025-12-12T05:45:09.673Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.673Z
Learning: Applies to **/tsconfig.json : Use TypeScript config from packages/typescript-config for all workspaces

Applied to files:

  • packages/auth0/tsconfig.json
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • packages/auth0/tsconfig.json
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • packages/trpc/src/trpc.ts
📚 Learning: 2025-12-12T05:45:09.673Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.673Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables in apps/desktop/src/main/index.ts with override: true before any imports

Applied to files:

  • apps/admin/src/env.ts
🧬 Code graph analysis (18)
apps/admin/src/app/layout.tsx (1)
packages/auth0/src/client.ts (1)
  • Auth0Provider (3-3)
apps/api/src/trpc/context.ts (1)
packages/auth0/src/server.ts (1)
  • getSession (21-27)
packages/trpc/src/router/organization.ts (1)
packages/db/src/schema/schema.ts (1)
  • users (15-35)
apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx (1)
packages/auth0/src/server.ts (1)
  • auth0 (15-15)
apps/web/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx (2)
packages/ui/src/components/ui/button.tsx (1)
  • Button (60-60)
packages/ui/src/components/ai-elements/image.tsx (1)
  • Image (9-24)
packages/auth0/src/server.ts (1)
packages/auth0/src/types.ts (1)
  • AppSession (11-11)
packages/trpc/src/router/user.ts (2)
packages/db/src/index.ts (1)
  • eq (1-1)
packages/db/src/schema/schema.ts (1)
  • users (15-35)
packages/trpc/src/router/task.ts (1)
packages/db/src/schema/schema.ts (1)
  • users (15-35)
apps/admin/src/proxy.ts (4)
packages/auth0/src/server.ts (1)
  • auth0 (15-15)
packages/db/src/index.ts (2)
  • db (2-2)
  • eq (1-1)
packages/db/src/schema/schema.ts (1)
  • users (15-35)
packages/shared/src/constants.ts (1)
  • COMPANY (2-7)
apps/web/src/app/download/page.tsx (1)
packages/ui/src/components/ui/button.tsx (1)
  • Button (60-60)
packages/trpc/src/trpc.ts (2)
packages/auth0/src/types.ts (3)
  • AppSession (11-11)
  • isSignedIn (21-23)
  • SignedInSession (16-16)
packages/db/src/schema/schema.ts (1)
  • users (15-35)
apps/web/src/app/page.tsx (3)
packages/shared/src/names/names.ts (1)
  • getInitials (14-28)
packages/ui/src/components/ui/avatar.tsx (3)
  • Avatar (53-53)
  • AvatarImage (53-53)
  • AvatarFallback (53-53)
packages/ui/src/components/ui/dropdown-menu.tsx (5)
  • DropdownMenuTrigger (251-251)
  • DropdownMenuContent (252-252)
  • DropdownMenuLabel (254-254)
  • DropdownMenuSeparator (259-259)
  • DropdownMenuItem (255-255)
apps/api/src/proxy.ts (3)
apps/admin/src/proxy.ts (1)
  • middleware (18-50)
apps/marketing/src/proxy.ts (1)
  • middleware (5-18)
apps/web/src/proxy.ts (1)
  • middleware (13-42)
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx (1)
packages/ui/src/components/ui/dropdown-menu.tsx (1)
  • DropdownMenuItem (255-255)
apps/web/src/app/layout.tsx (3)
packages/auth0/src/client.ts (1)
  • Auth0Provider (3-3)
apps/admin/src/app/providers.tsx (1)
  • Providers (9-24)
apps/web/src/app/providers.tsx (1)
  • Providers (9-24)
apps/marketing/src/app/layout.tsx (1)
packages/auth0/src/client.ts (1)
  • Auth0Provider (3-3)
packages/auth0/src/types.ts (1)
packages/auth0/src/server.ts (1)
  • auth0 (15-15)
apps/web/src/proxy.ts (4)
apps/admin/src/proxy.ts (1)
  • middleware (18-50)
apps/api/src/proxy.ts (1)
  • middleware (20-54)
apps/marketing/src/proxy.ts (1)
  • middleware (5-18)
packages/auth0/src/server.ts (1)
  • auth0 (15-15)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 14-14: [UnorderedKey] The AUTH0_BASE_URL key should go before the AUTH0_SECRET key

(UnorderedKey)


[warning] 15-15: [UnorderedKey] The AUTH0_ISSUER_BASE_URL key should go before the AUTH0_SECRET key

(UnorderedKey)


[warning] 16-16: [UnorderedKey] The AUTH0_CLIENT_ID key should go before the AUTH0_ISSUER_BASE_URL key

(UnorderedKey)


[warning] 17-17: [UnorderedKey] The AUTH0_CLIENT_SECRET key should go before the AUTH0_ISSUER_BASE_URL key

(UnorderedKey)

🔇 Additional comments (33)
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx (1)

104-109: Verify Auth0 logout endpoint configuration.

The logout implementation uses a direct anchor link to /api/auth/logout, which will trigger a full page navigation. Ensure the Auth0 logout endpoint is properly configured to clear session cookies and redirect appropriately after logout.

apps/admin/src/app/(dashboard)/users/deleted/components/DeletedUsersTable/DeletedUsersTable.tsx (1)

271-271: LGTM!

The text update from "Clerk" to "Auth0" is consistent with the authentication migration and accurately reflects the new provider.

packages/auth0/tsconfig.json (1)

1-5: LGTM!

The TypeScript configuration correctly extends the shared workspace config from @superset/typescript/internal-package.json, following the project's coding guidelines. Based on learnings, this aligns with the convention to use TypeScript config from packages/typescript-config for all workspaces.

packages/auth0/src/client.ts (1)

1-3: LGTM!

The client module correctly uses the "use client" directive and exports exactly what is needed. Both Auth0Provider and useUser are actively used across the codebase (apps/web, apps/marketing, and apps/admin), and no other client-side utilities from @auth0/nextjs-auth0 are required.

apps/web/src/app/layout.tsx (1)

1-1: LGTM! Auth0Provider correctly integrated.

The Auth0Provider properly wraps the application content, maintaining the correct provider hierarchy. This aligns with the pattern used across other apps in this migration.

Also applies to: 49-54

.env.example (1)

11-17: Auth0 environment variables correctly configured.

All required Auth0 variables are present with helpful generation instructions for the secret. The current ordering (secret → URLs → client credentials) is logical and preferable to strict alphabetical ordering.

.github/workflows/deploy-preview.yml (1)

124-127: Ensure Auth0 tenant allows preview deployment callback URLs.

Preview deployments use dynamic URLs (e.g., web-pr-{number}-superset.vercel.app). The Auth0 tenant needs to have these callback URLs allowed. Consider either:

  1. Adding a wildcard callback URL pattern in Auth0 (e.g., https://*.vercel.app/api/auth/callback)
  2. Or documenting that preview auth testing requires manual Auth0 configuration

Also applies to: 198-201

apps/web/src/app/page.tsx (1)

3-3: LGTM! Auth0 user data correctly integrated.

The migration properly maps Auth0 user claims (name, email, picture) to the UI. The firstName extraction and getInitials usage handle nullable values safely.

Also applies to: 23-28

apps/api/src/proxy.ts (2)

1-2: LGTM! Auth0 import and typing.

The import from @superset/auth0/server and explicit NextRequest typing are correct.


29-46: Verify the authResponse.status !== 200 condition logic.

This proxy checks both authResponse.status !== 200 and pathname.startsWith("/api/auth"), while other proxies in this PR (marketing, admin, web) only check the pathname.

The status check could cause unintended behavior if Auth0 middleware returns a non-200 status for reasons other than handling auth routes (e.g., internal errors). Consider aligning with the pattern used in other proxies for consistency.

.github/workflows/deploy-production.yml (1)

75-78: Verify if AUTH0_BASE_URL is needed in production deployments.

The .env.example defines AUTH0_BASE_URL but it's not passed to the deployment jobs. The Auth0 SDK typically requires this for callback URL construction. If Vercel automatically sets this via VERCEL_URL or similar, this may be fine. Otherwise, each app may need AUTH0_BASE_URL set to its production URL.

Does @auth0/nextjs-auth0 require AUTH0_BASE_URL environment variable?
apps/web/src/proxy.ts (1)

1-42: LGTM!

The Auth0 middleware implementation follows the same pattern as the admin and marketing apps. The isPublicPath helper correctly handles both exact path matches and prefix matches, and the authentication flow properly:

  1. Runs Auth0 middleware for all requests
  2. Returns Auth0 response for /api/auth/* routes
  3. Redirects authenticated users away from sign-in/sign-up pages
  4. Protects non-public routes by redirecting unauthenticated users
apps/admin/src/app/layout.tsx (1)

1-1: LGTM!

The Auth0Provider is correctly imported from the shared @superset/auth0/client package and wraps the entire application at the root level. The removal of the env import is appropriate since Auth0Provider doesn't require the cookie domain configuration that ClerkProvider needed.

Also applies to: 41-41, 56-56

apps/marketing/package.json (1)

16-16: LGTM!

Clean dependency swap from @clerk/nextjs to the internal @superset/auth0 workspace package. This aligns with the other apps in the monorepo making the same migration.

apps/api/src/trpc/context.ts (1)

1-7: LGTM! Clean migration to Auth0 session handling.

The replacement of Clerk's auth() with Auth0's getSession() is correctly implemented. The session retrieval properly handles errors (returning null on failure as shown in packages/auth0/src/server.ts), and the context creation remains compatible with the updated session type.

apps/admin/package.json (1)

14-14: LGTM! Dependency correctly migrated to Auth0.

The replacement of @clerk/nextjs with the workspace-local @superset/auth0 package aligns with the authentication migration across the monorepo.

packages/trpc/package.json (1)

17-17: LGTM! TRPC package dependency correctly updated.

The swap from @clerk/backend to the workspace-local @superset/auth0 package is consistent with the authentication migration.

packages/trpc/src/router/task.ts (1)

75-78: LGTM! Proper error handling for missing user.

The migration from clerkId to auth0Id is correctly implemented, and the explicit error throw when the user is not found (line 78) is good practice. This ensures data integrity by preventing task creation with an invalid creator reference.

turbo.jsonc (1)

7-11: Auth0 environment variables are correctly configured.

The Auth0 environment variables are properly set up. Both AUTH0_BASE_URL (your application's base URL, e.g., http://localhost:3000) and AUTH0_ISSUER_BASE_URL (your Auth0 tenant URL, e.g., https://your-tenant.auth0.com) are required and serve distinct purposes—they are not interchangeable.

The variables AUTH0_AUDIENCE and AUTH0_SCOPE are optional and only needed if your application requires API authorization; they are not required for basic authentication.

apps/web/package.json (1)

14-14: LGTM! Clean dependency migration.

The replacement of Clerk with the workspace-based Auth0 package is correctly implemented.

apps/api/package.json (1)

14-14: LGTM! Consistent with migration pattern.

The Auth0 workspace dependency addition aligns with the broader authentication migration.

apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx (2)

1-1: LGTM! Correct import for Auth0 migration.

The import correctly uses the new Auth0 server integration.


8-10: Correction: Import isSignedIn from types.

Since isSignedIn is exported from packages/auth0/src/types.ts rather than server.ts, the import should be:

 import { auth0 } from "@superset/auth0/server";
+import { isSignedIn } from "@superset/auth0/types";
 import { DOWNLOAD_URL_MAC_ARM64 } from "@superset/shared/constants";
apps/marketing/src/proxy.ts (1)

1-18: LGTM! Middleware correctly implements Auth0 integration.

The async middleware properly:

  • Runs Auth0 middleware for all requests
  • Returns Auth0's response for /api/auth/* routes
  • Allows public access to marketing routes

The explicit typing with NextRequest and the logical flow are correct.

packages/auth0/src/server.ts (1)

1-29: LGTM! Server integration is well-structured.

The Auth0 client singleton and getSession() helper are correctly implemented. The function properly handles errors by returning null for unauthenticated states, which aligns with the AppSession type definition that allows null.

The JSDoc correctly documents the required environment variables.

packages/auth0/src/types.ts (1)

1-30: LGTM! Excellent type safety implementation.

The type definitions demonstrate strong TypeScript practices:

  • Proper inference from the Auth0 SDK
  • Clear distinction between nullable (AppSession) and non-null (SignedInSession) states
  • Type guard isSignedIn correctly checks session?.user?.sub != null for robust authentication validation
  • getUserId safely accesses user.sub only when guaranteed non-null

This provides a solid foundation for type-safe Auth0 integration across the codebase.

apps/marketing/src/env.ts (1)

22-26: LGTM! Runtime environment correctly configured.

The experimental__runtimeEnv appropriately exposes only public client-side variables and excludes server-only Auth0 secrets.

packages/auth0/package.json (1)

6-19: LGTM! Export configuration correct for TypeScript workspace package.

The exports correctly map server, client, and types modules to their TypeScript source files. This pattern is appropriate for a monorepo where consuming packages handle TypeScript compilation.

apps/admin/src/proxy.ts (1)

21-27: Auth0 middleware response handling looks correct.

The pattern of running auth0.middleware(req) first and returning its response for /api/auth routes is the correct approach for Auth0 Next.js SDK v2.

packages/trpc/src/trpc.ts (4)

1-2: LGTM!

Imports are correctly updated to use Auth0 types from the new shared package.


20-28: Context type definitions are well-structured.

The AppSession type correctly models the nullable session state for unauthenticated users, and the documentation comments clearly explain the session types.


50-64: Protected procedure pattern is correct.

The isSignedIn type guard properly validates the session, and the cast to SignedInSession is safe after the guard check. The narrowed context ensures downstream procedures have access to authenticated session data.


66-93: Admin procedure correctly implements defense-in-depth.

The domain check in adminProcedure provides an additional authorization layer beyond the middleware, which is appropriate since tRPC routers could be shared across apps. The auth0Id extraction from session.user.sub aligns with Auth0's JWT structure, and the database query uses the correctly indexed auth0Id column.

Comment on lines +8 to +10
const session = await auth0.getSession();

if (userId) {
if (session?.user) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use the isSignedIn type guard for stricter authentication.

The condition session?.user is weaker than the previous userId check. According to packages/auth0/src/types.ts, the actual user identifier is user.sub, and a dedicated isSignedIn() type guard exists that checks session?.user?.sub != null.

This matters because session?.user could theoretically be an object without a valid sub, potentially allowing access without a proper user ID.

Apply this diff to use the stricter type guard:

-import { auth0 } from "@superset/auth0/server";
+import { auth0, isSignedIn } from "@superset/auth0/server";
 import { DOWNLOAD_URL_MAC_ARM64 } from "@superset/shared/constants";
 export async function CTAButtons() {
 	const session = await auth0.getSession();
 
-	if (session?.user) {
+	if (isSignedIn(session)) {
 		return (
🤖 Prompt for AI Agents
In apps/marketing/src/app/components/CTAButtons/CTAButtons.tsx around lines 8 to
10, replace the weak check `if (session?.user)` with the stricter type guard `if
(isSignedIn(session))`; import the `isSignedIn` helper from packages/auth0 (or
its exported path) if not already imported, and update the condition to call
`isSignedIn(session)` so the code verifies `session?.user?.sub != null` before
treating the user as signed in.

@@ -1,12 +1,10 @@
import { ClerkProvider } from "@clerk/nextjs";
import { Auth0Provider } from "@superset/auth0/client";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n apps/marketing/src/app/layout.tsx | head -70

Repository: superset-sh/superset

Length of output: 2277


🏁 Script executed:

cat apps/marketing/src/env.ts

Repository: superset-sh/superset

Length of output: 836


🏁 Script executed:

rg "NEXT_PUBLIC_COOKIE_DOMAIN" apps/marketing

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

rg "Auth0Provider" apps/marketing --type tsx

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

rg "export.*Auth0Provider" --type ts --type tsx -A 10

Repository: superset-sh/superset

Length of output: 91


🌐 Web query:

Auth0 React SDK Auth0Provider configuration requirements and props

💡 Result:

Summary — Auth0Provider (auth0-react)

Required / must-provide

  • domain — your Auth0 tenant domain (or custom domain). [1]
  • clientId — the Auth0 Application Client ID. [1]
  • authorizationParams.redirect_uri — the post-login redirect URI (commonly window.location.origin). The quickstart warns this must be provided or login will fail. [2]

Common/important optional props

  • authorizationParams — object for authorization parameters (audience, scope, redirect_uri, prompt, etc.). [1][2]
  • audience — (can be passed inside authorizationParams) the API identifier when requesting access tokens. [1]
  • onRedirectCallback — callback to run after redirect (useful with custom routers). [1]
  • cacheLocation — "memory" (default) or "localstorage" for token caching. [1]
  • useRefreshTokens — boolean to enable refresh token rotation (requires cacheLocation/local storage and tenant settings). [1]
  • children — your app (Auth0Provider must wrap the root App). [2]
  • onBeforeAuthorize / advanced options — see SDK docs for other props and lifecycle flags. [1]

Behavior / integration notes

  • Auth0Provider wraps the app and exposes useAuth0() hook and context (isLoading, error, login/logout, getAccessTokenSilently, etc.). [1]
  • Always wrap the root App (not a single component). [2]
  • If calling APIs, set audience and scope when requesting tokens (either in Auth0Provider authorizationParams or per call). [1][3]

References
[1] Auth0 React SDK docs (Auth0Provider usage and props).
[2] Auth0 React Quickstart — React SPA (importance of authorizationParams.redirect_uri and wrapping root App).
[3] Auth0 React GitHub / SDK site (examples and additional config notes).


🏁 Script executed:

find . -type f -name "*.ts" -o -name "*.tsx" -o -name "*.json" | xargs grep -l "@superset/auth0/client" | head -20

Repository: superset-sh/superset

Length of output: 189


🏁 Script executed:

fd "auth0" --type d | head -20

Repository: superset-sh/superset

Length of output: 79


🏁 Script executed:

fd "client" packages -type f | grep -i auth0

Repository: superset-sh/superset

Length of output: 234


🏁 Script executed:

ls -la packages/auth0/

Repository: superset-sh/superset

Length of output: 347


🏁 Script executed:

find packages/auth0 -type f -name "*.ts" -o -name "*.tsx" | head -20

Repository: superset-sh/superset

Length of output: 149


🏁 Script executed:

cat packages/auth0/package.json

Repository: superset-sh/superset

Length of output: 705


🏁 Script executed:

cat packages/auth0/src/client.ts

Repository: superset-sh/superset

Length of output: 140


🏁 Script executed:

cat packages/auth0/src/types.ts

Repository: superset-sh/superset

Length of output: 764


🌐 Web query:

@auth0/nextjs-auth0 Auth0Provider configuration props environment variables

💡 Result:

Summary — key configuration props and environment variables for @auth0/nextjs-auth0

Required environment variables (common names used by the SDK)

  • AUTH0_DOMAIN (or AUTH0_ISSUER_BASE_URL) — your tenant or custom domain. [1][2]
  • AUTH0_CLIENT_ID — Auth0 application client ID. [1][2]
  • AUTH0_CLIENT_SECRET — Auth0 application client secret (or use client assertion key). [1][2]
  • AUTH0_SECRET (aka secret) — 32-byte hex secret used to encrypt session cookies. Generate with openssl rand -hex 32. [1][2]
  • APP_BASE_URL (aka appBaseUrl / AUTH0_BASE_URL in some docs) — your app base URL (e.g. http://localhost:3000). Register callback/logout URLs in Auth0 accordingly. [1][2][3]

Optional / session / advanced environment variables

  • AUTH0_COOKIE_DOMAIN, AUTH0_COOKIE_PATH, AUTH0_COOKIE_TRANSIENT, AUTH0_COOKIE_SECURE, AUTH0_COOKIE_SAME_SITE — cookie settings. [1][2]
  • AUTH0_AUDIENCE, AUTH0_SCOPE — for requesting API access / access tokens. [3]
  • AUTH0_CLIENT_ASSERTION_SIGNING_KEY / AUTH0_CLIENT_ASSERTION_SIGNING_ALG — for private_key_jwt clients (alternative to client secret). [2]
  • AUTH0_DPOP_PUBLIC_KEY, AUTH0_DPOP_PRIVATE_KEY, AUTH0_DPOP_CLOCK_SKEW, AUTH0_DPOP_CLOCK_TOLERANCE — DPoP support keys/options. [1][2]

Main programmatic configuration options (Auth0Client / SDK init)

  • domain (string) — falls back to AUTH0_DOMAIN / AUTH0_ISSUER_BASE_URL. [2]
  • clientId (string) — falls back to AUTH0_CLIENT_ID. [2]
  • clientSecret (string) — falls back to AUTH0_CLIENT_SECRET (or use clientAssertionSigningKey). [2]
  • appBaseUrl / appBaseUrl (string) — falls back to APP_BASE_URL / AUTH0_BASE_URL. [2]
  • secret (string) — falls back to AUTH0_SECRET. [2]
  • authorizationParameters / authorizationParams — object passed to /authorize (scope, audience, redirect_uri, prompt, etc.). [2]
  • useDPoP / dpopKeyPair / dpopOptions — enable DPoP and pass keys/options. [1]

Client-side provider (UserProvider / Auth0Provider) notes

  • The Next.js SDK exposes UserProvider (or Auth0Provider in other Auth0 libs) to wrap your app and provide useUser()/useAuth hooks. For SPA-style SDKs (auth0-react) Auth0Provider takes domain, clientId and authorizationParams (redirect_uri, scope). For nextjs-auth0 you typically configure server-side via env vars and wrap with UserProvider on the client. [1][3]

Where to configure

  • Put env vars in .env.local (or your hosting platform’s environment settings). The SDK will read env vars on server-side init; you can also pass the same options programmatically to Auth0Client/initAuth0. [1][2][3]

Quick links (official docs)

  • SDK docs / API reference (auth0.github.io/nextjs-auth0). [1]
  • GitHub README (required env vars and options). [2]
  • Auth0 Next.js quickstart (setup examples and .env.local). [3]

If you want, I can show a minimal .env.local and an example auth0 client/init file for Next.js.

Sources: [1] SDK docs site, [2] GitHub README, [3] Auth0 Next.js quickstart.


🏁 Script executed:

rg "APP_BASE_URL|AUTH0_BASE_URL" packages apps

Repository: superset-sh/superset

Length of output: 342


🏁 Script executed:

rg "NEXT_PUBLIC_COOKIE_DOMAIN" --type ts --type json

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

find . -name ".env*" -type f | head -10

Repository: superset-sh/superset

Length of output: 78


🏁 Script executed:

cat .env.example

Repository: superset-sh/superset

Length of output: 1034


🏁 Script executed:

cat packages/auth0/src/server.ts

Repository: superset-sh/superset

Length of output: 686


🏁 Script executed:

cat apps/web/src/env.ts

Repository: superset-sh/superset

Length of output: 1086


🏁 Script executed:

cat apps/admin/src/env.ts

Repository: superset-sh/superset

Length of output: 948


Auth0Provider is correctly configured for Next.js environment-based setup.

The Auth0Provider from @auth0/nextjs-auth0 requires no configuration props (correct implementation). All required environment variables are properly defined in env.ts: AUTH0_SECRET, AUTH0_ISSUER_BASE_URL, AUTH0_CLIENT_ID, and AUTH0_CLIENT_SECRET.

However, note that AUTH0_BASE_URL is required by the @auth0/nextjs-auth0 SDK per the official documentation and is shown in .env.example, but it's missing from the env.ts validation schema for this app. This validation gap should be added for consistency (matching apps/admin).

The removal of NEXT_PUBLIC_COOKIE_DOMAIN is appropriate—@auth0/nextjs-auth0 handles cookie configuration via AUTH0_COOKIE_DOMAIN and related environment variables if needed, rather than requiring client-side constants.

🤖 Prompt for AI Agents
In apps/marketing/src/app/layout.tsx around lines 1 to 1, the review notes that
the AUTH0_BASE_URL env var (required by @auth0/nextjs-auth0) is missing from
this app's env.ts validation schema; update apps/marketing/src/env.ts to add
AUTH0_BASE_URL as a required string (mirror the validation used in apps/admin),
ensure it's reflected in the app's .env.example if present, and run
type/validation checks to confirm the schema change is accepted.

Comment thread apps/marketing/src/env.ts
Comment on lines +13 to +16
AUTH0_SECRET: z.string(),
AUTH0_ISSUER_BASE_URL: z.string().url(),
AUTH0_CLIENT_ID: z.string(),
AUTH0_CLIENT_SECRET: z.string(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's check the content of the server.ts file mentioned in the comment
find . -path "*/packages/auth0/src/server.ts" -type f

Repository: superset-sh/superset

Length of output: 94


🏁 Script executed:

# Also check the env.ts file in marketing app
find . -path "*/apps/marketing/src/env.ts" -type f

Repository: superset-sh/superset

Length of output: 91


🌐 Web query:

@auth0/nextjs-auth0 version 4.13.1 required environment variables configuration

💡 Result:

Required environment variables for @auth0/nextjs-auth0 v4.13.1 (minimum):

  • AUTH0_DOMAIN (or ISSUER URL) — your Auth0 tenant domain/issuer. [1][2]
  • AUTH0_CLIENT_ID — your Auth0 application client ID. [1][2]
  • AUTH0_CLIENT_SECRET — your Auth0 application client secret (or use AUTH0_CLIENT_ASSERTION_SIGNING_KEY instead). [1]
  • AUTH0_SECRET — 32-byte hex secret used to encrypt session cookies. [1][2]
  • APP_BASE_URL (or AUTH0_BASE_URL / AUTH0_APP_BASE_URL variants shown in docs) — your app’s root URL (e.g. http://localhost:3000). [1][2]

Common/optional environment variables (used for cookies, DPoP, routes, etc.):

  • AUTH0_COOKIE_DOMAIN, AUTH0_COOKIE_PATH, AUTH0_COOKIE_TRANSIENT, AUTH0_COOKIE_SECURE, AUTH0_COOKIE_SAME_SITE. [1]
  • AUTH0_CLIENT_ASSERTION_SIGNING_KEY (private key alternative to client secret). [1]
  • AUTH0_DPOP_PUBLIC_KEY, AUTH0_DPOP_PRIVATE_KEY, AUTH0_DPOP_CLOCK_SKEW, AUTH0_DPOP_CLOCK_TOLERANCE (for DPoP). [1]
  • NEXT_PUBLIC_BASE_PATH (if using Next.js basePath). [1]
  • AUTH0_AUDIENCE, AUTH0_SCOPE (when requesting API access). [2][3]

Notes:

  • The SDK requires domain, clientId, appBaseUrl, and secret; and either clientSecret or clientAssertionSigningKey — if missing, initialization will warn. [1]
  • Exact variable names shown in docs: see Auth0 Next.js SDK v4.13.1 documentation for full list and examples. [1][2]

Sources: Auth0 Next.js SDK v4.13.1 docs and quickstart. [1] https://auth0.github.io/nextjs-auth0/ (v4.13.1) [2] Auth0 blog/quickstart.


🏁 Script executed:

# Check the JSDoc in packages/auth0/src/server.ts around line 10
head -n 30 ./packages/auth0/src/server.ts

Repository: superset-sh/superset

Length of output: 686


🏁 Script executed:

# Check the full env schema in apps/marketing/src/env.ts
cat -n ./apps/marketing/src/env.ts

Repository: superset-sh/superset

Length of output: 1032


Add AUTH0_BASE_URL to the server env schema.

The JSDoc in packages/auth0/src/server.ts correctly lists AUTH0_BASE_URL as a required configuration variable. The Auth0 Next.js SDK (v4.13.1) requires this variable to specify the application's base URL for authentication callbacks. It is currently missing from the env schema in apps/marketing/src/env.ts.

 server: {
 	AUTH0_SECRET: z.string(),
+	AUTH0_BASE_URL: z.string().url(),
 	AUTH0_ISSUER_BASE_URL: z.string().url(),
 	AUTH0_CLIENT_ID: z.string(),
 	AUTH0_CLIENT_SECRET: z.string(),
 },
📝 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
AUTH0_SECRET: z.string(),
AUTH0_ISSUER_BASE_URL: z.string().url(),
AUTH0_CLIENT_ID: z.string(),
AUTH0_CLIENT_SECRET: z.string(),
AUTH0_SECRET: z.string(),
AUTH0_BASE_URL: z.string().url(),
AUTH0_ISSUER_BASE_URL: z.string().url(),
AUTH0_CLIENT_ID: z.string(),
AUTH0_CLIENT_SECRET: z.string(),
🤖 Prompt for AI Agents
In apps/marketing/src/env.ts around lines 13 to 16, the server env schema is
missing AUTH0_BASE_URL required by the Auth0 Next.js SDK; add an AUTH0_BASE_URL
entry to the zod schema (as a required URL string, e.g. AUTH0_BASE_URL:
z.string().url()) alongside the other AUTH0_* entries so the type/schema and
runtime validation include this required configuration variable.

Comment on lines +17 to +21
<a href="/api/auth/logout">
<Button variant="outline" size="sm">
Sign Out
</Button>
</SignOutButton>
</a>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the logout API route handler
find apps -name "*logout*" -type f 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Search for auth logout endpoint in route handlers
find apps -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) | xargs grep -l "auth.*logout" | grep -E "(route|api)" | head -20

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Check the structure of the apps directory
ls -la apps/ 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 558


🏁 Script executed:

# Look for route files in the apps/web directory
find apps/web -type f -name "route.*" | head -20

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Read the download page file mentioned in the review
cat apps/web/src/app/download/page.tsx 2>/dev/null | head -50

Repository: superset-sh/superset

Length of output: 1757


🏁 Script executed:

# Search for authentication-related files
find apps/web -type f -name "*.ts" -o -name "*.tsx" | grep -i auth | head -20

Repository: superset-sh/superset

Length of output: 210


🏁 Script executed:

# Look for API route handlers in apps/web
find apps/web -path "*/api/*" -type f | head -20

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Check package.json for dependencies
cat apps/web/package.json 2>/dev/null | grep -A 10 -B 2 "auth\|clerk\|Auth0"

Repository: superset-sh/superset

Length of output: 478


🏁 Script executed:

# Find the @superset/auth0 package
find . -path "*packages/*" -name "*auth0*" -type d | head -10

Repository: superset-sh/superset

Length of output: 80


🏁 Script executed:

# List packages directory
ls -la packages/ 2>/dev/null

Repository: superset-sh/superset

Length of output: 500


🏁 Script executed:

# Search for logout implementation across the codebase
rg -i "logout" --type ts --type tsx --type js --type jsx -g "!node_modules" | head -40

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

# Check for API routes in apps/api
find apps/api -type f -name "route.*" 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 105


🏁 Script executed:

# Explore the auth0 package
find packages/auth0 -type f | head -30

Repository: superset-sh/superset

Length of output: 206


🏁 Script executed:

# Check the structure of auth0 package
ls -la packages/auth0/

Repository: superset-sh/superset

Length of output: 347


🏁 Script executed:

# Read auth0 package files
cat packages/auth0/src/*.ts 2>/dev/null | head -100

Repository: superset-sh/superset

Length of output: 1464


🏁 Script executed:

# Search for logout in the entire codebase with correct rg syntax
rg -i "logout" -t js -t ts | head -50

Repository: superset-sh/superset

Length of output: 2724


🏁 Script executed:

# Search for route.ts or route.js files
find apps -name "route.ts" -o -name "route.js" 2>/dev/null

Repository: superset-sh/superset

Length of output: 105


🏁 Script executed:

# Check for middleware handling auth
find apps -name "middleware.*" -type f

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Search for dynamic routes or catch-all routes
rg -t js -t ts "\[.*\]" | grep -i "route\|auth" | head -20

Repository: superset-sh/superset

Length of output: 1743


🏁 Script executed:

# Check the main layout or app configuration for Auth0 setup
cat apps/web/src/app/layout.tsx 2>/dev/null | head -80

Repository: superset-sh/superset

Length of output: 1361


🏁 Script executed:

# Look for actual @auth0/nextjs-auth0 usage patterns
rg -t js -t ts "@auth0/nextjs-auth0" --no-heading | head -30

Repository: superset-sh/superset

Length of output: 405


🌐 Web query:

@auth0/nextjs-auth0 /api/auth/logout GET request CSRF protection

💡 Result:

Short answer: The built-in /api/auth/logout route in @auth0/nextjs-auth0 is a simple GET handler and does not implement an explicit CSRF token check for logout; this has raised community concern and requests for guidance. [1][2]

What to do

  • Treat logout as a state-changing action and avoid exposing it as an unauthenticated GET link. Replace link-triggered GETs with a POST (form or fetch) and verify a CSRF token or same-site origin on your server before calling handleLogout. (You can implement a custom logout endpoint that calls handleLogout(req,res,opts) after your CSRF/origin check.) [2][3]
  • Ensure cookies set for sessions use SameSite=strict or Lax and Secure/HttpOnly where appropriate to reduce CSRF risk.
  • If you must keep the default GET route, avoid prefetching/automatic navigation (Next ) so it cannot be triggered unintentionally. Community posts show this is a practical issue. [1][4]

References

  1. Auth0 Community thread discussing securing logout / CSRF concerns. [Auth0 Community]. [April 30, 2024].
  2. auth0/nextjs-auth0 README — lists mounted /auth/logout route (no mention of built-in CSRF protection). (GitHub).
  3. GitHub issue / examples on customizing logout (showing how to implement your own logout handler using handleLogout).
  4. Community/Reddit reports about accidental/pre-fetch triggered logout when using GET links.

If you want, I can provide a small example: a custom POST /api/auth/logout that validates a CSRF token (or Origin/Referer) and then calls handleLogout(req,res). Which example would you prefer (fetch + CSRF cookie, double-submit cookie, or Origin/Referer check)?


Secure logout with POST form to prevent CSRF attacks.

Using a plain anchor tag with GET request for logout exposes a security vulnerability:

  1. CSRF vulnerability: The /api/auth/logout route in @auth0/nextjs-auth0 handles GET requests without explicit CSRF protection. Malicious actors can trigger logout via cross-site requests (e.g., <img src="/api/auth/logout">), logging out users without their consent. This is a documented community concern with the library.

  2. Auth0 SDK guidance: The official recommendation is to avoid exposing logout as an unauthenticated GET endpoint. Instead, implement logout as a state-changing action with POST method and validate CSRF tokens or same-site origin.

  3. Accidental logout: Using a simple GET link risks unintentional logouts if prefetching is enabled or the link is triggered unexpectedly.

Replace with a POST-based form submission:

<form action="/api/auth/logout" method="POST">
  <Button variant="outline" size="sm" type="submit">
    Sign Out
  </Button>
</form>

Or create a custom logout endpoint that validates CSRF before calling the SDK's handleLogout().

🤖 Prompt for AI Agents
In apps/web/src/app/download/page.tsx around lines 17 to 21, the logout is
implemented as a GET anchor which is vulnerable to CSRF and accidental/logout
prefetching; change it to submit a POST to /api/auth/logout by replacing the
anchor with an HTML form whose action is /api/auth/logout and method is POST and
render the Button inside that form with type="submit"; optionally, if you need
extra protection, implement a custom logout endpoint that validates a CSRF token
or origin before calling the Auth0 SDK's handleLogout().

"typecheck": "tsc --noEmit --emitDeclarationOnly false"
},
"dependencies": {
"@auth0/nextjs-auth0": "^4.13.1"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

@auth0/nextjs-auth0 latest version npm

💡 Result:

As of December 13, 2025 the latest published version is 4.13.2. [Install with npm:]
npm install @auth0/nextjs-auth0@4.13.2

Sources: Yarn package listing (shows v4.13.2, Dec 4, 2025). [1] GitHub releases for the project. [2]

[1] https://classic.yarnpkg.com/en/package/%40auth0/nextjs-auth0
[2] https://github.com/auth0/nextjs-auth0/releases


🌐 Web query:

@auth0/nextjs-auth0 4.13.1 security vulnerabilities CVE

💡 Result:

Short answer: No known CVEs affecting @auth0/nextjs-auth0 version 4.13.1. The recent CVEs (e.g., CVE-2025-67716, CVE-2025-67490, CVE-2025-48947) affect earlier ranges and were fixed in 4.13.0 or earlier patch releases — upgrade to >=4.13.0 (4.13.1 is fine). [1][2][3][4]

Sources:

  • CVE-2025-67716 (input validation / returnTo) — fixed in 4.13.0. [1]
  • CVE-2025-67490 (token cache / improper request caching) — affects 4.11.x/4.12.0, patched in 4.11.2/4.12.1. [2]
  • CVE-2025-48947 (CDN caching of __session cookies) — affects <4.6.1, patched in 4.6.1. [3]
  • Vulnerability database summaries for @auth0/nextjs-auth0. [4]

References:
[1] GitLab advisory / NVD summaries for CVE-2025-67716 (fix in 4.13.0).
[2] Multiple vulnerability reports for CVE-2025-67490 (patched in 4.11.2 / 4.12.1).
[3] Snyk advisory for CVE-2025-48947 (upgrade to 4.6.1+).
[4] Aggregate vuln listings for @auth0/nextjs-auth0 (vuln timelines and affected versions).


Update @auth0/nextjs-auth0 to the latest stable version 4.13.2.

Version 4.13.1 is secure with no known CVEs, but version 4.13.2 (released Dec 4, 2025) is the current latest stable version and should be used.

🤖 Prompt for AI Agents
In packages/auth0/package.json around line 25, the dependency
"@auth0/nextjs-auth0" is pinned to "^4.13.1"; update it to "^4.13.2" to use the
latest stable release, then run your package manager (npm/yarn/pnpm) to update
node_modules and the lockfile (package-lock.json/yarn.lock/pnpm-lock.yaml), and
run the test suite or a build to verify nothing breaks.

{
id: uuid().primaryKey().defaultRandom(),
clerkId: text("clerk_id").notNull().unique(),
auth0Id: text("auth0_id").notNull().unique(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if migration file exists for the clerk to auth0 rename
fd -t f "rename_clerk_to_auth0" packages/db

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

#!/bin/bash
# Read the schema file to verify the field names and indices
head -50 packages/db/src/schema/schema.ts | cat -n

Repository: superset-sh/superset

Length of output: 1683


🏁 Script executed:

#!/bin/bash
# Look for migration files in packages/db
find packages/db -type f -name "*.sql" -o -name "*.ts" | grep -i migr | head -20

Repository: superset-sh/superset

Length of output: 110


🏁 Script executed:

#!/bin/bash
# Read the schema file focusing on lines around 19 and 32
sed -n '1,50p' packages/db/src/schema/schema.ts | cat -n

Repository: superset-sh/superset

Length of output: 1683


🏁 Script executed:

#!/bin/bash
# Check git history for changes to clerkId
git log --oneline --all -- packages/db/src/schema/schema.ts | head -20

Repository: superset-sh/superset

Length of output: 187


🏁 Script executed:

#!/bin/bash
# Read the initial migration to see the schema
cat packages/db/drizzle/0000_initial_migration.sql

Repository: superset-sh/superset

Length of output: 5073


Migration file is missing for the auth0Id field addition.

The schema definition at line 19 is correct (auth0Id: text("auth0_id").notNull().unique()), and the index at line 32 is properly configured. However, no migration file exists to add this field to the database. The initial migration (0000_initial_migration.sql) does not include the auth0_id column in the users table.

Generate the migration file by running:

bun drizzle-kit generate --name="add_auth0_id"

This will create the necessary migration to add the auth0_id column with the proper constraints to the database schema.

🤖 Prompt for AI Agents
In packages/db/src/schema/schema.ts around line 19, you added auth0Id:
text("auth0_id").notNull().unique() but did not generate a migration; run bun
drizzle-kit generate --name="add_auth0_id" to create the migration, then edit
the generated SQL so it safely adds the auth0_id column and constraints (for
existing data: add column nullable, backfill/populate values or set a temporary
default, create the UNIQUE index, and then ALTER COLUMN to NOT NULL), or
otherwise ensure the migration includes steps to avoid violating NOT NULL/UNIQUE
on existing rows before finalizing the NOT NULL constraint.

Comment on lines 9 to 13
me: protectedProcedure.query(async ({ ctx }) => {
return db.query.users.findFirst({
where: eq(users.clerkId, ctx.session.userId),
where: eq(users.auth0Id, ctx.session.user.sub),
});
}),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider error handling for missing user in the me query.

The migration from clerkId to auth0Id is correct. However, the me resolver can return undefined if no user matches the auth0Id, even though the user has a valid authenticated session. This inconsistency could occur if:

  • The database migration hasn't run yet
  • The user record was deleted but the session is still valid
  • There's a mismatch between Auth0 and the database

Compare this with packages/trpc/src/router/task.ts (line 78), which throws "User not found" in a similar scenario. Consider either:

  1. Throwing an error for consistency
  2. Documenting that undefined is an expected return value

Apply this diff for consistent error handling:

 me: protectedProcedure.query(async ({ ctx }) => {
-	return db.query.users.findFirst({
+	const user = await db.query.users.findFirst({
 		where: eq(users.auth0Id, ctx.session.user.sub),
 	});
+	if (!user) {
+		throw new Error("User not found");
+	}
+	return user;
 }),
📝 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
me: protectedProcedure.query(async ({ ctx }) => {
return db.query.users.findFirst({
where: eq(users.clerkId, ctx.session.userId),
where: eq(users.auth0Id, ctx.session.user.sub),
});
}),
me: protectedProcedure.query(async ({ ctx }) => {
const user = await db.query.users.findFirst({
where: eq(users.auth0Id, ctx.session.user.sub),
});
if (!user) {
throw new Error("User not found");
}
return user;
}),
🤖 Prompt for AI Agents
In packages/trpc/src/router/user.ts around lines 9 to 13, the me resolver can
return undefined when no user matches the auth0Id; update the handler to mirror
task.ts by checking the query result and throwing a TRPCError (e.g., code
'NOT_FOUND' with message "User not found") when the DB returns no user, and
ensure TRPCError is imported at the top of the file; this makes behavior
consistent rather than returning undefined.

@Kitenite Kitenite deleted the ruling-turtle-84ebc8 branch December 18, 2025 01:32
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.

1 participant