mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
fix signup, sso and personal workspace (#12200)
* fix signup, sso and personal workspace * updates * remove unused function * update * updates
This commit is contained in:
parent
70d125f89f
commit
c6ba6ac33b
10 changed files with 56 additions and 47 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 },
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue