import { beforeEach, describe, expect, it } from 'vitest';
import { handleActuateAPI } from '../../api/index.js';
import { initDB } from '../../db.js';
import { generateApiKey } from '../../security/api-key-enhanced.js';
/**
 * Regression test for the `/seo/summary` SSRF blocker. The link-health probe
 * issues outbound requests, so the endpoint must be gated to EDITOR+ (mirroring
 * `/seo/link-health`) rather than any authenticated user. The SSRF primitive
 * itself (private-IP blocking via `safeFetch`) is covered by
 * `__tests__/security/safe-fetch.test.ts`.
 */
const VALID_SECRET = 'a'.repeat(48);
async function makeKey(scopes) {
    const { key, keyHash, keyPrefix } = await generateApiKey({ prefix: 'act_sk', scopes });
    return {
        key,
        record: {
            id: 'apikey-1',
            keyHash,
            keyPrefix,
            userId: 'user-1',
            scopes,
            ipRestrictions: null,
            expiresAt: null,
            lastUsedAt: null,
            revokedAt: null,
        },
    };
}
function createMockDB(apiKey) {
    return {
        apiKey: {
            findMany: async () => [apiKey],
            findUnique: async ({ where }) => apiKey.keyHash === where.keyHash ? apiKey : null,
            update: async () => apiKey,
        },
        document: { findMany: async () => [], count: async () => 0, findFirst: async () => null },
        user: {},
        session: {},
        media: {},
    };
}
describe('GET /seo/summary access control', () => {
    beforeEach(() => {
        delete globalThis.__actuateConfig;
        delete process.env.NEXT_PUBLIC_SITE_URL;
        process.env.CMS_SECRET = VALID_SECRET;
    });
    it('rejects a non-privileged (non-admin) API key with 403', async () => {
        const { key, record } = await makeKey({ collections: ['pages'], actions: ['read'] });
        const db = createMockDB(record);
        initDB(db);
        const handler = handleActuateAPI({ prismaClient: db, config: { collections: {} } });
        const res = await handler(new Request('https://x.com/api/cms/seo/summary', {
            headers: { Authorization: `Bearer ${key}` },
        }));
        expect(res.status).toBe(403);
    });
    it('requires authentication', async () => {
        const { record } = await makeKey({ collections: ['pages'], actions: ['read'] });
        const db = createMockDB(record);
        initDB(db);
        const handler = handleActuateAPI({ prismaClient: db, config: { collections: {} } });
        const res = await handler(new Request('https://x.com/api/cms/seo/summary'));
        expect(res.status).toBe(401);
    });
    it('allows an admin key and does not probe external hosts when site URL is unset', async () => {
        const { key, record } = await makeKey({ admin: true });
        const db = createMockDB(record);
        initDB(db);
        const handler = handleActuateAPI({ prismaClient: db, config: { collections: {} } });
        const res = await handler(new Request('https://x.com/api/cms/seo/summary', {
            headers: { Authorization: `Bearer ${key}` },
        }));
        expect(res.status).toBe(200);
        const body = (await res.json());
        expect(body.data.issuesSummary.brokenInternalLinks).toBe(0);
    });
});
//# sourceMappingURL=seo-summary-ssrf.test.js.map