diff --git a/apps/api-server/src/middlewares/index.ts b/apps/api-server/src/middlewares/index.ts index 37e246a..50d6919 100644 --- a/apps/api-server/src/middlewares/index.ts +++ b/apps/api-server/src/middlewares/index.ts @@ -4,6 +4,5 @@ export { authMiddleware } from "./auth.js"; export { loginRequestMiddleware } from "./login-request.js"; -export { orgMemberMiddleware } from "./org-member.js"; export { os } from "./os.js"; export { superuserMiddleware } from "./superuser.js"; diff --git a/apps/api-server/src/middlewares/org-member.ts b/apps/api-server/src/middlewares/org-member.ts deleted file mode 100644 index d5b0b9c..0000000 --- a/apps/api-server/src/middlewares/org-member.ts +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Org member middleware - authenticates and verifies org membership - * - * This middleware chains authMiddleware first, then looks up the org - * and verifies the user is a member. Adds org and membership to context. - * - * Input must include `slug` (the org slug). - */ - -import type { - AuthenticatedContext, - OrgInfo, - OrgMembership, -} from "../context.js"; -import { ORPCError } from "@orpc/server"; -import { authMiddleware } from "./auth.js"; -import { os } from "./os.js"; - -interface OrgSlugInput { - slug: string; -} - -const orgMemberCheck = os.middleware( - async ( - { - context, - next, - }: { - context: AuthenticatedContext; - next: (opts: { - context: { org: OrgInfo; membership: OrgMembership }; - }) => Promise; - }, - input: OrgSlugInput, - ) => { - const { db } = context; - const { slug } = input; - - // Look up org by slug - const org = await db - .selectFrom("orgs") - .select(["id", "slug", "display_name", "logo_url", "created_at"]) - .where("slug", "=", slug) - .executeTakeFirst(); - - if (!org) { - throw new ORPCError("NOT_FOUND", { message: "Organization not found" }); - } - - // Check user membership - const membership = await db - .selectFrom("org_members") - .select(["id", "role", "created_at"]) - .where("org_id", "=", org.id) - .where("user_id", "=", context.user.id) - .executeTakeFirst(); - - if (!membership) { - throw new ORPCError("FORBIDDEN", { - message: "You are not a member of this organization", - }); - } - - const orgInfo: OrgInfo = { - id: org.id, - slug: org.slug, - displayName: org.display_name, - logoUrl: org.logo_url, - createdAt: org.created_at, - }; - - const membershipInfo: OrgMembership = { - id: membership.id, - role: membership.role, - createdAt: membership.created_at, - }; - - return next({ - context: { - org: orgInfo, - membership: membershipInfo, - }, - }); - }, -); - -export const orgMemberMiddleware = authMiddleware.concat(orgMemberCheck); diff --git a/apps/api-server/src/middlewares/superuser.ts b/apps/api-server/src/middlewares/superuser.ts index c900549..e902ed0 100644 --- a/apps/api-server/src/middlewares/superuser.ts +++ b/apps/api-server/src/middlewares/superuser.ts @@ -4,19 +4,11 @@ * This middleware chains authMiddleware first, then checks for superuser. */ -import type { AuthenticatedContext } from "../context.js"; import { ORPCError } from "@orpc/server"; import { authMiddleware } from "./auth.js"; -import { os } from "./os.js"; -const superuserCheck = os.middleware( - async ({ - context, - next, - }: { - context: AuthenticatedContext; - next: () => Promise; - }) => { +export const superuserMiddleware = authMiddleware.concat( + async ({ context, next }) => { if (!context.user.isSuperuser) { throw new ORPCError("FORBIDDEN", { message: "Superuser access required", @@ -25,5 +17,3 @@ const superuserCheck = os.middleware( return next(); }, ); - -export const superuserMiddleware = authMiddleware.concat(superuserCheck); diff --git a/apps/api-server/src/procedures/base.ts b/apps/api-server/src/procedures/base.ts index 77b7bd5..4e0c68c 100644 --- a/apps/api-server/src/procedures/base.ts +++ b/apps/api-server/src/procedures/base.ts @@ -9,35 +9,21 @@ import type { APIContext, AuthenticatedContext, LoginRequestContext, - OrgMemberContext, } from "../context.js"; import { authMiddleware, loginRequestMiddleware, - orgMemberMiddleware, os, superuserMiddleware, } from "../middlewares/index.js"; // Re-export middlewares and os -export { - authMiddleware, - loginRequestMiddleware, - orgMemberMiddleware, - os, - superuserMiddleware, -}; +export { authMiddleware, loginRequestMiddleware, os, superuserMiddleware }; // Pre-configured procedures with middleware applied export const authedProcedure = os.use(authMiddleware); export const superuserProcedure = os.use(superuserMiddleware); export const loginRequestProcedure = os.use(loginRequestMiddleware); -export const orgMemberProcedure = os.use(orgMemberMiddleware); // Type exports for use in procedure files -export type { - APIContext, - AuthenticatedContext, - LoginRequestContext, - OrgMemberContext, -}; +export type { APIContext, AuthenticatedContext, LoginRequestContext }; diff --git a/apps/api-server/src/procedures/orgs/helpers.ts b/apps/api-server/src/procedures/orgs/helpers.ts index 3816d74..8d29b65 100644 --- a/apps/api-server/src/procedures/orgs/helpers.ts +++ b/apps/api-server/src/procedures/orgs/helpers.ts @@ -3,27 +3,13 @@ * Provides org lookup, membership verification, and role checks */ +import type { OrgInfo, OrgMembership } from "../../context.js"; import type { DB, OrgRole } from "@reviq/db-schema"; import type { Kysely } from "kysely"; import { ORPCError } from "@orpc/server"; -// ===== Types ===== - -/** Org info returned from lookup */ -export interface OrgInfo { - id: number; - slug: string; - displayName: string; - logoUrl: string | null; - createdAt: Date; -} - -/** User's membership in an org */ -export interface OrgMembership { - id: number; - role: OrgRole; - createdAt: Date; -} +// Re-export types for convenience +export type { OrgInfo, OrgMembership }; // ===== Role Hierarchy =====