less create workspace form fields in cloud (#1265)

* sync

* less signup form fields in cloud

* min length
This commit is contained in:
Philip Okugbe
2025-06-17 23:56:07 +01:00
committed by GitHub
parent 44445fbf46
commit 5f62448894
9 changed files with 49 additions and 29 deletions
@@ -21,7 +21,7 @@ import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts"; import APP_ROUTE from "@/lib/app-route.ts";
const formSchema = z.object({ const formSchema = z.object({
workspaceName: z.string().trim().min(3).max(50), workspaceName: z.string().trim().max(50).optional(),
name: z.string().min(1).max(50), name: z.string().min(1).max(50),
email: z email: z
.string() .string()
@@ -46,6 +46,7 @@ export function SetupWorkspaceForm() {
}); });
async function onSubmit(data: ISetupWorkspace) { async function onSubmit(data: ISetupWorkspace) {
console.log(data)
await setupWorkspace(data); await setupWorkspace(data);
} }
@@ -60,15 +61,17 @@ export function SetupWorkspaceForm() {
{isCloud() && <SsoCloudSignup />} {isCloud() && <SsoCloudSignup />}
<form onSubmit={form.onSubmit(onSubmit)}> <form onSubmit={form.onSubmit(onSubmit)}>
<TextInput {!isCloud() && (
id="workspaceName" <TextInput
type="text" id="workspaceName"
label={t("Workspace Name")} type="text"
placeholder={t("e.g ACME Inc")} label={t("Workspace Name")}
variant="filled" placeholder={t("e.g ACME Inc")}
mt="md" variant="filled"
{...form.getInputProps("workspaceName")} mt="md"
/> {...form.getInputProps("workspaceName")}
/>
)}
<TextInput <TextInput
id="name" id="name"
@@ -10,7 +10,7 @@ export interface IRegister {
} }
export interface ISetupWorkspace { export interface ISetupWorkspace {
workspaceName: string; workspaceName?: string;
name: string; name: string;
email: string; email: string;
password: string; password: string;
@@ -11,7 +11,7 @@ import { notifications } from "@mantine/notifications";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
const formSchema = z.object({ const formSchema = z.object({
name: z.string().min(2).max(40), name: z.string().min(1).max(40),
}); });
type FormValues = z.infer<typeof formSchema>; type FormValues = z.infer<typeof formSchema>;
@@ -11,7 +11,7 @@ import useUserRole from "@/hooks/use-user-role.tsx";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
const formSchema = z.object({ const formSchema = z.object({
name: z.string().min(4), name: z.string().min(1),
}); });
type FormValues = z.infer<typeof formSchema>; type FormValues = z.infer<typeof formSchema>;
+6
View File
@@ -16,6 +16,12 @@ export async function comparePasswordHash(
return bcrypt.compare(plainPassword, passwordHash); return bcrypt.compare(plainPassword, passwordHash);
} }
export function generateRandomSuffixNumbers(length: number) {
return Math.random()
.toFixed(length)
.substring(2, 2 + length);
}
export type RedisConfig = { export type RedisConfig = {
host: string; host: string;
port: number; port: number;
@@ -1,6 +1,12 @@
import { IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator'; import {
IsNotEmpty,
IsOptional,
IsString,
MaxLength,
MinLength,
} from 'class-validator';
import { CreateUserDto } from './create-user.dto'; import { CreateUserDto } from './create-user.dto';
import {Transform, TransformFnParams} from "class-transformer"; import { Transform, TransformFnParams } from 'class-transformer';
export class CreateAdminUserDto extends CreateUserDto { export class CreateAdminUserDto extends CreateUserDto {
@IsNotEmpty() @IsNotEmpty()
@@ -9,10 +15,17 @@ export class CreateAdminUserDto extends CreateUserDto {
@Transform(({ value }: TransformFnParams) => value?.trim()) @Transform(({ value }: TransformFnParams) => value?.trim())
name: string; name: string;
@IsNotEmpty() @IsOptional()
@MinLength(3) @MinLength(1)
@MaxLength(50) @MaxLength(50)
@IsString() @IsString()
@Transform(({ value }: TransformFnParams) => value?.trim()) @Transform(({ value }: TransformFnParams) => value?.trim())
workspaceName: string; workspaceName: string;
@IsOptional()
@MinLength(4)
@MaxLength(50)
@IsString()
@Transform(({ value }: TransformFnParams) => value?.trim())
hostname?: string;
} }
@@ -92,7 +92,8 @@ export class SignupService {
// create workspace with full setup // create workspace with full setup
const workspaceData: CreateWorkspaceDto = { const workspaceData: CreateWorkspaceDto = {
name: createAdminUserDto.workspaceName, name: createAdminUserDto.workspaceName || 'My workspace',
hostname: createAdminUserDto.hostname,
}; };
workspace = await this.workspaceService.create( workspace = await this.workspaceService.create(
@@ -32,6 +32,7 @@ import { AttachmentType } from 'src/core/attachment/attachment.constants';
import { InjectQueue } from '@nestjs/bullmq'; import { InjectQueue } from '@nestjs/bullmq';
import { QueueJob, QueueName } from '../../../integrations/queue/constants'; import { QueueJob, QueueName } from '../../../integrations/queue/constants';
import { Queue } from 'bullmq'; import { Queue } from 'bullmq';
import { generateRandomSuffixNumbers } from '../../../common/helpers';
@Injectable() @Injectable()
export class WorkspaceService { export class WorkspaceService {
@@ -377,24 +378,20 @@ export class WorkspaceService {
name: string, name: string,
trx?: KyselyTransaction, trx?: KyselyTransaction,
): Promise<string> { ): Promise<string> {
const generateRandomSuffix = (length: number) =>
Math.random()
.toFixed(length)
.substring(2, 2 + length);
let subdomain = name let subdomain = name
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9]/g, '') .replace(/[^a-z0-9-]/g, '')
.substring(0, 20); .substring(0, 20)
.replace(/^-+|-+$/g, ''); //remove any hyphen at the start or end
// Ensure we leave room for a random suffix. // Ensure we leave room for a random suffix.
const maxSuffixLength = 6; const maxSuffixLength = 6;
if (subdomain.length < 4) { if (subdomain.length < 4) {
subdomain = `${subdomain}-${generateRandomSuffix(maxSuffixLength)}`; subdomain = `${subdomain}-${generateRandomSuffixNumbers(maxSuffixLength)}`;
} }
if (DISALLOWED_HOSTNAMES.includes(subdomain)) { if (DISALLOWED_HOSTNAMES.includes(subdomain)) {
subdomain = `workspace-${generateRandomSuffix(maxSuffixLength)}`; subdomain = `workspace-${generateRandomSuffixNumbers(maxSuffixLength)}`;
} }
let uniqueHostname = subdomain; let uniqueHostname = subdomain;
@@ -408,7 +405,7 @@ export class WorkspaceService {
break; break;
} }
// Append a random suffix and retry. // Append a random suffix and retry.
const randomSuffix = generateRandomSuffix(maxSuffixLength); const randomSuffix = generateRandomSuffixNumbers(maxSuffixLength);
uniqueHostname = `${subdomain}-${randomSuffix}`.substring(0, 25); uniqueHostname = `${subdomain}-${randomSuffix}`.substring(0, 25);
} }