import { d as defineEventHandler, aG as requireFeature, $ as getAuthRequestContext, c as createError, q as readBody, aH as consumeLoginState, aI as findSsoProviderById, aR as findSsoProviderBySlug, aS as validateSamlResponse, aN as resolveSsoLogin, a3 as tryGetTenantContext, a4 as getDefaultTenantId, a5 as isMfaEnabledGlobally, a6 as getAdminMfaState, a7 as isMfaRequiredForRole, a8 as issueMfaChallenge, a2 as emitAdminLoginFailed, aP as sendRedirect, aa as generateAdminJWTForTenant, ab as emitAdminAfterLogin } from '../../../../../../nitro/nitro.mjs';
import { g as getServerBaseUrl, b as buildSsoCallbackUrl } from '../../../../../../_/url-helpers.mjs';
import '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 buildSpaRedirect(base, token, redirectAfter) {
  const params = new URLSearchParams({ token });
  if (redirectAfter) {
    params.set("redirect", redirectAfter);
  }
  return `${base}/admin/sso/callback#${params.toString()}`;
}
function buildSpaMfaRedirect(base, challengeToken, purpose, redirectAfter) {
  const params = new URLSearchParams({ challenge: challengeToken, purpose });
  if (redirectAfter) {
    params.set("redirect", redirectAfter);
  }
  return `${base}/admin/sso/callback#${params.toString()}`;
}
function buildSpaErrorRedirect(base, message) {
  const params = new URLSearchParams({ error: message });
  return `${base}/admin/login?${params.toString()}`;
}
const callback_post = defineEventHandler(async (event) => {
  var _a, _b;
  await requireFeature("enterprise.sso", event);
  const slug = (_a = event.context.params) == null ? void 0 : _a.slug;
  const reqCtx = getAuthRequestContext(event);
  const baseUrl = getServerBaseUrl(event);
  if (!slug || typeof slug !== "string") {
    throw createError({
      statusCode: 400,
      statusMessage: "Bad Request",
      message: "Provider slug is required"
    });
  }
  try {
    const body = await readBody(event);
    const samlResponse = typeof (body == null ? void 0 : body.SAMLResponse) === "string" ? body.SAMLResponse : null;
    const relayState = typeof (body == null ? void 0 : body.RelayState) === "string" ? body.RelayState : null;
    if (!samlResponse) {
      throw new Error("Missing SAMLResponse in callback body");
    }
    if (!relayState) {
      throw new Error("Missing RelayState \u2014 possible CSRF or stale session");
    }
    const loginState = await consumeLoginState(relayState);
    if (!loginState) {
      throw new Error("Login state expired or invalid (possible CSRF)");
    }
    let provider = await findSsoProviderById(loginState.providerId);
    if (!provider) {
      provider = await findSsoProviderBySlug(slug);
    }
    if (!provider || !provider.isEnabled) {
      throw new Error("SSO provider not found or disabled");
    }
    if (provider.slug !== slug) {
      throw new Error("Provider slug mismatch");
    }
    if (provider.type !== "saml") {
      throw new Error("Provider is not configured for SAML");
    }
    const callbackUrl = buildSsoCallbackUrl(event, provider.slug);
    const validated = await validateSamlResponse({
      config: provider.config,
      callbackUrl,
      samlResponse,
      relayState
    });
    const result = await resolveSsoLogin(provider, validated.profile);
    const tenant = tryGetTenantContext(event);
    const tenantId = (_b = tenant == null ? void 0 : tenant.id) != null ? _b : await getDefaultTenantId();
    const mfaEnabled = isMfaEnabledGlobally();
    const mfaState = mfaEnabled ? await getAdminMfaState(result.user.id) : null;
    const mfaRequired = mfaEnabled && isMfaRequiredForRole(result.user.role);
    if (mfaEnabled && ((mfaState == null ? void 0 : mfaState.enabled) || mfaRequired)) {
      const purpose = (mfaState == null ? void 0 : mfaState.enabled) ? "login" : "enroll";
      const challengeToken = issueMfaChallenge({
        sub: result.user.id,
        username: result.user.username,
        email: result.user.email,
        role: result.user.role,
        tid: tenantId,
        purpose,
        baseAmr: ["sso"]
      });
      await emitAdminLoginFailed(result.user.email, "mfa_required", reqCtx);
      return sendRedirect(
        event,
        buildSpaMfaRedirect(baseUrl, challengeToken, purpose, loginState.redirectAfter),
        302
      );
    }
    const adminToken = generateAdminJWTForTenant(
      {
        id: result.user.id,
        username: result.user.username,
        email: result.user.email,
        role: result.user.role
      },
      tenantId
    );
    await emitAdminAfterLogin(
      result.user.id,
      result.user.email,
      result.user.username,
      result.user.role,
      reqCtx
    );
    return sendRedirect(
      event,
      buildSpaRedirect(baseUrl, adminToken, loginState.redirectAfter),
      302
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : "SAML callback failed";
    console.error(`[POST /api/admin/auth/sso/${slug}/callback] Error:`, message);
    await emitAdminLoginFailed(`saml:${slug}`, "sso_error", reqCtx);
    return sendRedirect(event, buildSpaErrorRedirect(baseUrl, message), 302);
  }
});

export { callback_post as default };
//# sourceMappingURL=callback.post.mjs.map
