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;
}>;
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>>;
syncUserAndGroups(
userResponse: UserResponse,

View file

@ -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],
};

View file

@ -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 },

View file

@ -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<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,
},
};
async getSSOConfigs(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise<Partial<SSOConfigs>> {
switch (ssoType) {
case SSOType.GOOGLE:
return {
enabled: ssoConfigMap.google.enabled || false,
configs: ssoConfigMap.google.configs || {},
enabled: !!this.configService.get<string>('SSO_GOOGLE_OAUTH2_CLIENT_ID'),
configs: { clientId: this.configService.get<string>('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<string>('SSO_GIT_OAUTH2_CLIENT_ID'),
configs: {
clientId: this.configService.get<string>('SSO_GIT_OAUTH2_CLIENT_ID'),
clientSecret: this.configService.get<string>('SSO_GIT_OAUTH2_CLIENT_SECRET'),
hostName: this.configService.get<string>('SSO_GIT_OAUTH2_HOST'),
},
};
default:
return;
}
}
async getInstanceSSOConfigsOfType(
ssoType: SSOType.GOOGLE | SSOType.GIT | SSOType.OPENID
): Promise<DeepPartial<SSOConfigs>> {
async getInstanceSSOConfigsOfType(ssoType: SSOType.GOOGLE | SSOType.GIT): Promise<DeepPartial<SSOConfigs>> {
const instanceSettings = await this.instanceSettingsUtilService.getSettings([
INSTANCE_SYSTEM_SETTINGS.ALLOWED_DOMAINS,
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 } from '@entities/user.entity';
import { DATA_BASE_CONSTRAINTS } from './constants/error';
@Injectable()
export class GroupPermissionsRepository extends Repository<GroupPermissions> {
constructor(private dataSource: DataSource) {

View file

@ -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) {

View file

@ -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,

View file

@ -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
);

View file

@ -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],
};
}
}

View file

@ -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<DynamicModule> {
@ -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],
};