[settings/security] Prevent toggle if only 1 authentication option (#10169)
fix https://github.com/twentyhq/core-team-issues/issues/387
This commit is contained in:
@ -161,6 +161,31 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
|
|||||||
customDomainRegistered = true;
|
customDomainRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const authProvidersBySystem = {
|
||||||
|
google: this.environmentService.get('AUTH_GOOGLE_ENABLED'),
|
||||||
|
password: this.environmentService.get('AUTH_PASSWORD_ENABLED'),
|
||||||
|
microsoft: this.environmentService.get('AUTH_MICROSOFT_ENABLED'),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (payload.isGoogleAuthEnabled && !authProvidersBySystem.google) {
|
||||||
|
throw new WorkspaceException(
|
||||||
|
'Google auth is not enabled in the system.',
|
||||||
|
WorkspaceExceptionCode.ENVIRONMENT_VAR_NOT_ENABLED,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (payload.isMicrosoftAuthEnabled && !authProvidersBySystem.microsoft) {
|
||||||
|
throw new WorkspaceException(
|
||||||
|
'Microsoft auth is not enabled in the system.',
|
||||||
|
WorkspaceExceptionCode.ENVIRONMENT_VAR_NOT_ENABLED,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (payload.isPasswordAuthEnabled && !authProvidersBySystem.password) {
|
||||||
|
throw new WorkspaceException(
|
||||||
|
'Password auth is not enabled in the system.',
|
||||||
|
WorkspaceExceptionCode.ENVIRONMENT_VAR_NOT_ENABLED,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
FeatureFlagKey.IsPermissionsEnabled,
|
||||||
workspace.id,
|
workspace.id,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ConflictError,
|
ConflictError,
|
||||||
|
ForbiddenError,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
@ -16,6 +17,8 @@ export const workspaceGraphqlApiExceptionHandler = (error: Error) => {
|
|||||||
throw new NotFoundError(error.message);
|
throw new NotFoundError(error.message);
|
||||||
case WorkspaceExceptionCode.SUBDOMAIN_ALREADY_TAKEN:
|
case WorkspaceExceptionCode.SUBDOMAIN_ALREADY_TAKEN:
|
||||||
throw new ConflictError(error.message);
|
throw new ConflictError(error.message);
|
||||||
|
case WorkspaceExceptionCode.ENVIRONMENT_VAR_NOT_ENABLED:
|
||||||
|
throw new ForbiddenError(error.message);
|
||||||
default:
|
default:
|
||||||
throw new InternalServerError(error.message);
|
throw new InternalServerError(error.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,4 +12,5 @@ export enum WorkspaceExceptionCode {
|
|||||||
DOMAIN_ALREADY_TAKEN = 'DOMAIN_ALREADY_TAKEN',
|
DOMAIN_ALREADY_TAKEN = 'DOMAIN_ALREADY_TAKEN',
|
||||||
WORKSPACE_NOT_FOUND = 'WORKSPACE_NOT_FOUND',
|
WORKSPACE_NOT_FOUND = 'WORKSPACE_NOT_FOUND',
|
||||||
WORKSPACE_CUSTOM_DOMAIN_DISABLED = 'WORKSPACE_CUSTOM_DOMAIN_DISABLED',
|
WORKSPACE_CUSTOM_DOMAIN_DISABLED = 'WORKSPACE_CUSTOM_DOMAIN_DISABLED',
|
||||||
|
ENVIRONMENT_VAR_NOT_ENABLED = 'ENVIRONMENT_VAR_NOT_ENABLED',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,8 @@ import {
|
|||||||
} from '@nestjs/graphql';
|
} from '@nestjs/graphql';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import assert from 'assert';
|
||||||
|
|
||||||
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
@ -17,6 +19,7 @@ import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.
|
|||||||
|
|
||||||
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||||
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
|
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
|
||||||
|
import { CustomDomainValidRecords } from 'src/engine/core-modules/domain-manager/dtos/custom-domain-valid-records';
|
||||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||||
@ -44,9 +47,7 @@ import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
|||||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||||
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
|
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
|
||||||
import { GraphqlValidationExceptionFilter } from 'src/filters/graphql-validation-exception.filter';
|
import { GraphqlValidationExceptionFilter } from 'src/filters/graphql-validation-exception.filter';
|
||||||
import { assert } from 'src/utils/assert';
|
|
||||||
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
||||||
import { CustomDomainValidRecords } from 'src/engine/core-modules/domain-manager/dtos/custom-domain-valid-records';
|
|
||||||
|
|
||||||
import { Workspace } from './workspace.entity';
|
import { Workspace } from './workspace.entity';
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ export class WorkspaceResolver {
|
|||||||
async currentWorkspace(@AuthWorkspace() { id }: Workspace) {
|
async currentWorkspace(@AuthWorkspace() { id }: Workspace) {
|
||||||
const workspace = await this.workspaceService.findById(id);
|
const workspace = await this.workspaceService.findById(id);
|
||||||
|
|
||||||
assert(workspace, 'User not found');
|
assert(workspace, 'Workspace not found');
|
||||||
|
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
@ -229,6 +230,30 @@ export class WorkspaceResolver {
|
|||||||
return this.domainManagerService.getWorkspaceUrls(workspace);
|
return this.domainManagerService.getWorkspaceUrls(workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => Boolean)
|
||||||
|
isGoogleAuthEnabled(@Parent() workspace: Workspace) {
|
||||||
|
return (
|
||||||
|
workspace.isGoogleAuthEnabled &&
|
||||||
|
this.environmentService.get('AUTH_GOOGLE_ENABLED')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => Boolean)
|
||||||
|
isMicrosoftAuthEnabled(@Parent() workspace: Workspace) {
|
||||||
|
return (
|
||||||
|
workspace.isMicrosoftAuthEnabled &&
|
||||||
|
this.environmentService.get('AUTH_MICROSOFT_ENABLED')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => Boolean)
|
||||||
|
isPasswordAuthEnabled(@Parent() workspace: Workspace) {
|
||||||
|
return (
|
||||||
|
workspace.isPasswordAuthEnabled &&
|
||||||
|
this.environmentService.get('AUTH_PASSWORD_ENABLED')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Mutation(() => CustomDomainValidRecords, { nullable: true })
|
@Mutation(() => CustomDomainValidRecords, { nullable: true })
|
||||||
@UseGuards(WorkspaceAuthGuard)
|
@UseGuards(WorkspaceAuthGuard)
|
||||||
async checkCustomDomainValidRecords(
|
async checkCustomDomainValidRecords(
|
||||||
|
|||||||
Reference in New Issue
Block a user