From c6ba6ac33b6283cd460ff4ed4e3947ecdfeb59de Mon Sep 17 00:00:00 2001 From: Anantshree Chandola Date: Tue, 11 Mar 2025 20:24:19 +0530 Subject: [PATCH] fix signup, sso and personal workspace (#12200) * fix signup, sso and personal workspace * updates * remove unused function * update * updates --- .../modules/auth/interfaces/IUtilService.ts | 2 +- server/src/modules/auth/module.ts | 8 +++++ server/src/modules/auth/oauth/service.ts | 13 +++---- server/src/modules/auth/util.service.ts | 36 ++++++------------- .../modules/group-permissions/repository.ts | 1 - .../modules/group-permissions/util.service.ts | 13 ++++--- .../instance-settings/constants/index.ts | 7 ++-- .../organization-users/util.service.ts | 15 ++++++-- server/src/modules/organizations/module.ts | 3 +- .../src/modules/setup-organization/module.ts | 5 +-- 10 files changed, 56 insertions(+), 47 deletions(-) diff --git a/server/src/modules/auth/interfaces/IUtilService.ts b/server/src/modules/auth/interfaces/IUtilService.ts index d4a62deaf3..10bb7c56f1 100644 --- a/server/src/modules/auth/interfaces/IUtilService.ts +++ b/server/src/modules/auth/interfaces/IUtilService.ts @@ -11,7 +11,7 @@ export interface IAuthUtilService { [key: string]: any; }>; verifyToken(token: string): any; - getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise>; + getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise>; getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise>; syncUserAndGroups( userResponse: UserResponse, diff --git a/server/src/modules/auth/module.ts b/server/src/modules/auth/module.ts index 6119cbef4c..c161ed6286 100644 --- a/server/src/modules/auth/module.ts +++ b/server/src/modules/auth/module.ts @@ -16,6 +16,9 @@ import { SSOResponseRepository } from '@modules/auth/oauth/repository/sso-respon import { FeatureAbilityFactory } from './ability'; import { AbilityService } from '@modules/ability/service'; import { AbilityUtilService } from '@modules/ability/util.service'; +import { GroupPermissionsRepository } from '@modules/group-permissions/repository'; +import { SetupOrganizationsModule } from '@modules/setup-organization/module'; +import { SSOConfigsRepository } from '@modules/login-configs/repository'; @Module({}) export class AuthModule { @@ -31,6 +34,7 @@ export class AuthModule { const { GoogleOAuthService } = await import(`${importPath}/auth/oauth/util-services/google-oauth.service`); const { OidcOAuthService } = await import(`${importPath}/auth/oauth/util-services/oidc-auth.service`); const { LdapService } = await import(`${importPath}/auth/oauth/util-services/ldap.service`); + const { AppEnvironmentUtilService } = await import(`${importPath}/app-environments/util.service`); return { module: AuthModule, @@ -45,6 +49,7 @@ export class AuthModule { await SessionModule.register(configs), await OrganizationUsersModule.register(configs), await LoginConfigsModule.register(configs), + await SetupOrganizationsModule.register(configs), ], controllers: [AuthController, OauthController], providers: [ @@ -64,6 +69,9 @@ export class AuthModule { FeatureAbilityFactory, AbilityService, AbilityUtilService, + AppEnvironmentUtilService, + GroupPermissionsRepository, + SSOConfigsRepository, ], exports: [AuthUtilService], }; diff --git a/server/src/modules/auth/oauth/service.ts b/server/src/modules/auth/oauth/service.ts index b289f64628..dea8283bba 100644 --- a/server/src/modules/auth/oauth/service.ts +++ b/server/src/modules/auth/oauth/service.ts @@ -36,6 +36,7 @@ import { OrganizationUsersRepository } from '@modules/organization-users/reposit import { LicenseUserService } from '@modules/licensing/services/user.service'; import { OnboardingUtilService } from '@modules/onboarding/util.service'; import { SessionUtilService } from '@modules/session/util.service'; +import { SetupOrganizationsUtilService } from '@modules/setup-organization/util.service'; const uuid = require('uuid'); @Injectable() @@ -56,7 +57,8 @@ export class OauthService implements IOAuthService { protected readonly organizationUsersRepository: OrganizationUsersRepository, protected readonly licenseUserService: LicenseUserService, protected readonly onboardingUtilService: OnboardingUtilService, - protected readonly sessionUtilService: SessionUtilService + protected readonly sessionUtilService: SessionUtilService, + protected readonly setupOrganizationsUtilService: SetupOrganizationsUtilService ) {} async signIn( @@ -172,21 +174,20 @@ export class OauthService implements IOAuthService { // Not logging in to specific organization, creating new const { name, slug } = generateNextNameAndSlug('My workspace'); - defaultOrganization = await this.organizationRepository.createOne(name, slug, manager); + defaultOrganization = await this.setupOrganizationsUtilService.create(name, slug, null, manager); userDetails = await this.userRepository.createOne( { firstName: userResponse.firstName, lastName: userResponse.lastName, email: userResponse.email, - userType: USER_ROLE.ADMIN, defaultOrganizationId: defaultOrganization.id, - ...getUserStatusAndSource(lifecycleEvents.USER_SSO_VERIFY, sso), + ...getUserStatusAndSource(lifecycleEvents.USER_SSO_ACTIVATE, sso), }, manager ); + await this.organizationUsersRepository.createOne(userDetails, defaultOrganization, false, manager); - await this.organizationUsersRepository.createOne(userDetails, defaultOrganization, true, manager); organizationDetails = defaultOrganization; } else if (userDetails) { // Finding organization to be loaded @@ -213,7 +214,7 @@ export class OauthService implements IOAuthService { if (!isInviteRedirect) { // no SSO login enabled organization available for user - creating new one const { name, slug } = generateNextNameAndSlug('My workspace'); - organizationDetails = await this.organizationRepository.createOne(name, slug, manager); + organizationDetails = await this.setupOrganizationsUtilService.create(name, slug, null, manager); await this.userRepository.updateOne( userDetails.id, { defaultOrganizationId: organizationDetails.id }, diff --git a/server/src/modules/auth/util.service.ts b/server/src/modules/auth/util.service.ts index 320520c920..623d7460a7 100644 --- a/server/src/modules/auth/util.service.ts +++ b/server/src/modules/auth/util.service.ts @@ -25,7 +25,6 @@ import { dbTransactionWrap } from 'src/helpers/database.helper'; import { DeepPartial } from 'typeorm'; import { SSOType } from '../../entities/sso_config.entity'; import { LicenseTermsService } from '../licensing/interfaces/IService'; -import { LICENSE_FIELD } from '../licensing/constants'; import { GroupPermissionsUtilService } from '../group-permissions/util.service'; import { App } from '../../entities/app.entity'; import { In } from 'typeorm'; @@ -38,7 +37,6 @@ import { RolesRepository } from '@modules/roles/repository'; import { GroupPermissions } from '@entities/group_permissions.entity'; import { ProfileUtilService } from '@modules/profile/util.service'; import { OrganizationUsersRepository } from '@modules/organization-users/repository'; -import { InstanceSSOConfigMap } from '@modules/login-configs/types'; import { SessionUtilService } from '@modules/session/util.service'; import { OnboardingStatus } from '@modules/onboarding/constants'; import { IAuthUtilService } from './interfaces/IUtilService'; @@ -196,42 +194,28 @@ export class AuthUtilService implements IAuthUtilService { return user; } - async getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise> { - const ssoConfigs = await this.getInstanceSSOConfigsOfType(ssoType); - const oidcEnabled = await this.licenseTermsService.getLicenseTerms(LICENSE_FIELD.OIDC); - - // Create a map from the ssoConfig object - const ssoConfigMap: InstanceSSOConfigMap = { - [ssoConfigs.sso]: { - enabled: ssoConfigs.enabled, - configs: ssoConfigs.configs, - }, - }; - + async getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise> { switch (ssoType) { case SSOType.GOOGLE: return { - enabled: ssoConfigMap.google.enabled || false, - configs: ssoConfigMap.google.configs || {}, + enabled: !!this.configService.get('SSO_GOOGLE_OAUTH2_CLIENT_ID'), + configs: { clientId: this.configService.get('SSO_GOOGLE_OAUTH2_CLIENT_ID') }, }; case SSOType.GIT: return { - enabled: ssoConfigMap.git.enabled || false, - configs: ssoConfigMap.git.configs || {}, - }; - case SSOType.OPENID: - return { - enabled: ssoConfigMap.openid.enabled && oidcEnabled, - configs: ssoConfigMap.openid.configs || {}, + enabled: !!this.configService.get('SSO_GIT_OAUTH2_CLIENT_ID'), + configs: { + clientId: this.configService.get('SSO_GIT_OAUTH2_CLIENT_ID'), + clientSecret: this.configService.get('SSO_GIT_OAUTH2_CLIENT_SECRET'), + hostName: this.configService.get('SSO_GIT_OAUTH2_HOST'), + }, }; default: return; } } - async getInstanceSSOConfigsOfType( - ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID - ): Promise> { + async getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise> { const instanceSettings = await this.instanceSettingsUtilService.getSettings([ INSTANCE_SYSTEM_SETTINGS.ALLOWED_DOMAINS, INSTANCE_SYSTEM_SETTINGS.ENABLE_SIGNUP, diff --git a/server/src/modules/group-permissions/repository.ts b/server/src/modules/group-permissions/repository.ts index e29b4f5e52..b8f042f6c0 100644 --- a/server/src/modules/group-permissions/repository.ts +++ b/server/src/modules/group-permissions/repository.ts @@ -20,7 +20,6 @@ import { GroupUsers } from '@entities/group_users.entity'; import { USER_STATUS, WORKSPACE_USER_STATUS } from '@modules/users/constants/lifecycle'; import { User } from '@entities/user.entity'; import { DATA_BASE_CONSTRAINTS } from './constants/error'; - @Injectable() export class GroupPermissionsRepository extends Repository { constructor(private dataSource: DataSource) { diff --git a/server/src/modules/group-permissions/util.service.ts b/server/src/modules/group-permissions/util.service.ts index 7779774ab4..c67b86f753 100644 --- a/server/src/modules/group-permissions/util.service.ts +++ b/server/src/modules/group-permissions/util.service.ts @@ -94,11 +94,14 @@ export class GroupPermissionsUtilService implements IGroupPermissionsUtilService return await dbTransactionWrap(async (manager: EntityManager) => { // Get Group details - const group = await this.groupPermissionsRepository.getGroup({ - id, - organizationId, - ...(!isLicenseValid ? noLicenseFilter : {}), - }); + const group = await this.groupPermissionsRepository.getGroup( + { + id, + organizationId, + ...(!isLicenseValid ? noLicenseFilter : {}), + }, + manager + ); if (!isLicenseValid) { if (group.name !== USER_ROLE.END_USER) { diff --git a/server/src/modules/instance-settings/constants/index.ts b/server/src/modules/instance-settings/constants/index.ts index f82b011964..49a363b156 100644 --- a/server/src/modules/instance-settings/constants/index.ts +++ b/server/src/modules/instance-settings/constants/index.ts @@ -45,11 +45,12 @@ export const INSTANCE_SETTINGS_ENCRYPTION_KEY = 'instance_settings'; export function getDefaultInstanceSettings() { return { - [INSTANCE_SYSTEM_SETTINGS.ENABLE_SIGNUP]: process.env.SSO_DISABLE_SIGNUPS, + [INSTANCE_SYSTEM_SETTINGS.ENABLE_SIGNUP]: process.env.DISABLE_SIGNUPS === 'false' ? 'true' : 'false', [INSTANCE_SYSTEM_SETTINGS.ENABLE_WORKSPACE_LOGIN_CONFIGURATION]: 'true', [INSTANCE_USER_SETTINGS.ALLOW_PERSONAL_WORKSPACE]: 'true', - [INSTANCE_USER_SETTINGS.ENABLE_MULTIPLAYER_EDITING]: process.env.ENABLE_MULTIPLAYER_EDITING, - [INSTANCE_USER_SETTINGS.ENABLE_COMMENTS]: process.env.COMMENT_FEATURE_ENABLE, + [INSTANCE_USER_SETTINGS.ENABLE_MULTIPLAYER_EDITING]: + process.env.ENABLE_MULTIPLAYER_EDITING === 'true' ? 'true' : 'false', + [INSTANCE_USER_SETTINGS.ENABLE_COMMENTS]: process.env.COMMENT_FEATURE_ENABLE === 'true' ? 'true' : 'false', [INSTANCE_SYSTEM_SETTINGS.SMTP_PORT]: process.env.SMTP_PORT, [INSTANCE_SYSTEM_SETTINGS.SMTP_DOMAIN]: process.env.SMTP_DOMAIN, [INSTANCE_SYSTEM_SETTINGS.SMTP_USERNAME]: process.env.SMTP_USERNAME, diff --git a/server/src/modules/organization-users/util.service.ts b/server/src/modules/organization-users/util.service.ts index df88da3e6c..256be761c2 100644 --- a/server/src/modules/organization-users/util.service.ts +++ b/server/src/modules/organization-users/util.service.ts @@ -40,7 +40,8 @@ import { SessionUtilService } from '@modules/session/util.service'; import { SetupOrganizationsUtilService } from '@modules/setup-organization/util.service'; import { IOrganizationUsersUtilService } from './interfaces/IUtilService'; import { EventEmitter2 } from '@nestjs/event-emitter'; - +import { GroupPermissions } from '@entities/group_permissions.entity'; +import { GroupUsers } from '@entities/group_users.entity'; @Injectable() export class OrganizationUsersUtilService implements IOrganizationUsersUtilService { constructor( @@ -147,8 +148,18 @@ export class OrganizationUsersUtilService implements IOrganizationUsersUtilServi try { for (const addGroup of groups) { + const orgGroupPermission = await this.groupPermissionsRepository.getGroup( + { + organizationId: organizationId, + name: addGroup, + }, + manager + ); + if (!orgGroupPermission) { + throw new BadRequestException(`${addGroup} group does not exist for current organization`); + } await this.groupPermissionsUtilService.addUsersToGroup( - { allowRoleChange: false, userIds: [userId], groupId: addGroup }, + { allowRoleChange: false, userIds: [userId], groupId: orgGroupPermission.id }, organizationId, manager ); diff --git a/server/src/modules/organizations/module.ts b/server/src/modules/organizations/module.ts index 77410f36bd..b7432d5e4c 100644 --- a/server/src/modules/organizations/module.ts +++ b/server/src/modules/organizations/module.ts @@ -9,12 +9,13 @@ export class OrganizationsModule { const { OrganizationsService } = await import(`${importPath}/organizations/service`); const { OrganizationsController } = await import(`${importPath}/organizations/controller`); const { FeatureAbilityFactory } = await import(`${importPath}/organizations/ability`); + const { AppEnvironmentUtilService } = await import(`${importPath}/app-environments/util.service`); return { module: OrganizationsModule, imports: [await InstanceSettingsModule.register(configs)], controllers: [OrganizationsController], - providers: [OrganizationsService, OrganizationRepository, FeatureAbilityFactory], + providers: [OrganizationsService, OrganizationRepository, FeatureAbilityFactory, AppEnvironmentUtilService], }; } } diff --git a/server/src/modules/setup-organization/module.ts b/server/src/modules/setup-organization/module.ts index 17e143b39c..9d0405886c 100644 --- a/server/src/modules/setup-organization/module.ts +++ b/server/src/modules/setup-organization/module.ts @@ -9,7 +9,7 @@ import { RolesModule } from '@modules/roles/module'; import { ThemesModule } from '@modules/organization-themes/module'; import { SessionModule } from '@modules/session/module'; import { InstanceSettingsModule } from '@modules/instance-settings/module'; -import { TooljetDbTableOperationsService } from '@modules/tooljet-db/services/tooljet-db-table-operations.service'; +import { TooljetDbModule } from '@modules/tooljet-db/module'; export class SetupOrganizationsModule { static async register(configs?: { IS_GET_CONTEXT: boolean }): Promise { @@ -29,6 +29,7 @@ export class SetupOrganizationsModule { await ThemesModule.register(configs), await SessionModule.register(configs), await InstanceSettingsModule.register(configs), + await TooljetDbModule.register(configs), ], controllers: [SetupOrganizationsController], providers: [ @@ -37,7 +38,7 @@ export class SetupOrganizationsModule { OrganizationRepository, OrganizationUsersRepository, FeatureAbilityFactory, - TooljetDbTableOperationsService, + TooljetDbModule, ], exports: [SetupOrganizationsUtilService], };