diff --git a/packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts index e8ed4a1553..794e6a8174 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts @@ -403,8 +403,8 @@ export class SignInUpService { ); } - private async isFirstWorkspaceForUser(userId: string): Promise { - const count = await this.userWorkspaceService.countUserWorkspaces(userId); + private async isFirstWorkspaceInSystem(): Promise { + const count = await this.workspaceRepository.count(); return count === 0; } @@ -414,7 +414,8 @@ export class SignInUpService { ): Promise { if (!this.isWorkspaceCreationLimitedToServerAdmins()) return; - if (await this.isFirstWorkspaceForUser(currentUser.id)) return; + // Only allow bypass during initial system bootstrap (no workspaces exist yet) + if (await this.isFirstWorkspaceInSystem()) return; if (!currentUser.canAccessFullAdminPanel) { throw new AuthException( @@ -445,6 +446,25 @@ export class SignInUpService { ); } + if ( + this.isWorkspaceCreationLimitedToServerAdmins() && + !(await this.isFirstWorkspaceInSystem()) + ) { + const isExistingAdmin = + userData.type === 'existingUser' && + userData.existingUser.canAccessFullAdminPanel; + + if (!isExistingAdmin) { + throw new AuthException( + 'Workspace creation is restricted to admins', + AuthExceptionCode.FORBIDDEN_EXCEPTION, + { + userFriendlyMessage: msg`Workspace creation is restricted to admins`, + }, + ); + } + } + const { canImpersonate, canAccessFullAdminPanel } = await this.setDefaultImpersonateAndAccessFullAdminPanel();