Skip to content

Commit 18e88aa

Browse files
waleedlatif1claude
andcommitted
fix(sso): scope domain conflict query with indexed lower(domain) filter
Address PR review: avoid a full-table scan on every SSO provider registration by filtering candidate rows in SQL with lower(domain) = <normalized>, keeping the in-memory ownership check. Also tighten the normalizeSSODomain TSDoc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4de3e07 commit 18e88aa

2 files changed

Lines changed: 6 additions & 11 deletions

File tree

apps/sim/app/api/auth/sso/register/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { db, member, ssoProvider } from '@sim/db'
22
import { createLogger } from '@sim/logger'
33
import { getErrorMessage } from '@sim/utils/errors'
4-
import { and, eq } from 'drizzle-orm'
4+
import { and, eq, sql } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { ssoRegistrationContract } from '@/lib/api/contracts/auth'
77
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -88,6 +88,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
8888
organizationId: ssoProvider.organizationId,
8989
})
9090
.from(ssoProvider)
91+
.where(eq(sql`lower(${ssoProvider.domain})`, domain))
9192
const conflictingProvider = existingProviders.find(
9293
(provider) => normalizeSSODomain(provider.domain) === domain && !isOwnedByCaller(provider)
9394
)

apps/sim/lib/auth/sso/domain.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
/**
2-
* Normalizes a user-supplied SSO email domain to a canonical, comparable form.
3-
*
4-
* Strips protocol, path, query, port, leading wildcard/`@`, an email local
5-
* part, surrounding whitespace, and a trailing dot, then lowercases the result.
6-
* Returns `null` when the input does not look like a registrable domain
7-
* (`example.com`), which callers should treat as a validation error.
8-
*
9-
* Used to compare a requested SSO domain against already-registered providers
10-
* so a tenant cannot claim a domain another tenant already owns via casing or
11-
* formatting variants.
2+
* Normalizes a user-supplied SSO email domain to a canonical, comparable form:
3+
* strips protocol, path, query, port, a leading wildcard/`@`, an email local
4+
* part, and a trailing dot, then lowercases. Returns `null` for inputs that are
5+
* not a registrable domain (e.g. `example.com`), which callers treat as invalid.
126
*/
137
export function normalizeSSODomain(input: string): string | null {
148
if (typeof input !== 'string') return null

0 commit comments

Comments
 (0)