From 47a5fc7bf71982f2e3c459292fa9f6462808e209 Mon Sep 17 00:00:00 2001 From: Rakshit Sisodiya Date: Tue, 16 Dec 2025 23:17:59 +0530 Subject: [PATCH] fix: allow organizations to sign up with existing usernames (#25941) * fix: allow organizations to sign up with existing usernames - Update usernameCheck to check organization context when currentOrgDomain is provided - Organizations can now use usernames that exist in other orgs or global namespace - Only checks username availability within the specific organization - Fixes issue where org signups were blocked by global username conflicts Refs #25800 * Update username.ts --- packages/lib/server/username.ts | 34 ++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/lib/server/username.ts b/packages/lib/server/username.ts index aaaf261a83..a02bd97202 100644 --- a/packages/lib/server/username.ts +++ b/packages/lib/server/username.ts @@ -1,5 +1,7 @@ import type { NextResponse } from "next/server"; +import { ErrorCode } from "@calcom/lib/errorCodes"; +import { ErrorWithCode } from "@calcom/lib/errors"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; import { RedirectType } from "@calcom/prisma/enums"; @@ -116,11 +118,36 @@ const usernameCheck = async (usernameRaw: string, currentOrgDomain?: string | nu const username = slugify(usernameRaw); + let organizationId: number | null = null; + if (currentOrgDomain) { + // Get organizationId from orgSlug + const organization = await prisma.team.findFirst({ + where: { + isOrganization: true, + OR: [ + { slug: currentOrgDomain }, + { metadata: { path: ["requestedSlug"], equals: currentOrgDomain } }, + ], + }, + select: { + id: true, + }, + }); + if (!organization) { + throw new ErrorWithCode( + ErrorCode.NotFound, + `Organization with domain "${currentOrgDomain}" not found`, + { currentOrgDomain } + ); + } + organizationId = organization.id; + } + const user = await prisma.user.findFirst({ where: { username, - // Simply remove it when we drop organizationId column - organizationId: null, + // Check in the specific organization context, or global namespace if no org + organizationId: organizationId ?? null, }, select: { id: true, @@ -140,12 +167,13 @@ const usernameCheck = async (usernameRaw: string, currentOrgDomain?: string | nu response.premium = true; } - // get list of similar usernames in the db + // get list of similar usernames in the db (scoped to organization if checking in org context) const users = await prisma.user.findMany({ where: { username: { contains: username, }, + ...(organizationId !== null ? { organizationId } : { organizationId: null }), }, select: { username: true,