import { cO as getPreviousJwtSecrets, aQ as useRuntimeConfig, f as defineAdminEventHandler, h as requireAdminRole, cP as ensurePluginRuntimePrepared, _ as getAuditLogs, cQ as getPluginTrustSummary } from '../../../../nitro/nitro.mjs';
import { createHash } from 'node:crypto';
import 'jsonwebtoken';
import 'node:fs';
import 'node:module';
import 'node:path';
import 'node:url';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'pino';
import 'drizzle-orm/better-sqlite3';
import 'drizzle-orm/node-postgres';
import 'drizzle-orm/mysql2';
import 'better-sqlite3';
import 'pg';
import 'mysql2/promise';
import 'drizzle-orm';
import 'fs';
import 'path';
import 'prom-client';
import 'bcryptjs';
import '@node-rs/argon2';
import 'node:async_hooks';
import 'crypto';
import 'node:dns';
import 'node:util';
import 'node:net';
import 'fs/promises';
import 'url';
import 'semver';

function computeFingerprint(value) {
  if (!value || value.trim() === "") {
    return null;
  }
  return createHash("sha256").update(value).digest("hex").slice(0, 12);
}
function isProductionMode() {
  return true;
}
function readEnvSecret(envKey) {
  const value = process.env[envKey];
  return typeof value === "string" && value.trim().length > 0 ? value : null;
}
function readRuntimeJwtSecret() {
  var _a;
  try {
    if (typeof useRuntimeConfig !== "function") {
      return null;
    }
    const runtimeConfig = useRuntimeConfig();
    const secret = (_a = runtimeConfig.jwt) == null ? void 0 : _a.secret;
    return typeof secret === "string" && secret.trim().length > 0 ? secret : null;
  } catch {
    return null;
  }
}
function resolveJwtSecret() {
  const envValue = readEnvSecret("JWT_SECRET");
  if (envValue) {
    return { value: envValue, source: "env" };
  }
  const runtimeValue = readRuntimeJwtSecret();
  if (runtimeValue) {
    return { value: runtimeValue, source: "runtime" };
  }
  return { value: null, source: "missing" };
}
function hasPreviousList(envKey) {
  return typeof process.env[`${envKey}_PREVIOUS_LIST`] === "string";
}
function describeJwtKey() {
  const resolved = resolveJwtSecret();
  const configured = resolved.value !== null;
  const previousKeys = getPreviousJwtSecrets("JWT_SECRET");
  const notes = [];
  if (!configured) {
    notes.push(
      "JWT_SECRET is not set in env/runtime config; authentication tokens cannot be signed."
    );
  }
  if (configured && resolved.value && resolved.value.length < 32) {
    notes.push("JWT_SECRET value is shorter than 32 characters \u2014 consider rotating.");
  }
  if (resolved.source === "runtime") {
    notes.push("JWT_SECRET is provided by runtime config, not process.env.");
  }
  if (previousKeys.length === 0) {
    notes.push(
      "No previous keys configured (JWT_SECRET_PREVIOUS / _LIST). Set them during rotation to keep existing tokens valid."
    );
  }
  return {
    envKey: "JWT_SECRET",
    configured,
    source: resolved.source,
    fingerprint: computeFingerprint(resolved.value),
    previousKeyCount: previousKeys.length,
    hasPreviousList: hasPreviousList("JWT_SECRET"),
    notes
  };
}
function describeAdminJwtKey() {
  const adminEnv = readEnvSecret("ADMIN_JWT_SECRET");
  const jwtFallback = resolveJwtSecret();
  const currentValue = adminEnv != null ? adminEnv : jwtFallback.value;
  const previousKeys = adminEnv ? getPreviousJwtSecrets("ADMIN_JWT_SECRET") : [...getPreviousJwtSecrets("ADMIN_JWT_SECRET"), ...getPreviousJwtSecrets("JWT_SECRET")];
  const notes = [];
  if (!adminEnv && !jwtFallback.value) {
    notes.push(
      "ADMIN_JWT_SECRET is not set and there is no JWT_SECRET/runtime fallback. Admin auth will fail."
    );
  } else if (!adminEnv && jwtFallback.value) {
    notes.push(
      "ADMIN_JWT_SECRET is missing \u2014 falling back to JWT_SECRET. Set a dedicated admin secret for stronger isolation."
    );
  }
  if (adminEnv && adminEnv.length < 32) {
    notes.push("ADMIN_JWT_SECRET is shorter than 32 characters \u2014 consider rotating.");
  }
  if (previousKeys.length === 0) {
    notes.push(
      "No previous admin keys configured (ADMIN_JWT_SECRET_PREVIOUS / _LIST). Set them during rotation."
    );
  }
  return {
    envKey: "ADMIN_JWT_SECRET",
    configured: Boolean(adminEnv),
    source: adminEnv ? "env" : jwtFallback.value ? "derived" : "missing",
    fingerprint: computeFingerprint(currentValue),
    previousKeyCount: previousKeys.length,
    hasPreviousList: hasPreviousList("ADMIN_JWT_SECRET") || !adminEnv && hasPreviousList("JWT_SECRET"),
    notes
  };
}
function describePasswordResetKey() {
  const explicit = readEnvSecret("PASSWORD_RESET_SECRET");
  const jwtFallback = resolveJwtSecret();
  const currentValue = explicit != null ? explicit : jwtFallback.value ? `${jwtFallback.value}:password-reset` : null;
  const previousKeys = explicit ? getPreviousJwtSecrets("PASSWORD_RESET_SECRET") : [
    ...getPreviousJwtSecrets("PASSWORD_RESET_SECRET"),
    ...getPreviousJwtSecrets("JWT_SECRET").map((secret) => `${secret}:password-reset`)
  ];
  const notes = [];
  if (!explicit && !jwtFallback.value) {
    notes.push(
      "PASSWORD_RESET_SECRET is missing and JWT_SECRET fallback is not set \u2014 password reset flow disabled."
    );
  } else if (!explicit) {
    notes.push(
      "PASSWORD_RESET_SECRET is missing \u2014 derived from JWT_SECRET:password-reset. Set a dedicated secret for stronger isolation."
    );
  }
  if (previousKeys.length === 0) {
    notes.push(
      explicit ? "No previous password reset keys configured (PASSWORD_RESET_SECRET_PREVIOUS / _LIST). Set them during rotation." : "No previous password reset/JWT keys configured (PASSWORD_RESET_SECRET_PREVIOUS / JWT_SECRET_PREVIOUS / _LIST). Set them during rotation."
    );
  }
  return {
    envKey: "PASSWORD_RESET_SECRET",
    configured: Boolean(explicit),
    source: explicit ? "env" : jwtFallback.value ? "derived" : "missing",
    fingerprint: computeFingerprint(currentValue),
    previousKeyCount: previousKeys.length,
    hasPreviousList: hasPreviousList("PASSWORD_RESET_SECRET") || !explicit && hasPreviousList("JWT_SECRET"),
    notes
  };
}
function describeSsrfPosture() {
  const productionMode = isProductionMode();
  return {
    productionMode,
    allowPrivateByDefault: !productionMode,
    allowedProtocolsByDefault: ["https:"] 
  };
}
function describeSecretsPosture() {
  const mfaExplicit = typeof process.env.MFA_ENCRYPTION_KEY === "string" && process.env.MFA_ENCRYPTION_KEY.trim().length > 0;
  const mfaFallback = typeof process.env.ADMIN_JWT_SECRET === "string" || typeof process.env.JWT_SECRET === "string";
  const mfaNotes = [];
  if (!mfaExplicit && mfaFallback) {
    mfaNotes.push(
      "MFA_ENCRYPTION_KEY is not set \u2014 TOTP secrets encrypted with admin/JWT secret fallback. Set a dedicated key in production."
    );
  } else if (!mfaExplicit && !mfaFallback) {
    mfaNotes.push(
      "MFA encryption is unavailable: no MFA_ENCRYPTION_KEY/ADMIN_JWT_SECRET/JWT_SECRET configured."
    );
  }
  const metricsTokenConfigured = typeof process.env.METRICS_TOKEN === "string" && process.env.METRICS_TOKEN.trim().length > 0;
  const metricsPublic = process.env.METRICS_PUBLIC === "true";
  const metricsNotes = [];
  if (!metricsTokenConfigured && !metricsPublic) {
    metricsNotes.push(
      "Metrics endpoint is private but no METRICS_TOKEN configured \u2014 admin auth required."
    );
  }
  if (metricsPublic) {
    metricsNotes.push(
      "Metrics endpoint exposed publicly (METRICS_PUBLIC=true). Limit access at network level."
    );
  }
  const cronConfigured = typeof process.env.CRON_SECRET === "string" && process.env.CRON_SECRET.trim().length > 0;
  const cronNotes = [];
  if (!cronConfigured) {
    cronNotes.push("CRON_SECRET is not set \u2014 scheduled job triggers cannot be authenticated.");
  }
  return {
    mfaEncryptionKey: {
      configured: mfaExplicit,
      source: mfaExplicit ? "env" : mfaFallback ? "fallback" : "missing",
      notes: mfaNotes
    },
    metricsToken: {
      configured: metricsTokenConfigured,
      notes: metricsNotes
    },
    cronSecret: {
      configured: cronConfigured,
      notes: cronNotes
    }
  };
}
function getSecurityPostureSnapshot() {
  return {
    generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
    environment: "production",
    signingKeys: {
      jwt: describeJwtKey(),
      adminJwt: describeAdminJwtKey(),
      passwordReset: describePasswordResetKey()
    },
    ssrf: describeSsrfPosture(),
    secrets: describeSecretsPosture()
  };
}

const TRUST_VIOLATION_ACTIONS = ["plugin.blocked", "plugin.trust_failed"];
const posture_get = defineAdminEventHandler("admin:security:posture:get", async (event) => {
  await requireAdminRole(event, ["super-admin"]);
  await ensurePluginRuntimePrepared().catch(() => null);
  const pluginTrust = getPluginTrustSummary();
  const posture = getSecurityPostureSnapshot();
  const auditLogs = await getAuditLogs({ action: TRUST_VIOLATION_ACTIONS }, 20, 0).catch(() => ({
    data: [],
    total: 0
  }));
  const data = {
    posture,
    pluginTrust,
    recentViolations: auditLogs.data
  };
  return { success: true, data };
});

export { posture_get as default };
//# sourceMappingURL=posture.get.mjs.map
