Repository: Infisical/infisical
File: backend/src/server/routes/v1/organization-router.ts (TypeScript)

Code before:
import { ApiDocsTags, AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
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";

import { integrationAuthPubSchema } from "../sanitizedSchemas";

export const registerOrgRouter = async (server: FastifyZodProvider) => {
  server.route({
    method: "GET",
    url: "/",
    config: {
      rateLimit: readLimit
    },
    schema: {
      response: {
        200: z.union([
          z.object({
            id: z.string(),
            name: z.string(),
            slug: z.string(),
            role: z.string()
          }),
          z.object({
            organizations: sanitizedOrganizationSchema
              .extend({
                orgAuthMethod: z.string(),
                userRole: z.string()
              })
              .array()
          })
        ])
      }
    },
    onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN], { requireOrg: false }),
    handler: async (req) => {
      if (req.permission.type === ActorType.IDENTITY) {
        const organization = await server.services.org.findIdentityOrganization(req.permission.id);
        return organization;
      }
      const organizations = await server.services.org.findAllOrganizationOfUser(req.permission.id);
      return { organizations };
    }
  });

  server.route({
    method: "GET",
    url: "/:organizationId",

Review comment (security):
why do we return a completely different schema for identities? 

Can we unify it to use `sanitizedOrganizationSchema` without the `.extend` section? It might be better if always just returns an array so that it's predictable

Code after:
import { ApiDocsTags, AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
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";

import { integrationAuthPubSchema } from "../sanitizedSchemas";

export const registerOrgRouter = async (server: FastifyZodProvider) => {
  server.route({
    method: "GET",
    url: "/",
    config: {
      rateLimit: readLimit
    },
    schema: {
      response: {
        200: z.object({
          organizations: sanitizedOrganizationSchema
            .extend({
              orgAuthMethod: z.string(),
              userRole: z.string()
            })
            .array()
        })
      }
    },
    onRequest: verifyAuth([AuthMode.JWT], { requireOrg: false }),
    handler: async (req) => {
      const organizations = await server.services.org.findAllOrganizationOfUser(req.permission.id);
      return { organizations };
    }
  });

  server.route({
    method: "GET",
    url: "/:organizationId",
    config: {
      rateLimit: readLimit
    },
    schema: {
      params: z.object({
        organizationId: z.string().trim()
      }),
      response: {
        200: z.object({
          organization: sanitizedOrganizationSchema
        })
      }