import {
  __esm
} from "./chunk-J7LXIPZS.mjs";

// src/enterprise/license/validator.ts
import * as crypto from "crypto";
import * as fs from "fs";
import * as path from "path";
var LicenseValidator;
var init_validator = __esm({
  "src/enterprise/license/validator.ts"() {
    LicenseValidator = class _LicenseValidator {
      /** Ed25519 public key for license verification (PEM format). */
      static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
      cache = null;
      static CACHE_TTL = 5 * 60 * 1e3;
      // 5 minutes
      static GRACE_PERIOD = 72 * 3600 * 1e3;
      // 72 hours after expiry
      /**
       * Load and validate license from environment or file.
       *
       * Resolution order:
       * 1. VISOR_LICENSE env var (JWT string)
       * 2. VISOR_LICENSE_FILE env var (path to file)
       * 3. .visor-license in project root (cwd)
       * 4. .visor-license in ~/.config/visor/
       */
      async loadAndValidate() {
        if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
          return this.cache.payload;
        }
        const token = this.resolveToken();
        if (!token) return null;
        const payload = this.verifyAndDecode(token);
        if (!payload) return null;
        this.cache = { payload, validatedAt: Date.now() };
        return payload;
      }
      /** Check if a specific feature is licensed */
      hasFeature(feature) {
        if (!this.cache) return false;
        return this.cache.payload.features.includes(feature);
      }
      /** Check if license is valid (with grace period) */
      isValid() {
        if (!this.cache) return false;
        const now = Date.now();
        const expiryMs = this.cache.payload.exp * 1e3;
        return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
      }
      /** Check if the license is within its grace period (expired but still valid) */
      isInGracePeriod() {
        if (!this.cache) return false;
        const now = Date.now();
        const expiryMs = this.cache.payload.exp * 1e3;
        return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
      }
      resolveToken() {
        if (process.env.VISOR_LICENSE) {
          return process.env.VISOR_LICENSE.trim();
        }
        if (process.env.VISOR_LICENSE_FILE) {
          const resolved = path.resolve(process.env.VISOR_LICENSE_FILE);
          const home2 = process.env.HOME || process.env.USERPROFILE || "";
          const allowedPrefixes = [path.normalize(process.cwd())];
          if (home2) allowedPrefixes.push(path.normalize(path.join(home2, ".config", "visor")));
          let realPath;
          try {
            realPath = fs.realpathSync(resolved);
          } catch {
            return null;
          }
          const isSafe = allowedPrefixes.some(
            (prefix) => realPath === prefix || realPath.startsWith(prefix + path.sep)
          );
          if (!isSafe) return null;
          return this.readFile(realPath);
        }
        const cwdPath = path.join(process.cwd(), ".visor-license");
        const cwdToken = this.readFile(cwdPath);
        if (cwdToken) return cwdToken;
        const home = process.env.HOME || process.env.USERPROFILE || "";
        if (home) {
          const configPath = path.join(home, ".config", "visor", ".visor-license");
          const configToken = this.readFile(configPath);
          if (configToken) return configToken;
        }
        return null;
      }
      readFile(filePath) {
        try {
          return fs.readFileSync(filePath, "utf-8").trim();
        } catch {
          return null;
        }
      }
      verifyAndDecode(token) {
        try {
          const parts = token.split(".");
          if (parts.length !== 3) return null;
          const [headerB64, payloadB64, signatureB64] = parts;
          const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
          if (header.alg !== "EdDSA") return null;
          const data = `${headerB64}.${payloadB64}`;
          const signature = Buffer.from(signatureB64, "base64url");
          const publicKey = crypto.createPublicKey(_LicenseValidator.PUBLIC_KEY);
          if (publicKey.asymmetricKeyType !== "ed25519") {
            return null;
          }
          const isValid = crypto.verify(null, Buffer.from(data), publicKey, signature);
          if (!isValid) return null;
          const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
          if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
            return null;
          }
          const now = Date.now();
          const expiryMs = payload.exp * 1e3;
          if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
            return null;
          }
          return payload;
        } catch {
          return null;
        }
      }
    };
  }
});
init_validator();
export {
  LicenseValidator
};
//# sourceMappingURL=validator-XTZJZZJH.mjs.map