everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
160 lines (158 loc) • 5.18 kB
JavaScript
import { ORPCError } from "@orpc/server";
//#region src/api/auth-middleware.ts
function createAuthMiddleware(builder, options) {
const requireAuth = builder.middleware(async ({ context, next }) => {
if (!context.user || !context.userId) throw new ORPCError("UNAUTHORIZED", {
message: "Authentication required",
data: { hint: "Sign in to continue" }
});
return next({ context: {
userId: context.userId,
user: context.user
} });
});
const requireAuthOrApiKey = builder.middleware(async ({ context, next }) => {
if (!context.user && !context.userId && !context.apiKey) throw new ORPCError("UNAUTHORIZED", {
message: "Authentication required",
data: { hint: "Sign in or provide an API key" }
});
return next({ context });
});
const requireRole = (...roles) => builder.middleware(async ({ context, next }) => {
if (!context.user || !context.userId) throw new ORPCError("UNAUTHORIZED", {
message: "Authentication required",
data: {
authType: "session",
hint: "Sign in to continue"
}
});
const currentRole = context.user.role;
if (!currentRole || !roles.includes(currentRole)) throw new ORPCError("FORBIDDEN", {
message: `Requires role: ${roles.join(" or ")}`,
data: {
requiredRoles: roles,
currentRole
}
});
return next({ context: {
userId: context.userId,
user: context.user
} });
});
const requireAdmin = requireRole("admin");
const requireOrganization = builder.middleware(async ({ context, next }) => {
if (!context.user || !context.userId) throw new ORPCError("UNAUTHORIZED", {
message: "Authentication required",
data: {
authType: "session",
hint: "Sign in to continue"
}
});
if (!context.organization?.activeOrganizationId) throw new ORPCError("FORBIDDEN", {
message: "Active organization required",
data: { hint: "Select or create an organization" }
});
const org = context.organization;
assertOrganizationApproval(org.organization);
return next({ context: {
userId: context.userId,
user: context.user,
organization: {
...org,
activeOrganizationId: org.activeOrganizationId,
organization: org.organization ? {
...org.organization,
metadata: parseOrgMetadata(org.organization.metadata, options?.orgMetaSchema)
} : null
}
} });
});
const requireOrgRole = (...roles) => builder.middleware(async ({ context, next }) => {
if (!context.user || !context.userId) throw new ORPCError("UNAUTHORIZED", {
message: "Authentication required",
data: {
authType: "session",
hint: "Sign in to continue"
}
});
if (!context.organization?.activeOrganizationId) throw new ORPCError("FORBIDDEN", {
message: "Active organization required",
data: { hint: "Select or create an organization" }
});
const member = context.organization?.member;
if (!member?.id || !member?.role || !roles.includes(member.role)) throw new ORPCError("FORBIDDEN", {
message: `Requires organization role: ${roles.join(" or ")}`,
data: {
requiredRoles: roles,
currentRole: member?.role ?? null
}
});
const org = context.organization;
assertOrganizationApproval(org.organization);
return next({ context: {
userId: context.userId,
user: context.user,
organization: {
...org,
activeOrganizationId: org.activeOrganizationId,
member: {
id: member.id,
role: member.role
},
organization: org.organization ? {
...org.organization,
metadata: parseOrgMetadata(org.organization.metadata, options?.orgMetaSchema)
} : null
}
} });
});
const requireApiKey = (requiredPermissions) => builder.middleware(async ({ context, next }) => {
if (!context.apiKey) throw new ORPCError("UNAUTHORIZED", {
message: "API key required",
data: {
authType: "apiKey",
hint: "Provide a valid API key via x-api-key header"
}
});
if (requiredPermissions) {
const keyPerms = context.apiKey.permissions ?? {};
for (const [resource, actions] of Object.entries(requiredPermissions)) {
const allowed = keyPerms[resource] ?? [];
const missing = actions.filter((a) => !allowed.includes(a));
if (missing.length > 0) throw new ORPCError("FORBIDDEN", {
message: `API key lacks permission: ${resource}:${missing.join(",")}`,
data: {
requiredPermissions,
keyPermissions: keyPerms
}
});
}
}
return next({ context: { apiKey: context.apiKey } });
});
return {
requireAuth,
requireAuthOrApiKey,
requireRole,
requireAdmin,
requireOrganization,
requireOrgRole,
requireApiKey
};
}
function assertOrganizationApproval(organization) {
if (organization?.status && organization.status !== "active") throw new ORPCError("FORBIDDEN", { message: "Organization requires platform-admin approval" });
}
function parseOrgMetadata(raw, schema) {
if (!raw) return null;
if (!schema) return raw;
const result = schema.safeParse(raw);
if (result.success) return result.data;
throw new ORPCError("INTERNAL_SERVER_ERROR", {
message: "Invalid organization metadata",
data: { errors: result.error.issues }
});
}
//#endregion
export { createAuthMiddleware };
//# sourceMappingURL=auth-middleware.mjs.map