fix signup, sso and personal workspace (#12200)

* fix signup, sso and personal workspace

* updates

* remove unused function

* update

* updates
This commit is contained in:
Anantshree Chandola 2025-03-11 20:24:19 +05:30 committed by GitHub
parent 70d125f89f
commit c6ba6ac33b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 56 additions and 47 deletions

View file

@ -11,7 +11,7 @@ export interface IAuthUtilService {
[key: string]: any; [key: string]: any;
}>; }>;
verifyToken(token: string): any; verifyToken(token: string): any;
getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise<Partial<SSOConfigs>>; getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise<Partial<SSOConfigs>>;
getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise<DeepPartial<SSOConfigs>>; getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise<DeepPartial<SSOConfigs>>;
syncUserAndGroups( syncUserAndGroups(
userResponse: UserResponse, userResponse: UserResponse,

View file

@ -16,6 +16,9 @@ import { SSOResponseRepository } from '@modules/auth/oauth/repository/sso-respon
import { FeatureAbilityFactory } from './ability'; import { FeatureAbilityFactory } from './ability';
import { AbilityService } from '@modules/ability/service'; import { AbilityService } from '@modules/ability/service';
import { AbilityUtilService } from '@modules/ability/util.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({}) @Module({})
export class AuthModule { export class AuthModule {
@ -31,6 +34,7 @@ export class AuthModule {
const { GoogleOAuthService } = await import(`${importPath}/auth/oauth/util-services/google-oauth.service`); 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 { OidcOAuthService } = await import(`${importPath}/auth/oauth/util-services/oidc-auth.service`);
const { LdapService } = await import(`${importPath}/auth/oauth/util-services/ldap.service`); const { LdapService } = await import(`${importPath}/auth/oauth/util-services/ldap.service`);
const { AppEnvironmentUtilService } = await import(`${importPath}/app-environments/util.service`);
return { return {
module: AuthModule, module: AuthModule,
@ -45,6 +49,7 @@ export class AuthModule {
await SessionModule.register(configs), await SessionModule.register(configs),
await OrganizationUsersModule.register(configs), await OrganizationUsersModule.register(configs),
await LoginConfigsModule.register(configs), await LoginConfigsModule.register(configs),
await SetupOrganizationsModule.register(configs),
], ],
controllers: [AuthController, OauthController], controllers: [AuthController, OauthController],
providers: [ providers: [
@ -64,6 +69,9 @@ export class AuthModule {
FeatureAbilityFactory, FeatureAbilityFactory,
AbilityService, AbilityService,
AbilityUtilService, AbilityUtilService,
AppEnvironmentUtilService,
GroupPermissionsRepository,
SSOConfigsRepository,
], ],
exports: [AuthUtilService], exports: [AuthUtilService],
}; };

View file

@ -36,6 +36,7 @@ import { OrganizationUsersRepository } from '@modules/organization-users/reposit
import { LicenseUserService } from '@modules/licensing/services/user.service'; import { LicenseUserService } from '@modules/licensing/services/user.service';
import { OnboardingUtilService } from '@modules/onboarding/util.service'; import { OnboardingUtilService } from '@modules/onboarding/util.service';
import { SessionUtilService } from '@modules/session/util.service'; import { SessionUtilService } from '@modules/session/util.service';
import { SetupOrganizationsUtilService } from '@modules/setup-organization/util.service';
const uuid = require('uuid'); const uuid = require('uuid');
@Injectable() @Injectable()
@ -56,7 +57,8 @@ export class OauthService implements IOAuthService {
protected readonly organizationUsersRepository: OrganizationUsersRepository, protected readonly organizationUsersRepository: OrganizationUsersRepository,
protected readonly licenseUserService: LicenseUserService, protected readonly licenseUserService: LicenseUserService,
protected readonly onboardingUtilService: OnboardingUtilService, protected readonly onboardingUtilService: OnboardingUtilService,
protected readonly sessionUtilService: SessionUtilService protected readonly sessionUtilService: SessionUtilService,
protected readonly setupOrganizationsUtilService: SetupOrganizationsUtilService
) {} ) {}
async signIn( async signIn(
@ -172,21 +174,20 @@ export class OauthService implements IOAuthService {
// Not logging in to specific organization, creating new // Not logging in to specific organization, creating new
const { name, slug } = generateNextNameAndSlug('My workspace'); 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( userDetails = await this.userRepository.createOne(
{ {
firstName: userResponse.firstName, firstName: userResponse.firstName,
lastName: userResponse.lastName, lastName: userResponse.lastName,
email: userResponse.email, email: userResponse.email,
userType: USER_ROLE.ADMIN,
defaultOrganizationId: defaultOrganization.id, defaultOrganizationId: defaultOrganization.id,
...getUserStatusAndSource(lifecycleEvents.USER_SSO_VERIFY, sso), ...getUserStatusAndSource(lifecycleEvents.USER_SSO_ACTIVATE, sso),
}, },
manager manager
); );
await this.organizationUsersRepository.createOne(userDetails, defaultOrganization, false, manager);
await this.organizationUsersRepository.createOne(userDetails, defaultOrganization, true, manager);
organizationDetails = defaultOrganization; organizationDetails = defaultOrganization;
} else if (userDetails) { } else if (userDetails) {
// Finding organization to be loaded // Finding organization to be loaded
@ -213,7 +214,7 @@ export class OauthService implements IOAuthService {
if (!isInviteRedirect) { if (!isInviteRedirect) {
// no SSO login enabled organization available for user - creating new one // no SSO login enabled organization available for user - creating new one
const { name, slug } = generateNextNameAndSlug('My workspace'); 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( await this.userRepository.updateOne(
userDetails.id, userDetails.id,
{ defaultOrganizationId: organizationDetails.id }, { defaultOrganizationId: organizationDetails.id },

View file

@ -25,7 +25,6 @@ import { dbTransactionWrap } from 'src/helpers/database.helper';
import { DeepPartial } from 'typeorm'; import { DeepPartial } from 'typeorm';
import { SSOType } from '../../entities/sso_config.entity'; import { SSOType } from '../../entities/sso_config.entity';
import { LicenseTermsService } from '../licensing/interfaces/IService'; import { LicenseTermsService } from '../licensing/interfaces/IService';
import { LICENSE_FIELD } from '../licensing/constants';
import { GroupPermissionsUtilService } from '../group-permissions/util.service'; import { GroupPermissionsUtilService } from '../group-permissions/util.service';
import { App } from '../../entities/app.entity'; import { App } from '../../entities/app.entity';
import { In } from 'typeorm'; import { In } from 'typeorm';
@ -38,7 +37,6 @@ import { RolesRepository } from '@modules/roles/repository';
import { GroupPermissions } from '@entities/group_permissions.entity'; import { GroupPermissions } from '@entities/group_permissions.entity';
import { ProfileUtilService } from '@modules/profile/util.service'; import { ProfileUtilService } from '@modules/profile/util.service';
import { OrganizationUsersRepository } from '@modules/organization-users/repository'; import { OrganizationUsersRepository } from '@modules/organization-users/repository';
import { InstanceSSOConfigMap } from '@modules/login-configs/types';
import { SessionUtilService } from '@modules/session/util.service'; import { SessionUtilService } from '@modules/session/util.service';
import { OnboardingStatus } from '@modules/onboarding/constants'; import { OnboardingStatus } from '@modules/onboarding/constants';
import { IAuthUtilService } from './interfaces/IUtilService'; import { IAuthUtilService } from './interfaces/IUtilService';
@ -196,42 +194,28 @@ export class AuthUtilService implements IAuthUtilService {
return user; return user;
} }
async getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID): Promise<Partial<SSOConfigs>> { async getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise<Partial<SSOConfigs>> {
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,
},
};
switch (ssoType) { switch (ssoType) {
case SSOType.GOOGLE: case SSOType.GOOGLE:
return { return {
enabled: ssoConfigMap.google.enabled || false, enabled: !!this.configService.get<string>('SSO_GOOGLE_OAUTH2_CLIENT_ID'),
configs: ssoConfigMap.google.configs || {}, configs: { clientId: this.configService.get<string>('SSO_GOOGLE_OAUTH2_CLIENT_ID') },
}; };
case SSOType.GIT: case SSOType.GIT:
return { return {
enabled: ssoConfigMap.git.enabled || false, enabled: !!this.configService.get<string>('SSO_GIT_OAUTH2_CLIENT_ID'),
configs: ssoConfigMap.git.configs || {}, configs: {
}; clientId: this.configService.get<string>('SSO_GIT_OAUTH2_CLIENT_ID'),
case SSOType.OPENID: clientSecret: this.configService.get<string>('SSO_GIT_OAUTH2_CLIENT_SECRET'),
return { hostName: this.configService.get<string>('SSO_GIT_OAUTH2_HOST'),
enabled: ssoConfigMap.openid.enabled && oidcEnabled, },
configs: ssoConfigMap.openid.configs || {},
}; };
default: default:
return; return;
} }
} }
async getInstanceSSOConfigsOfType( async getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise<DeepPartial<SSOConfigs>> {
ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID
): Promise<DeepPartial<SSOConfigs>> {
const instanceSettings = await this.instanceSettingsUtilService.getSettings([ const instanceSettings = await this.instanceSettingsUtilService.getSettings([
INSTANCE_SYSTEM_SETTINGS.ALLOWED_DOMAINS, INSTANCE_SYSTEM_SETTINGS.ALLOWED_DOMAINS,
INSTANCE_SYSTEM_SETTINGS.ENABLE_SIGNUP, INSTANCE_SYSTEM_SETTINGS.ENABLE_SIGNUP,

View file

@ -20,7 +20,6 @@ import { GroupUsers } from '@entities/group_users.entity';
import { USER_STATUS, WORKSPACE_USER_STATUS } from '@modules/users/constants/lifecycle'; import { USER_STATUS, WORKSPACE_USER_STATUS } from '@modules/users/constants/lifecycle';
import { User } from '@entities/user.entity'; import { User } from '@entities/user.entity';
import { DATA_BASE_CONSTRAINTS } from './constants/error'; import { DATA_BASE_CONSTRAINTS } from './constants/error';
@Injectable() @Injectable()
export class GroupPermissionsRepository extends Repository<GroupPermissions> { export class GroupPermissionsRepository extends Repository<GroupPermissions> {
constructor(private dataSource: DataSource) { constructor(private dataSource: DataSource) {

View file

@ -94,11 +94,14 @@ export class GroupPermissionsUtilService implements IGroupPermissionsUtilService
return await dbTransactionWrap(async (manager: EntityManager) => { return await dbTransactionWrap(async (manager: EntityManager) => {
// Get Group details // Get Group details
const group = await this.groupPermissionsRepository.getGroup({ const group = await this.groupPermissionsRepository.getGroup(
id, {
organizationId, id,
...(!isLicenseValid ? noLicenseFilter : {}), organizationId,
}); ...(!isLicenseValid ? noLicenseFilter : {}),
},
manager
);
if (!isLicenseValid) { if (!isLicenseValid) {
if (group.name !== USER_ROLE.END_USER) { if (group.name !== USER_ROLE.END_USER) {

View file

@ -45,11 +45,12 @@ export const INSTANCE_SETTINGS_ENCRYPTION_KEY = 'instance_settings';
export function getDefaultInstanceSettings() { export function getDefaultInstanceSettings() {
return { 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_SYSTEM_SETTINGS.ENABLE_WORKSPACE_LOGIN_CONFIGURATION]: 'true',
[INSTANCE_USER_SETTINGS.ALLOW_PERSONAL_WORKSPACE]: 'true', [INSTANCE_USER_SETTINGS.ALLOW_PERSONAL_WORKSPACE]: 'true',
[INSTANCE_USER_SETTINGS.ENABLE_MULTIPLAYER_EDITING]: process.env.ENABLE_MULTIPLAYER_EDITING, [INSTANCE_USER_SETTINGS.ENABLE_MULTIPLAYER_EDITING]:
[INSTANCE_USER_SETTINGS.ENABLE_COMMENTS]: process.env.COMMENT_FEATURE_ENABLE, 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_PORT]: process.env.SMTP_PORT,
[INSTANCE_SYSTEM_SETTINGS.SMTP_DOMAIN]: process.env.SMTP_DOMAIN, [INSTANCE_SYSTEM_SETTINGS.SMTP_DOMAIN]: process.env.SMTP_DOMAIN,
[INSTANCE_SYSTEM_SETTINGS.SMTP_USERNAME]: process.env.SMTP_USERNAME, [INSTANCE_SYSTEM_SETTINGS.SMTP_USERNAME]: process.env.SMTP_USERNAME,

View file

@ -40,7 +40,8 @@ import { SessionUtilService } from '@modules/session/util.service';
import { SetupOrganizationsUtilService } from '@modules/setup-organization/util.service'; import { SetupOrganizationsUtilService } from '@modules/setup-organization/util.service';
import { IOrganizationUsersUtilService } from './interfaces/IUtilService'; import { IOrganizationUsersUtilService } from './interfaces/IUtilService';
import { EventEmitter2 } from '@nestjs/event-emitter'; import { EventEmitter2 } from '@nestjs/event-emitter';
import { GroupPermissions } from '@entities/group_permissions.entity';
import { GroupUsers } from '@entities/group_users.entity';
@Injectable() @Injectable()
export class OrganizationUsersUtilService implements IOrganizationUsersUtilService { export class OrganizationUsersUtilService implements IOrganizationUsersUtilService {
constructor( constructor(
@ -147,8 +148,18 @@ export class OrganizationUsersUtilService implements IOrganizationUsersUtilServi
try { try {
for (const addGroup of groups) { 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( await this.groupPermissionsUtilService.addUsersToGroup(
{ allowRoleChange: false, userIds: [userId], groupId: addGroup }, { allowRoleChange: false, userIds: [userId], groupId: orgGroupPermission.id },
organizationId, organizationId,
manager manager
); );

View file

@ -9,12 +9,13 @@ export class OrganizationsModule {
const { OrganizationsService } = await import(`${importPath}/organizations/service`); const { OrganizationsService } = await import(`${importPath}/organizations/service`);
const { OrganizationsController } = await import(`${importPath}/organizations/controller`); const { OrganizationsController } = await import(`${importPath}/organizations/controller`);
const { FeatureAbilityFactory } = await import(`${importPath}/organizations/ability`); const { FeatureAbilityFactory } = await import(`${importPath}/organizations/ability`);
const { AppEnvironmentUtilService } = await import(`${importPath}/app-environments/util.service`);
return { return {
module: OrganizationsModule, module: OrganizationsModule,
imports: [await InstanceSettingsModule.register(configs)], imports: [await InstanceSettingsModule.register(configs)],
controllers: [OrganizationsController], controllers: [OrganizationsController],
providers: [OrganizationsService, OrganizationRepository, FeatureAbilityFactory], providers: [OrganizationsService, OrganizationRepository, FeatureAbilityFactory, AppEnvironmentUtilService],
}; };
} }
} }

View file

@ -9,7 +9,7 @@ import { RolesModule } from '@modules/roles/module';
import { ThemesModule } from '@modules/organization-themes/module'; import { ThemesModule } from '@modules/organization-themes/module';
import { SessionModule } from '@modules/session/module'; import { SessionModule } from '@modules/session/module';
import { InstanceSettingsModule } from '@modules/instance-settings/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 { export class SetupOrganizationsModule {
static async register(configs?: { IS_GET_CONTEXT: boolean }): Promise<DynamicModule> { static async register(configs?: { IS_GET_CONTEXT: boolean }): Promise<DynamicModule> {
@ -29,6 +29,7 @@ export class SetupOrganizationsModule {
await ThemesModule.register(configs), await ThemesModule.register(configs),
await SessionModule.register(configs), await SessionModule.register(configs),
await InstanceSettingsModule.register(configs), await InstanceSettingsModule.register(configs),
await TooljetDbModule.register(configs),
], ],
controllers: [SetupOrganizationsController], controllers: [SetupOrganizationsController],
providers: [ providers: [
@ -37,7 +38,7 @@ export class SetupOrganizationsModule {
OrganizationRepository, OrganizationRepository,
OrganizationUsersRepository, OrganizationUsersRepository,
FeatureAbilityFactory, FeatureAbilityFactory,
TooljetDbTableOperationsService, TooljetDbModule,
], ],
exports: [SetupOrganizationsUtilService], exports: [SetupOrganizationsUtilService],
}; };