Simplify middleware and remove unused code
- Remove unused orgMemberMiddleware (org procedures use helper functions) - Remove orgMemberProcedure from base.ts - Simplify superuserMiddleware using inline concat syntax - Import OrgInfo/OrgMembership from context.ts instead of redefining Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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<unknown>;
|
||||
},
|
||||
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);
|
||||
@@ -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<unknown>;
|
||||
}) => {
|
||||
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);
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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 =====
|
||||
|
||||
|
||||
Reference in New Issue
Block a user