From 76f34501dcd3dbcfb7260f87cf8ef5d4cebb9fc3 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Wed, 12 Mar 2025 17:20:53 -0700 Subject: [PATCH] improvements: address feedback --- backend/src/server/lib/schemas.ts | 2 +- backend/src/server/routes/v1/organization-router.ts | 4 ++-- backend/src/server/routes/v2/organization-router.ts | 4 ++-- backend/src/server/routes/v3/signup-router.ts | 4 ++-- .../organization/CreateOrgModal/CreateOrgModal.tsx | 3 ++- frontend/src/lib/schemas/index.ts | 12 ++++++++++++ .../OrgNameChangeSection/OrgNameChangeSection.tsx | 3 ++- 7 files changed, 23 insertions(+), 9 deletions(-) diff --git a/backend/src/server/lib/schemas.ts b/backend/src/server/lib/schemas.ts index 28e6b0697..0d8eae848 100644 --- a/backend/src/server/lib/schemas.ts +++ b/backend/src/server/lib/schemas.ts @@ -22,7 +22,7 @@ export const slugSchema = ({ min = 1, max = 32, field = "Slug" }: SlugSchemaInpu }); }; -export const OrganizationNameSchema = z +export const GenericResourceNameSchema = z .string() .trim() .min(1, { message: "Name must be at least 1 character" }) diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index 4e8b120f8..d117a4303 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -13,7 +13,7 @@ import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-t import { AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; -import { OrganizationNameSchema, slugSchema } from "@app/server/lib/schemas"; +import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode, MfaMethod } from "@app/services/auth/auth-type"; import { sanitizedOrganizationSchema } from "@app/services/org/org-schema"; @@ -251,7 +251,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { schema: { params: z.object({ organizationId: z.string().trim() }), body: z.object({ - name: OrganizationNameSchema.optional(), + name: GenericResourceNameSchema.optional(), slug: slugSchema({ max: 64 }).optional(), authEnforced: z.boolean().optional(), scimEnabled: z.boolean().optional(), diff --git a/backend/src/server/routes/v2/organization-router.ts b/backend/src/server/routes/v2/organization-router.ts index e4f04af52..326b8a497 100644 --- a/backend/src/server/routes/v2/organization-router.ts +++ b/backend/src/server/routes/v2/organization-router.ts @@ -12,7 +12,7 @@ import { import { ORGANIZATIONS } from "@app/lib/api-docs"; import { getConfig } from "@app/lib/config/env"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; -import { OrganizationNameSchema } from "@app/server/lib/schemas"; +import { GenericResourceNameSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; @@ -331,7 +331,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { }, schema: { body: z.object({ - name: OrganizationNameSchema + name: GenericResourceNameSchema }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index b1c7c7ddc..d9196dc88 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -4,7 +4,7 @@ import { UsersSchema } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { ForbiddenRequestError } from "@app/lib/errors"; import { authRateLimit } from "@app/server/config/rateLimiter"; -import { OrganizationNameSchema } from "@app/server/lib/schemas"; +import { GenericResourceNameSchema } from "@app/server/lib/schemas"; import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; @@ -101,7 +101,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { encryptedPrivateKeyTag: z.string().trim(), salt: z.string().trim(), verifier: z.string().trim(), - organizationName: OrganizationNameSchema, + organizationName: GenericResourceNameSchema, providerAuthToken: z.string().trim().optional().nullish(), attributionSource: z.string().trim().optional(), password: z.string() diff --git a/frontend/src/components/organization/CreateOrgModal/CreateOrgModal.tsx b/frontend/src/components/organization/CreateOrgModal/CreateOrgModal.tsx index c91d8280c..bdf1c5c81 100644 --- a/frontend/src/components/organization/CreateOrgModal/CreateOrgModal.tsx +++ b/frontend/src/components/organization/CreateOrgModal/CreateOrgModal.tsx @@ -8,10 +8,11 @@ import { createNotification } from "@app/components/notifications"; import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2"; import { useCreateOrg, useSelectOrganization } from "@app/hooks/api"; import { ProjectType } from "@app/hooks/api/workspace/types"; +import { GenericResourceNameSchema } from "@app/lib/schemas"; const schema = z .object({ - name: z.string().nonempty({ message: "Name is required" }) + name: GenericResourceNameSchema.nonempty({ message: "Name is required" }) }) .required(); diff --git a/frontend/src/lib/schemas/index.ts b/frontend/src/lib/schemas/index.ts index 41b8ace4b..f46500dc8 100644 --- a/frontend/src/lib/schemas/index.ts +++ b/frontend/src/lib/schemas/index.ts @@ -1 +1,13 @@ +import { z } from "zod"; + export * from "./slugSchema"; + +export const GenericResourceNameSchema = z + .string() + .trim() + .min(1, { message: "Name must be at least 1 character" }) + .max(64, { message: "Name must be 64 or fewer characters" }) + .regex( + /^[a-zA-Z0-9\-_\s]+$/, + "Name can only contain alphanumeric characters, dashes, underscores, and spaces" + ); diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx index bcf3e0446..15ce740bc 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx @@ -14,9 +14,10 @@ import { } from "@app/context"; import { isCustomOrgRole } from "@app/helpers/roles"; import { useGetOrgRoles, useUpdateOrg } from "@app/hooks/api"; +import { GenericResourceNameSchema } from "@app/lib/schemas"; const formSchema = z.object({ - name: z.string().max(64, "Too long, maximum length is 64 characters"), + name: GenericResourceNameSchema, slug: z .string() .regex(/^[a-zA-Z0-9-]+$/, "Name must only contain alphanumeric characters or hyphens"),