import {
  TangleIdentityUnreachableError,
  createTangleIdentityClient
} from "./chunk-Q5X3QNHR.js";

// src/middleware/index.ts
async function requireTangleAuth(request, opts = {}) {
  const client = opts.client ?? createTangleIdentityClient(opts);
  const requireCredential = opts.requireCredential !== false;
  const token = extractToken(request, opts.sessionCookieName);
  if (!token) {
    if (!requireCredential) {
      return {
        ok: true,
        auth: {
          userId: "",
          workspaceId: "",
          scopes: [],
          kind: "session",
          ownerType: "user"
        }
      };
    }
    return { ok: false, status: 401, reason: "missing_credential" };
  }
  let result;
  try {
    result = await client.verifyToken(token);
  } catch (err) {
    if (err instanceof TangleIdentityUnreachableError) {
      return { ok: false, status: 503, reason: "platform_unreachable" };
    }
    throw err;
  }
  if (!result.valid) {
    const status = result.reason === "service_token_refused" ? 403 : 401;
    return { ok: false, status, reason: result.reason };
  }
  return {
    ok: true,
    auth: {
      userId: result.userId,
      workspaceId: result.workspaceId,
      scopes: result.scopes,
      kind: result.kind,
      ownerType: result.ownerType,
      ...result.expiresAt !== void 0 ? { expiresAt: result.expiresAt } : {},
      ...result.credentialId ? { credentialId: result.credentialId } : {},
      ...result.product ? { product: result.product } : {}
    }
  };
}
function extractToken(request, sessionCookieName = "better-auth.session_token") {
  const headers = request.headers;
  const authHeader = headerValue(headers, "authorization");
  if (authHeader && authHeader.startsWith("Bearer ")) {
    const candidate = authHeader.slice(7).trim();
    if (!candidate) return void 0;
    if (candidate.startsWith("svc_")) return void 0;
    return candidate;
  }
  const cookieHeader = headerValue(headers, "cookie");
  if (cookieHeader) {
    const token = readCookie(cookieHeader, sessionCookieName);
    if (token) return token;
  }
  return void 0;
}
function headerValue(headers, name) {
  if (typeof headers.get === "function") {
    return headers.get(name) ?? void 0;
  }
  const lookup = headers[name] ?? headers[name.toLowerCase()];
  if (Array.isArray(lookup)) return typeof lookup[0] === "string" ? lookup[0] : void 0;
  return typeof lookup === "string" ? lookup : void 0;
}
function readCookie(cookieHeader, name) {
  const target = `${name}=`;
  for (const piece of cookieHeader.split(";")) {
    const trimmed = piece.trim();
    if (!trimmed.startsWith(target)) continue;
    return trimmed.slice(target.length);
  }
  return void 0;
}
function honoTangleAuthMiddleware(opts = {}) {
  return async function tangleAuthHandler(c, next) {
    const outcome = await requireTangleAuth(c.req.raw, opts);
    if (!outcome.ok) {
      return new Response(
        JSON.stringify({
          success: false,
          error: { code: outcome.reason.toUpperCase(), message: outcome.reason }
        }),
        {
          status: outcome.status,
          headers: { "content-type": "application/json" }
        }
      );
    }
    c.set("tangleAuth", outcome.auth);
    await next();
  };
}
function expressTangleAuthMiddleware(opts = {}) {
  return async function tangleAuthHandler(req, res, next) {
    const headers = req.headers ?? {};
    const outcome = await requireTangleAuth({ headers }, opts);
    if (!outcome.ok) {
      res.status(outcome.status);
      res.setHeader?.("content-type", "application/json");
      res.end(JSON.stringify({
        success: false,
        error: { code: outcome.reason.toUpperCase(), message: outcome.reason }
      }));
      return;
    }
    req.tangleAuth = outcome.auth;
    next();
  };
}

export {
  requireTangleAuth,
  extractToken,
  honoTangleAuthMiddleware,
  expressTangleAuthMiddleware
};
//# sourceMappingURL=chunk-CDY2ETYT.js.map