feat(signup): allow to block signup (#3209)

* feat(signup): allow to block signup

* feat(signup): update environment variable documentation

* test: update auth service tests

* feat(signup): prevent user from reaching out the sign up page

* Fix lint

* Fixes

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Arthur EICHELBERGER
2024-01-11 11:48:14 +01:00
committed by GitHub
parent 66a054ac21
commit c6ae480856
16 changed files with 60 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import { WorkspaceManagerService } from 'src/workspace/workspace-manager/workspa
import { FileUploadService } from 'src/core/file/services/file-upload.service';
import { Workspace } from 'src/core/workspace/workspace.entity';
import { User } from 'src/core/user/user.entity';
import { EnvironmentService } from 'src/integrations/environment/environment.service';
import { AuthService } from './auth.service';
import { TokenService } from './token.service';
@ -46,6 +47,10 @@ describe('AuthService', () => {
provide: getRepositoryToken(User, 'core'),
useValue: {},
},
{
provide: EnvironmentService,
useValue: {},
},
],
}).compile();

View File

@ -29,6 +29,7 @@ import { UserService } from 'src/core/user/services/user.service';
import { WorkspaceManagerService } from 'src/workspace/workspace-manager/workspace-manager.service';
import { getImageBufferFromUrl } from 'src/utils/image';
import { FileUploadService } from 'src/core/file/services/file-upload.service';
import { EnvironmentService } from 'src/integrations/environment/environment.service';
import { TokenService } from './token.service';
@ -50,6 +51,7 @@ export class AuthService {
@InjectRepository(User, 'core')
private readonly userRepository: Repository<User>,
private readonly httpService: HttpService,
private readonly environmentService: EnvironmentService,
) {}
async challenge(challengeInput: ChallengeInput) {
@ -114,6 +116,12 @@ export class AuthService {
ForbiddenException,
);
} else {
assert(
!this.environmentService.isSignUpDisabled(),
'Sign up is disabled',
ForbiddenException,
);
const workspaceToCreate = this.workspaceRepository.create({
displayName: '',
domainName: '',

View File

@ -59,6 +59,9 @@ export class ClientConfig {
@Field(() => Boolean)
signInPrefilled: boolean;
@Field(() => Boolean)
signUpDisabled: boolean;
@Field(() => Boolean)
debugMode: boolean;

View File

@ -26,6 +26,7 @@ export class ClientConfigResolver {
billingUrl: this.environmentService.getBillingUrl(),
},
signInPrefilled: this.environmentService.isSignInPrefilled(),
signUpDisabled: this.environmentService.isSignUpDisabled(),
debugMode: this.environmentService.isDebugMode(),
support: {
supportDriver: this.environmentService.getSupportDriver(),

View File

@ -5,6 +5,7 @@ import {
BaseGraphQLError,
ForbiddenError,
ValidationError,
NotFoundError,
} from 'src/filters/utils/graphql-errors.util';
import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service';
@ -12,6 +13,7 @@ const graphQLPredefinedExceptions = {
400: ValidationError,
401: AuthenticationError,
403: ForbiddenError,
404: NotFoundError,
};
export const handleExceptionAndConvertToGraphQLError = (

View File

@ -133,3 +133,11 @@ export class UserInputError extends BaseGraphQLError {
Object.defineProperty(this, 'name', { value: 'UserInputError' });
}
}
export class NotFoundError extends BaseGraphQLError {
constructor(message: string, extensions?: Record<string, any>) {
super(message, 'NOT_FOUND', extensions);
Object.defineProperty(this, 'name', { value: 'NotFoundError' });
}
}

View File

@ -244,4 +244,8 @@ export class EnvironmentService {
getOpenRouterApiKey(): string | undefined {
return this.configService.get<string | undefined>('OPENROUTER_API_KEY');
}
isSignUpDisabled(): boolean {
return this.configService.get<boolean>('IS_SIGN_UP_DISABLED') ?? false;
}
}

View File

@ -170,6 +170,11 @@ export class EnvironmentVariables {
)
@IsString()
SENTRY_DSN?: string;
@CastToBoolean()
@IsOptional()
@IsBoolean()
IS_SIGN_UP_DISABLED?: boolean;
}
export const validate = (config: Record<string, unknown>) => {