File size: 1,540 Bytes
6dd9bad
 
 
 
 
5b8761d
6dd9bad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a0c3ba
 
 
 
 
 
 
 
 
6dd9bad
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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' });
    }
}