edtech / apps /api /src /middleware /tenant.ts
CognxSafeTrack
feat: agentic platform β€” text-to-sql, pedagogy advisor, security hardening & performance
5b8761d
import { FastifyRequest, FastifyReply } from 'fastify';
import { prisma } from '../services/prisma';
import { decryptSecrets } from '../services/organization';
export async function injectTenantConfig(request: FastifyRequest, reply: FastifyReply) {
const organizationId = request.organizationId;
if (!organizationId) {
return; // Some routes might not require it, guarded routes will check this later if needed
}
try {
const organization = await prisma.organization.findUnique({
where: { id: organizationId },
include: { phoneNumbers: true }
});
if (!organization) {
return reply.code(404).send({ error: 'Organization not found' });
}
// Reject requests from hard-stopped (suspended) organizations
if (organization.isHardStopped) {
// Super-admin API key calls always pass (needed for management)
const isInternalCall = request.headers['x-api-key'] === process.env.ADMIN_API_KEY;
if (!isInternalCall) {
return reply.code(402).send({ error: 'Service suspended β€” payment required', code: 'ORG_SUSPENDED' });
}
}
// Attach decrypted config to request
request.tenantConfig = decryptSecrets(organization);
} catch (err) {
request.log.error({ err, organizationId }, '[TENANT_MIDDLEWARE] Failed to resolve tenant config');
return reply.code(500).send({ error: 'Internal server error resolving organization' });
}
}