/**
 * authz-mutation-roles smoke — asserts that sensitive MUTATING routes actually
 * gate by ROLE, not merely by "is there a session".
 *
 * Why (2026-05-30): audit3-withauth-coverage proves every route has *some*
 * auth posture, but NOT that mutations are role-gated — so a VIEWER-writable
 * settings route passed it clean. An external assessment found four real
 * privilege-escalation holes behind exactly that gap:
 *   - /api/settings POST       (VIEWER could repoint SMTP / swap bot token)
 *   - /api/countries P/P/D     (VIEWER could reroute country alert emails)
 *   - /api/monitors/import POST (VIEWER could bulk-create monitors)
 *   - /api/notifications/test  (VIEWER could drive arbitrary SMTP connects)
 *   - /api/webhooks/telegram   (fully unauthenticated → alert-routing takeover)
 * This smoke statically guards each fix so the holes can't silently reopen.
 */
import './_lib';
import { ok, fail } from './_lib';
import { readFileSync } from 'fs';
import path from 'path';

const ROOT = path.resolve(__dirname, '../..');
const read = (rel: string): string => readFileSync(path.join(ROOT, rel), 'utf8');

/** A route enforces a role when it rejects on a role NOT in an allowed set. */
const ADMIN_GATE = /role[\s\S]{0,40}!==\s*['"]ADMIN['"]|!\s*\[\s*['"]ADMIN['"]/;
const ADMIN_EDITOR_GATE = /\[\s*['"]ADMIN['"]\s*,\s*['"]EDITOR['"]\s*\]\.includes/;

function assert(label: string, cond: boolean, detail: string): void {
    if (!cond) fail(label, detail);
    ok(label);
}

function main(): void {
    const settings = read('src/app/api/settings/route.ts');
    assert('settings POST is ADMIN-gated', /export async function POST/.test(settings) && ADMIN_GATE.test(settings),
        '/api/settings POST no longer rejects non-ADMIN — a VIEWER could rewrite SMTP/bot-token.');
    // GET must also role-gate: it returns non-secret SMTP/notification config
    // (host, port, username, from-address, chat_id) that a VIEWER should not read.
    assert('settings GET is ADMIN-gated', /ADMIN_READ_ONLY['"]\s*\]\.includes/.test(settings),
        '/api/settings GET no longer restricts to ADMIN/ADMIN_READ_ONLY — non-secret config leaks to any authenticated user.');

    const countries = read('src/app/api/countries/route.ts');
    // All three mutations must role-gate; require at least 3 ADMIN rejections.
    const countryGates = (countries.match(/!==\s*['"]ADMIN['"]/g) ?? []).length;
    assert('countries POST/PUT/DELETE are ADMIN-gated', countryGates >= 3,
        `/api/countries has only ${countryGates} ADMIN gate(s); expected ≥3 (POST, PUT, DELETE).`);

    const importRoute = read('src/app/api/monitors/import/route.ts');
    assert('monitors/import POST is ADMIN/EDITOR-gated', ADMIN_EDITOR_GATE.test(importRoute),
        '/api/monitors/import POST no longer gates to ADMIN/EDITOR — a VIEWER could bulk-create monitors.');

    const notifTest = read('src/app/api/notifications/test/route.ts');
    assert('notifications/test POST is ADMIN/EDITOR-gated', ADMIN_EDITOR_GATE.test(notifTest),
        '/api/notifications/test no longer gates to ADMIN/EDITOR — a VIEWER could drive arbitrary SMTP connects.');

    const telegram = read('src/app/api/webhooks/telegram/route.ts');
    assert('telegram webhook verifies the secret-token header', /x-telegram-bot-api-secret-token/i.test(telegram),
        '/api/webhooks/telegram no longer checks X-Telegram-Bot-Api-Secret-Token — endpoint is unauthenticated.');
    assert('telegram webhook fails closed when secret unset', /TELEGRAM_WEBHOOK_SECRET/.test(telegram) && /timingSafeEqual/.test(telegram),
        'telegram secret check is not constant-time / does not reference TELEGRAM_WEBHOOK_SECRET.');

    // Webhook/bot secrets are masked + encrypted at rest, not returned cleartext.
    const secrets = read('src/lib/services/system-setting-secrets.ts');
    for (const key of ['telegram_bot_token', 'slack_webhook_url', 'discord_webhook_url']) {
        assert(`secret key registered: ${key}`, secrets.includes(`'${key}'`),
            `${key} is not in SECRET_SETTING_KEYS — it would leak cleartext via GET /api/settings.`);
    }

    ok('authz-mutation-roles', 'sensitive mutations are role-gated; telegram webhook authenticated; webhook secrets masked+encrypted');
}

main();
