diff --git a/backend/src/ee/routes/v1/project-router.ts b/backend/src/ee/routes/v1/project-router.ts index cfcecb8f0..606448372 100644 --- a/backend/src/ee/routes/v1/project-router.ts +++ b/backend/src/ee/routes/v1/project-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; +import { AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -19,13 +20,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.workspaceId) }), querystring: z.object({ - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), - offset: z.coerce.number().default(0), - limit: z.coerce.number().default(20) + environment: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(PROJECTS.GET_SNAPSHOTS.path), + offset: z.coerce.number().default(0).describe(PROJECTS.GET_SNAPSHOTS.offset), + limit: z.coerce.number().default(20).describe(PROJECTS.GET_SNAPSHOTS.limit) }), response: { 200: z.object({ @@ -89,16 +90,16 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.workspaceId) }), querystring: z.object({ - eventType: z.nativeEnum(EventType).optional(), - userAgentType: z.nativeEnum(UserAgentType).optional(), - startDate: z.string().datetime().optional(), - endDate: z.string().datetime().optional(), - offset: z.coerce.number().default(0), - limit: z.coerce.number().default(20), - actor: z.string().optional() + eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType), + userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType), + startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate), + endDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.endDate), + offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset), + limit: z.coerce.number().default(20).describe(AUDIT_LOGS.EXPORT.limit), + actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor) }), response: { 200: z.object({ diff --git a/backend/src/ee/routes/v1/snapshot-router.ts b/backend/src/ee/routes/v1/snapshot-router.ts index 0b858255f..79161bfd3 100644 --- a/backend/src/ee/routes/v1/snapshot-router.ts +++ b/backend/src/ee/routes/v1/snapshot-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { SecretSnapshotsSchema, SecretTagsSchema, SecretVersionsSchema } from "@app/db/schemas"; +import { PROJECTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -65,7 +66,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - secretSnapshotId: z.string().trim() + secretSnapshotId: z.string().trim().describe(PROJECTS.ROLLBACK_TO_SNAPSHOT.secretSnapshotId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/identity-access-token-router.ts b/backend/src/server/routes/v1/identity-access-token-router.ts index 78112f896..5cd0b27a1 100644 --- a/backend/src/server/routes/v1/identity-access-token-router.ts +++ b/backend/src/server/routes/v1/identity-access-token-router.ts @@ -1,5 +1,7 @@ import { z } from "zod"; +import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; + export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => { server.route({ url: "/token/renew", @@ -7,7 +9,7 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid schema: { description: "Renew access token", body: z.object({ - accessToken: z.string().trim() + accessToken: z.string().trim().describe(UNIVERSAL_AUTH.RENEW_ACCESS_TOKEN.accessToken) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/identity-router.ts b/backend/src/server/routes/v1/identity-router.ts index 0ec27a98b..ac389b478 100644 --- a/backend/src/server/routes/v1/identity-router.ts +++ b/backend/src/server/routes/v1/identity-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { IdentitiesSchema, OrgMembershipRole } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { IDENTITIES } from "@app/lib/api-docs"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -20,9 +21,9 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { } ], body: z.object({ - name: z.string().trim(), - organizationId: z.string().trim(), - role: z.string().trim().min(1).default(OrgMembershipRole.NoAccess) + name: z.string().trim().describe(IDENTITIES.CREATE.name), + organizationId: z.string().trim().describe(IDENTITIES.CREATE.organizationId), + role: z.string().trim().min(1).default(OrgMembershipRole.NoAccess).describe(IDENTITIES.CREATE.role) }), response: { 200: z.object({ @@ -78,11 +79,11 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(IDENTITIES.UPDATE.identityId) }), body: z.object({ - name: z.string().trim().optional(), - role: z.string().trim().min(1).optional() + name: z.string().trim().optional().describe(IDENTITIES.UPDATE.name), + role: z.string().trim().min(1).optional().describe(IDENTITIES.UPDATE.role) }), response: { 200: z.object({ @@ -127,7 +128,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(IDENTITIES.DELETE.identityId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/identity-ua.ts b/backend/src/server/routes/v1/identity-ua.ts index 4499a88e7..6146fa242 100644 --- a/backend/src/server/routes/v1/identity-ua.ts +++ b/backend/src/server/routes/v1/identity-ua.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { IdentityUaClientSecretsSchema, IdentityUniversalAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { TIdentityTrustedIp } from "@app/services/identity/identity-types"; @@ -26,8 +27,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { schema: { description: "Login with Universal Auth", body: z.object({ - clientId: z.string().trim(), - clientSecret: z.string().trim() + clientId: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientId), + clientSecret: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientSecret) }), response: { 200: z.object({ @@ -76,7 +77,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string().trim() + identityId: z.string().trim().describe(UNIVERSAL_AUTH.ATTACH.identityId) }), body: z.object({ clientSecretTrustedIps: z @@ -85,14 +86,16 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }) .array() .min(1) - .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]), + .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]) + .describe(UNIVERSAL_AUTH.ATTACH.clientSecretTrustedIps), accessTokenTrustedIps: z .object({ ipAddress: z.string().trim() }) .array() .min(1) - .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]), + .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]) + .describe(UNIVERSAL_AUTH.ATTACH.accessTokenTrustedIps), accessTokenTTL: z .number() .int() @@ -100,15 +103,22 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { .refine((value) => value !== 0, { message: "accessTokenTTL must have a non zero number" }) - .default(2592000), + .default(2592000) + .describe(UNIVERSAL_AUTH.ATTACH.accessTokenTTL), // 30 days accessTokenMaxTTL: z .number() .int() .refine((value) => value !== 0, { message: "accessTokenMaxTTL must have a non zero number" }) - .default(2592000), // 30 days - accessTokenNumUsesLimit: z.number().int().min(0).default(0) + .default(2592000) + .describe(UNIVERSAL_AUTH.ATTACH.accessTokenMaxTTL), // 30 days + accessTokenNumUsesLimit: z + .number() + .int() + .min(0) + .default(0) + .describe(UNIVERSAL_AUTH.ATTACH.accessTokenNumUsesLimit) }), response: { 200: z.object({ @@ -156,7 +166,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(UNIVERSAL_AUTH.UPDATE.identityId) }), body: z.object({ clientSecretTrustedIps: z @@ -165,16 +175,23 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }) .array() .min(1) - .optional(), + .optional() + .describe(UNIVERSAL_AUTH.UPDATE.clientSecretTrustedIps), accessTokenTrustedIps: z .object({ ipAddress: z.string().trim() }) .array() .min(1) - .optional(), - accessTokenTTL: z.number().int().min(0).optional(), - accessTokenNumUsesLimit: z.number().int().min(0).optional(), + .optional() + .describe(UNIVERSAL_AUTH.UPDATE.accessTokenTrustedIps), + accessTokenTTL: z.number().int().min(0).optional().describe(UNIVERSAL_AUTH.UPDATE.accessTokenTTL), + accessTokenNumUsesLimit: z + .number() + .int() + .min(0) + .optional() + .describe(UNIVERSAL_AUTH.UPDATE.accessTokenNumUsesLimit), accessTokenMaxTTL: z .number() .int() @@ -182,6 +199,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { message: "accessTokenMaxTTL must have a non zero number" }) .optional() + .describe(UNIVERSAL_AUTH.UPDATE.accessTokenMaxTTL) }), response: { 200: z.object({ @@ -230,7 +248,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(UNIVERSAL_AUTH.RETRIEVE.identityId) }), response: { 200: z.object({ @@ -273,12 +291,12 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.identityId) }), body: z.object({ - description: z.string().trim().default(""), - numUsesLimit: z.number().min(0).default(0), - ttl: z.number().min(0).default(0) + description: z.string().trim().default("").describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.description), + numUsesLimit: z.number().min(0).default(0).describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.numUsesLimit), + ttl: z.number().min(0).default(0).describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.ttl) }), response: { 200: z.object({ @@ -324,7 +342,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string() + identityId: z.string().describe(UNIVERSAL_AUTH.LIST_CLIENT_SECRETS.identityId) }), response: { 200: z.object({ @@ -366,8 +384,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - identityId: z.string(), - clientSecretId: z.string() + identityId: z.string().describe(UNIVERSAL_AUTH.REVOKE_CLIENT_SECRET.identityId), + clientSecretId: z.string().describe(UNIVERSAL_AUTH.REVOKE_CLIENT_SECRET.clientSecretId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/project-env-router.ts b/backend/src/server/routes/v1/project-env-router.ts index b93ffe928..cb5be173e 100644 --- a/backend/src/server/routes/v1/project-env-router.ts +++ b/backend/src/server/routes/v1/project-env-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { ProjectEnvironmentsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { ENVIRONMENTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -18,11 +19,11 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(ENVIRONMENTS.CREATE.workspaceId) }), body: z.object({ - name: z.string().trim(), - slug: z.string().trim() + name: z.string().trim().describe(ENVIRONMENTS.CREATE.name), + slug: z.string().trim().describe(ENVIRONMENTS.CREATE.slug) }), response: { 200: z.object({ @@ -73,13 +74,13 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim(), - id: z.string().trim() + workspaceId: z.string().trim().describe(ENVIRONMENTS.UPDATE.workspaceId), + id: z.string().trim().describe(ENVIRONMENTS.UPDATE.id) }), body: z.object({ - slug: z.string().trim().optional(), - name: z.string().trim().optional(), - position: z.number().optional() + slug: z.string().trim().optional().describe(ENVIRONMENTS.UPDATE.slug), + name: z.string().trim().optional().describe(ENVIRONMENTS.UPDATE.name), + position: z.number().optional().describe(ENVIRONMENTS.UPDATE.position) }), response: { 200: z.object({ @@ -136,8 +137,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim(), - id: z.string().trim() + workspaceId: z.string().trim().describe(ENVIRONMENTS.DELETE.workspaceId), + id: z.string().trim().describe(ENVIRONMENTS.DELETE.id) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/project-membership-router.ts b/backend/src/server/routes/v1/project-membership-router.ts index 999a5d025..aece95a5d 100644 --- a/backend/src/server/routes/v1/project-membership-router.ts +++ b/backend/src/server/routes/v1/project-membership-router.ts @@ -9,6 +9,7 @@ import { UsersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { PROJECTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types"; @@ -26,7 +27,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider } ], params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.GET_USER_MEMBERSHIPS.workspaceId) }), response: { 200: z.object({ @@ -134,8 +135,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider } ], params: z.object({ - workspaceId: z.string().trim(), - membershipId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.UPDATE_USER_MEMBERSHIP.workspaceId), + membershipId: z.string().trim().describe(PROJECTS.UPDATE_USER_MEMBERSHIP.membershipId) }), body: z.object({ roles: z @@ -156,6 +157,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider ) .min(1) .refine((data) => data.some(({ isTemporary }) => !isTemporary), "At least long lived role is required") + .describe(PROJECTS.UPDATE_USER_MEMBERSHIP.roles) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index dc32702ff..3ffedf98d 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -7,6 +7,7 @@ import { UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; +import { PROJECTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -125,7 +126,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { method: "GET", schema: { params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.GET.workspaceId) }), response: { 200: z.object({ @@ -177,7 +178,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { method: "DELETE", schema: { params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.DELETE.workspaceId) }), response: { 200: z.object({ @@ -235,11 +236,16 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { method: "PATCH", schema: { params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.UPDATE.workspaceId) }), body: z.object({ - name: z.string().trim().max(64, { message: "Name must be 64 or fewer characters" }).optional(), - autoCapitalization: z.boolean().optional() + name: z + .string() + .trim() + .max(64, { message: "Name must be 64 or fewer characters" }) + .optional() + .describe(PROJECTS.UPDATE.name), + autoCapitalization: z.boolean().optional().describe(PROJECTS.UPDATE.autoCapitalization) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/secret-folder-router.ts b/backend/src/server/routes/v1/secret-folder-router.ts index af1bf7212..dee075943 100644 --- a/backend/src/server/routes/v1/secret-folder-router.ts +++ b/backend/src/server/routes/v1/secret-folder-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { SecretFoldersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { FOLDERS } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -19,12 +20,12 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => } ], body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - name: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(FOLDERS.CREATE.workspaceId), + environment: z.string().trim().describe(FOLDERS.CREATE.environment), + name: z.string().trim().describe(FOLDERS.CREATE.name), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.CREATE.path), // backward compatiability with cli - directory: z.string().trim().default("/").transform(removeTrailingSlash) + directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.CREATE.directory) }), response: { 200: z.object({ @@ -73,15 +74,15 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => ], params: z.object({ // old way this was name - folderId: z.string() + folderId: z.string().describe(FOLDERS.UPDATE.folderId) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - name: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(FOLDERS.UPDATE.workspaceId), + environment: z.string().trim().describe(FOLDERS.UPDATE.environment), + name: z.string().trim().describe(FOLDERS.UPDATE.name), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.UPDATE.path), // backward compatiability with cli - directory: z.string().trim().default("/").transform(removeTrailingSlash) + directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.UPDATE.directory) }), response: { 200: z.object({ @@ -119,6 +120,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => } }); + // TODO(daniel): Expose this route in api reference and write docs for it. server.route({ url: "/:folderIdOrName", method: "DELETE", @@ -131,14 +133,14 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => } ], params: z.object({ - folderIdOrName: z.string() + folderIdOrName: z.string().describe(FOLDERS.DELETE.folderIdOrName) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(FOLDERS.DELETE.workspaceId), + environment: z.string().trim().describe(FOLDERS.DELETE.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.DELETE.path), // keep this here as cli need directory - directory: z.string().trim().default("/").transform(removeTrailingSlash) + directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.DELETE.directory) }), response: { 200: z.object({ @@ -187,11 +189,11 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => } ], querystring: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(FOLDERS.LIST.workspaceId), + environment: z.string().trim().describe(FOLDERS.LIST.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.LIST.path), // backward compatiability with cli - directory: z.string().trim().default("/").transform(removeTrailingSlash) + directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.LIST.directory) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/secret-import-router.ts b/backend/src/server/routes/v1/secret-import-router.ts index 2ec2d5ce2..823e7dbee 100644 --- a/backend/src/server/routes/v1/secret-import-router.ts +++ b/backend/src/server/routes/v1/secret-import-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { SECRET_IMPORTS } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -19,12 +20,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => } ], body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(SECRET_IMPORTS.CREATE.workspaceId), + environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.path), import: z.object({ - environment: z.string().trim(), - path: z.string().trim().transform(removeTrailingSlash) + environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.import.environment), + path: z.string().trim().transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.import.path) }) }), response: { @@ -80,20 +81,21 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => } ], params: z.object({ - secretImportId: z.string().trim() + secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.workspaceId), + environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path), import: z.object({ - environment: z.string().trim().optional(), + environment: z.string().trim().optional().describe(SECRET_IMPORTS.UPDATE.import.environment), path: z .string() .trim() .optional() - .transform((val) => (val ? removeTrailingSlash(val) : val)), - position: z.number().optional() + .transform((val) => (val ? removeTrailingSlash(val) : val)) + .describe(SECRET_IMPORTS.UPDATE.import.path), + position: z.number().optional().describe(SECRET_IMPORTS.UPDATE.import.position) }) }), response: { @@ -150,12 +152,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => } ], params: z.object({ - secretImportId: z.string().trim() + secretImportId: z.string().trim().describe(SECRET_IMPORTS.DELETE.secretImportId) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash) + workspaceId: z.string().trim().describe(SECRET_IMPORTS.DELETE.workspaceId), + environment: z.string().trim().describe(SECRET_IMPORTS.DELETE.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.DELETE.path) }), response: { 200: z.object({ @@ -210,9 +212,9 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => } ], querystring: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - path: z.string().trim().default("/").transform(removeTrailingSlash) + workspaceId: z.string().trim().describe(SECRET_IMPORTS.LIST.workspaceId), + environment: z.string().trim().describe(SECRET_IMPORTS.LIST.environment), + path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.LIST.path) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v2/identity-org-router.ts b/backend/src/server/routes/v2/identity-org-router.ts index 1832e8962..97477b033 100644 --- a/backend/src/server/routes/v2/identity-org-router.ts +++ b/backend/src/server/routes/v2/identity-org-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas"; +import { ORGANIZATIONS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -18,7 +19,7 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - orgId: z.string().trim() + orgId: z.string().trim().describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.orgId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v2/identity-project-router.ts b/backend/src/server/routes/v2/identity-project-router.ts index 09e586839..67dccb5e3 100644 --- a/backend/src/server/routes/v2/identity-project-router.ts +++ b/backend/src/server/routes/v2/identity-project-router.ts @@ -7,6 +7,7 @@ import { ProjectMembershipRole, ProjectUserMembershipRolesSchema } from "@app/db/schemas"; +import { PROJECTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types"; @@ -55,8 +56,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) } ], params: z.object({ - projectId: z.string().trim(), - identityId: z.string().trim() + projectId: z.string().trim().describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.projectId), + identityId: z.string().trim().describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.identityId) }), body: z.object({ roles: z @@ -76,6 +77,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) ]) ) .min(1) + .describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.roles) }), response: { 200: z.object({ @@ -108,8 +110,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) } ], params: z.object({ - projectId: z.string().trim(), - identityId: z.string().trim() + projectId: z.string().trim().describe(PROJECTS.DELETE_IDENTITY_MEMBERSHIP.projectId), + identityId: z.string().trim().describe(PROJECTS.DELETE_IDENTITY_MEMBERSHIP.identityId) }), response: { 200: z.object({ @@ -141,7 +143,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) } ], params: z.object({ - projectId: z.string().trim() + projectId: z.string().trim().describe(PROJECTS.LIST_IDENTITY_MEMBERSHIPS.projectId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v2/organization-router.ts b/backend/src/server/routes/v2/organization-router.ts index ba5ca3c21..7d5ba3da7 100644 --- a/backend/src/server/routes/v2/organization-router.ts +++ b/backend/src/server/routes/v2/organization-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { OrganizationsSchema, OrgMembershipsSchema, UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; +import { ORGANIZATIONS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; @@ -17,7 +18,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - organizationId: z.string().trim() + organizationId: z.string().trim().describe(ORGANIZATIONS.LIST_USER_MEMBERSHIPS.organizationId) }), response: { 200: z.object({ @@ -62,7 +63,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - organizationId: z.string().trim() + organizationId: z.string().trim().describe(ORGANIZATIONS.GET_PROJECTS.organizationId) }), response: { 200: z.object({ @@ -106,9 +107,12 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { apiKeyAuth: [] } ], - params: z.object({ organizationId: z.string().trim(), membershipId: z.string().trim() }), + params: z.object({ + organizationId: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.organizationId), + membershipId: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.membershipId) + }), body: z.object({ - role: z.string().trim() + role: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.role) }), response: { 200: z.object({ @@ -142,7 +146,10 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { apiKeyAuth: [] } ], - params: z.object({ organizationId: z.string().trim(), membershipId: z.string().trim() }), + params: z.object({ + organizationId: z.string().trim().describe(ORGANIZATIONS.DELETE_USER_MEMBERSHIP.organizationId), + membershipId: z.string().trim().describe(ORGANIZATIONS.DELETE_USER_MEMBERSHIP.membershipId) + }), response: { 200: z.object({ membership: OrgMembershipsSchema diff --git a/backend/src/server/routes/v2/project-membership-router.ts b/backend/src/server/routes/v2/project-membership-router.ts index f63770346..6f81f8392 100644 --- a/backend/src/server/routes/v2/project-membership-router.ts +++ b/backend/src/server/routes/v2/project-membership-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { ProjectMembershipsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { PROJECTS } from "@app/lib/api-docs"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -11,11 +12,11 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider url: "/:projectId/memberships", schema: { params: z.object({ - projectId: z.string().describe("The ID of the project.") + projectId: z.string().describe(PROJECTS.INVITE_MEMBER.projectId) }), body: z.object({ - emails: z.string().email().array().default([]).describe("Emails of the users to add to the project."), - usernames: z.string().array().default([]).describe("Usernames of the users to add to the project.") + emails: z.string().email().array().default([]).describe(PROJECTS.INVITE_MEMBER.emails), + usernames: z.string().array().default([]).describe(PROJECTS.INVITE_MEMBER.usernames) }), response: { 200: z.object({ @@ -55,12 +56,12 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider url: "/:projectId/memberships", schema: { params: z.object({ - projectId: z.string().describe("The ID of the project.") + projectId: z.string().describe(PROJECTS.REMOVE_MEMBER.projectId) }), body: z.object({ - emails: z.string().email().array().default([]).describe("Emails of the users to remove from the project."), - usernames: z.string().array().default([]).describe("Usernames of the users to remove from the project.") + emails: z.string().email().array().default([]).describe(PROJECTS.REMOVE_MEMBER.emails), + usernames: z.string().array().default([]).describe(PROJECTS.REMOVE_MEMBER.usernames) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts index fe1254b2b..208edba7b 100644 --- a/backend/src/server/routes/v2/project-router.ts +++ b/backend/src/server/routes/v2/project-router.ts @@ -3,6 +3,7 @@ import { z } from "zod"; import { ProjectKeysSchema, ProjectsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { PROJECTS } from "@app/lib/api-docs"; import { authRateLimit } from "@app/server/config/rateLimiter"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -29,7 +30,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - workspaceId: z.string().trim() + workspaceId: z.string().trim().describe(PROJECTS.GET_KEY.workspaceId) }), response: { 200: ProjectKeysSchema.merge( @@ -127,7 +128,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { }, schema: { body: z.object({ - projectName: z.string().trim(), + projectName: z.string().trim().describe(PROJECTS.CREATE.projectName), slug: z .string() .min(5) @@ -135,8 +136,9 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { .refine((v) => slugify(v) === v, { message: "Slug must be a valid slug" }) - .optional(), - organizationId: z.string().trim() + .optional() + .describe(PROJECTS.CREATE.slug), + organizationId: z.string().trim().describe(PROJECTS.CREATE.organizationId) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 6b3dd6041..65219d0ab 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -10,6 +10,7 @@ import { } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { CommitType } from "@app/ee/services/secret-approval-request/secret-approval-request-types"; +import { RAW_SECRETS } from "@app/lib/api-docs"; import { BadRequestError } from "@app/lib/errors"; import { removeTrailingSlash } from "@app/lib/fn"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -33,13 +34,14 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } ], querystring: z.object({ - workspaceId: z.string().trim().optional(), - environment: z.string().trim().optional(), - secretPath: z.string().trim().default("/").transform(removeTrailingSlash), + workspaceId: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceId), + environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment), + secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath), include_imports: z .enum(["true", "false"]) .default("false") .transform((value) => value === "true") + .describe(RAW_SECRETS.LIST.includeImports) }), response: { 200: z.object({ @@ -123,18 +125,19 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - secretName: z.string().trim() + secretName: z.string().trim().describe(RAW_SECRETS.GET.secretName) }), querystring: z.object({ - workspaceId: z.string().trim().optional(), - environment: z.string().trim().optional(), - secretPath: z.string().trim().default("/").transform(removeTrailingSlash), - version: z.coerce.number().optional(), - type: z.nativeEnum(SecretType).default(SecretType.Shared), + workspaceId: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceId), + environment: z.string().trim().optional().describe(RAW_SECRETS.GET.environment), + secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.GET.secretPath), + version: z.coerce.number().optional().describe(RAW_SECRETS.GET.version), + type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.GET.type), include_imports: z .enum(["true", "false"]) .default("false") .transform((value) => value === "true") + .describe(RAW_SECRETS.GET.includeImports) }), response: { 200: z.object({ @@ -213,16 +216,24 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - secretName: z.string().trim() + secretName: z.string().trim().describe(RAW_SECRETS.CREATE.secretName) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - secretPath: z.string().trim().default("/").transform(removeTrailingSlash), - secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), - secretComment: z.string().trim().optional().default(""), - skipMultilineEncoding: z.boolean().optional(), - type: z.nativeEnum(SecretType).default(SecretType.Shared) + workspaceId: z.string().trim().describe(RAW_SECRETS.CREATE.workspaceId), + environment: z.string().trim().describe(RAW_SECRETS.CREATE.environment), + secretPath: z + .string() + .trim() + .default("/") + .transform(removeTrailingSlash) + .describe(RAW_SECRETS.CREATE.secretPath), + secretValue: z + .string() + .transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())) + .describe(RAW_SECRETS.CREATE.secretValue), + secretComment: z.string().trim().optional().default("").describe(RAW_SECRETS.CREATE.secretComment), + skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding), + type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.CREATE.type) }), response: { 200: z.object({ @@ -290,15 +301,23 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - secretName: z.string().trim() + secretName: z.string().trim().describe(RAW_SECRETS.UPDATE.secretName) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), - secretPath: z.string().trim().default("/").transform(removeTrailingSlash), - skipMultilineEncoding: z.boolean().optional(), - type: z.nativeEnum(SecretType).default(SecretType.Shared) + workspaceId: z.string().trim().describe(RAW_SECRETS.UPDATE.workspaceId), + environment: z.string().trim().describe(RAW_SECRETS.UPDATE.environment), + secretValue: z + .string() + .transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())) + .describe(RAW_SECRETS.UPDATE.secretValue), + secretPath: z + .string() + .trim() + .default("/") + .transform(removeTrailingSlash) + .describe(RAW_SECRETS.UPDATE.secretPath), + skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.UPDATE.skipMultilineEncoding), + type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.UPDATE.type) }), response: { 200: z.object({ @@ -364,13 +383,18 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } ], params: z.object({ - secretName: z.string().trim() + secretName: z.string().trim().describe(RAW_SECRETS.DELETE.secretName) }), body: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), - secretPath: z.string().trim().default("/").transform(removeTrailingSlash), - type: z.nativeEnum(SecretType).default(SecretType.Shared) + workspaceId: z.string().trim().describe(RAW_SECRETS.DELETE.workspaceId), + environment: z.string().trim().describe(RAW_SECRETS.DELETE.environment), + secretPath: z + .string() + .trim() + .default("/") + .transform(removeTrailingSlash) + .describe(RAW_SECRETS.DELETE.secretPath), + type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.DELETE.type) }), response: { 200: z.object({