Registers AppGate as a checkConfigOnly integration-health row and public sync route, matching the existing factory + is<Name>Configured() pattern. Committed now so Phase 13's worktree-isolated executors fork from a HEAD that includes this integration-health.ts entry, since Plan 13-02 inserts the PAX8 row immediately after it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHRgZqkzBHBbAbc3KHneuR
33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
/**
|
|
* GET /api/appgate/health
|
|
* Live AppGate Controller probe — used by the Integration Health dashboard
|
|
* and the admin/integrations page. Does a cheap unauthenticated reach test
|
|
* (identity-providers/names) plus a credential check (login).
|
|
*/
|
|
|
|
import { NextResponse } from 'next/server';
|
|
import { requireAdmin } from '@/lib/auth-utils';
|
|
import { getAppgateClient, isAppgateConfigured } from '@/lib/services/appgate-factory';
|
|
|
|
export async function GET() {
|
|
const { error } = await requireAdmin();
|
|
if (error) return error;
|
|
|
|
if (!isAppgateConfigured()) {
|
|
return NextResponse.json({ configured: false, reachable: false, authenticated: false });
|
|
}
|
|
try {
|
|
const client = getAppgateClient();
|
|
await client.ping();
|
|
// Force a login by hitting an authenticated endpoint.
|
|
await client.getLicense();
|
|
return NextResponse.json({ configured: true, reachable: true, authenticated: true });
|
|
} catch (err) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
const reachable = !/unreachable|ENOTFOUND|ECONNREFUSED/i.test(msg);
|
|
return NextResponse.json(
|
|
{ configured: true, reachable, authenticated: false, error: msg },
|
|
{ status: 503 },
|
|
);
|
|
}
|
|
}
|