{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { ok } from 'node:assert'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\n/** How often to consider periodic license renewal (in ms) */\nexport const AUTORENEWAL_INTERVAL = 15 * 60 * 1000 // 15 minutes\n\nexport type TLicenseManagerConfig = {\n  server?: string\n  tenantId: number\n  productIdentifier: string\n\n  /**\n   * Whether to renew the license periodically.\n   *\n   * @default true\n   */\n  autoRenewEnabled?: boolean\n  /**\n   * Whether to return any floatable entitlements to the pool on SDK shutdown.\n   *\n   * @default true\n   */\n  detachFloatingOnShutdown?: boolean\n  offlineMode?: boolean\n  renewOnInit?: boolean\n  autoRenewOffset?: number\n  loadCertStr: () => Promise<TLicenseBlock>\n  saveCertStr: (cert: TLicenseBlock) => Promise<void>\n  collectUsageMetrics?: () => Promise<Array<TUsageMetric>>\n  collectPassthroughData?: () => Promise<TPassthroughData>\n  deviceFingerprint?: () => string | Promise<string>\n  onFeatureChange?: (features: TFeatures) => any\n  onLicenseRenewed?: () => void\n\n  /**\n   * Callback to fire when the license is within `expirySoonOffsetMins` minutes of expiry.\n   * Fires only one time per license cert and resets on renewal. Sync callbacks only.\n   */\n  onExpirySoon?: () => void\n\n  /** The `onExpirySoon` callback will fire when the license is within this many minutes of expiry. */\n  expirySoonOffsetMins?: number\n\n  logger?: TLogger\n}\n\nexport type TLicenseBlock = string\n\nexport type TLicenseContainer = {\n  licenseKey: string\n  x509: string\n}\n\nexport type TFeatures = { [key: string]: boolean | number | string }\n\nexport type TUsageMetric = { name: string; value: number }\n\nexport type TPassthroughData = Record<string, unknown>\n\nexport type TMetadata = {\n  [key: string]: boolean | number | string | Array<any> | {}\n}\n\nexport type TEntitlement = {\n  id: string\n  productId: string\n  productMetadata: TMetadata\n  features: TFeatures\n  featureOverrides: TFeatures\n  validFrom: Date\n  validTo: Date\n  isFloatable: boolean\n}\n\nexport type TLicenseCertObj = {\n  consumerId: string\n  consumerRef?: string\n  version: number\n  tenantId: number\n  renewalToken: string\n  deviceLock: boolean\n  deviceFingerprint: string\n  createdAt: Date\n  issuedAt: Date\n  expiresAt: Date\n  terminatesAt: Date\n  entitlements: TEntitlement[]\n  /**\n   * Indicates the number of floating entitlements that are not attached to the consumer\n   * because they are in use elsewhere at the time of renewal.\n   */\n  detachedEntitlementsCount: number\n  managementJwt: string\n  /**\n   * Specifies whether the license is ephemeral and therefore does not have corresponding entries in the license server DB.\n   */\n  isEphemeral: boolean\n}\n\nexport type TLogger = {\n  error: Function\n  warn: Function\n  info: Function\n  debug: Function\n}\n\ntype SingleTimer = NodeJS.Timeout\ntype RepeatingTimer = NodeJS.Timeout\n\nconst enum LogLevel {\n  ERROR = 'error',\n  WARN = 'warn',\n  INFO = 'info',\n  DEBUG = 'debug',\n}\n\nexport class LicenseManager {\n  public config: TLicenseManagerConfig\n\n  private initializationPromise?: Promise<void>\n  private key?: NodeRSA\n  private logger: TLogger\n  protected licenseCert?: TLicenseCertObj\n  private x509Cert?: X509Certificate\n  private x509IssuerCert: X509Certificate\n  private deviceFingerprint?: string\n  private renewalTimer?: RepeatingTimer\n  private upcomingEntitlementChangesCheckTimer?: RepeatingTimer\n  private entitlementChangeTimer?: SingleTimer\n  private expirySoonTimer?: SingleTimer\n  private expirySoonCallbackFired = false\n  private currentFeatures?: TFeatures\n  private isShuttingDown = false\n\n  get isInitialized() {\n    return !!this.initializationPromise\n  }\n\n  constructor(config: TLicenseManagerConfig) {\n    this.config = config\n\n    if (this.config.logger) {\n      this.logger = this.config.logger\n    } else {\n      this.logger = {\n        error() {\n          console.log('ERROR:', ...arguments)\n        },\n        warn() {\n          console.log('WARN:', ...arguments)\n        },\n        info() {\n          console.log('INFO:', ...arguments)\n        },\n        debug() {\n          console.log('DEBUG:', ...arguments)\n        },\n      }\n    }\n\n    this.x509IssuerCert = new X509Certificate(\n      '-----BEGIN CERTIFICATE-----\\n' +\n        'MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE\\n' +\n        'RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp\\n' +\n        'Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL\\n' +\n        'MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw\\n' +\n        'FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\\n' +\n        'AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q\\n' +\n        'IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+\\n' +\n        'btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU\\n' +\n        'zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED\\n' +\n        '+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS\\n' +\n        'dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po\\n' +\n        'Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S\\n' +\n        '28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM\\n' +\n        'K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs\\n' +\n        'sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL\\n' +\n        'JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ\\n' +\n        'KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8\\n' +\n        'ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3\\n' +\n        'Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl\\n' +\n        '/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP\\n' +\n        'Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK\\n' +\n        'LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc\\n' +\n        'Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw\\n' +\n        'uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP\\n' +\n        'A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD\\n' +\n        '4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT\\n' +\n        '/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ\\n' +\n        '-----END CERTIFICATE-----'\n    )\n\n    //set defaults for not set config properties:\n    this.config.autoRenewEnabled = this.config.autoRenewEnabled ?? true\n    this.config.renewOnInit = this.config.renewOnInit ?? false\n    this.config.offlineMode = this.config.offlineMode ?? false\n    this.config.autoRenewOffset = this.config.autoRenewOffset ?? 60 * 60 * 72 // default: 72 hours\n    this.config.expirySoonOffsetMins = this.config.expirySoonOffsetMins ?? 0 // default: disabled\n    this.config.detachFloatingOnShutdown =\n      this.config.detachFloatingOnShutdown ?? true\n    this.config.server = this.config.server ?? 'https://license.n8n.io/v1'\n  }\n\n  log(msg: string, logLevel: LogLevel) {\n    this.logger[logLevel](`[license SDK] ${msg}`)\n  }\n\n  async initialize() {\n    if (this.initializationPromise) {\n      return this.initializationPromise\n    }\n\n    this.initializationPromise = this._doInitialization()\n\n    return await this.initializationPromise\n  }\n\n  private isInitialRenewalRequired() {\n    const logRenewalMessage = (message: string) => {\n      this.log(`Skipping renewal on init: ${message}`, LogLevel.INFO)\n    }\n\n    let isRenewalRequired = true\n    if (!this.config.renewOnInit) {\n      isRenewalRequired = false\n      logRenewalMessage('renewOnInit is disabled in config')\n    }\n\n    if (!this.config.autoRenewEnabled) {\n      isRenewalRequired = false\n      logRenewalMessage('autoRenewEnabled is disabled in config')\n    }\n\n    if (!this.hasCert()) {\n      isRenewalRequired = false\n      logRenewalMessage('license cert is not initialized')\n    } else {\n      // If detachedEntitlementsCount > 0, renewing is important in order to attempt re-attaching floating entitlements!\n      const hasDetachedEntitlements =\n        this.licenseCert.detachedEntitlementsCount > 0\n      const isDueForRenewal = this.isRenewalDue()\n      if (!(hasDetachedEntitlements || isDueForRenewal)) {\n        isRenewalRequired = false\n\n        const logMessage = !isDueForRenewal\n          ? 'license cert is not due for renewal'\n          : 'license cert has no detached entitlements'\n        logRenewalMessage(logMessage)\n      }\n    }\n\n    return isRenewalRequired\n  }\n\n  /** Initializes the license manager */\n  private async _doInitialization() {\n    ok(!this.initializationPromise, 'Initialization already in progress')\n\n    this.deviceFingerprint = await this.computeDeviceFingerprint()\n    this.log(\n      `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n      LogLevel.DEBUG\n    )\n\n    await this.initCert() // doesn't throw!\n\n    // Clear and set up periodic timer for entitlement changes\n    this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n    this.upcomingEntitlementChangesCheckTimer = this.setupRepeatingTimer(\n      () => this.setTimerForNextEntitlementChange(),\n      AUTORENEWAL_INTERVAL\n    )\n\n    this.checkAndTriggerExpirySoonCallback()\n\n    // Renew license on init if necessary\n    if (this.isInitialRenewalRequired()) {\n      await this.renewalCron({ force: true })\n    }\n\n    // Set up periodic renewal if enabled\n    if (this.config.autoRenewEnabled) {\n      this.clearRepeatingTimer(this.renewalTimer)\n      this.renewalTimer = this.setupRepeatingTimer(\n        () => this.renewalCron({ force: false }),\n        AUTORENEWAL_INTERVAL\n      )\n    }\n  }\n\n  private setupSingleTimer(\n    callback: () => void,\n    interval: number\n  ): SingleTimer {\n    return setTimeout(callback, interval)\n  }\n\n  clearSingleTimer(timer: SingleTimer | undefined) {\n    if (timer) {\n      clearTimeout(timer)\n    }\n  }\n\n  setupRepeatingTimer(callback: () => void, interval: number): RepeatingTimer {\n    return setInterval(callback, interval)\n  }\n\n  clearRepeatingTimer(timer: RepeatingTimer | undefined) {\n    if (timer) {\n      clearInterval(timer)\n    }\n  }\n\n  private isOlderThan(date: Date, durationInMs: number) {\n    return Date.now() - date.getTime() > durationInMs\n  }\n\n  async reload() {\n    await this.reset()\n    await this.initialize()\n  }\n\n  async reset() {\n    // Make sure initialization is not ongoing before resetting\n    if (this.initializationPromise) {\n      await this.initializationPromise\n    }\n    this.clearRepeatingTimer(this.renewalTimer)\n    this.renewalTimer = undefined\n    this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n    this.upcomingEntitlementChangesCheckTimer = undefined\n    this.clearSingleTimer(this.entitlementChangeTimer)\n    this.entitlementChangeTimer = undefined\n    this.clearSingleTimer(this.expirySoonTimer)\n    this.expirySoonTimer = undefined\n    this.expirySoonCallbackFired = false\n\n    this.licenseCert = undefined\n    this.deviceFingerprint = undefined\n    this.initializationPromise = undefined\n  }\n\n  async computeDeviceFingerprint() {\n    if (\n      this.config.deviceFingerprint &&\n      typeof this.config.deviceFingerprint === 'function'\n    ) {\n      return await this.config.deviceFingerprint()\n    }\n    return await machineId()\n  }\n\n  async activate(\n    reservationId: string,\n    options?: { eulaUri?: string; email?: string }\n  ) {\n    if (!this.isInitialized) {\n      throw new Error('activation failed because SDK was not yet initialized')\n    }\n\n    if (this.isShuttingDown) {\n      throw new Error('activation failed because SDK is shutting down')\n    }\n\n    if (this.config.offlineMode) {\n      throw new Error('activation failed because SDK is in offline mode')\n    }\n\n    const postData: {\n      reservationId: string\n      tenantId: number\n      productIdentifier: string\n      deviceFingerprint: string\n      consumerId?: string\n      renewalToken?: string\n      eulaUri?: string\n      email?: string\n    } = {\n      reservationId,\n      tenantId: this.config.tenantId,\n      productIdentifier: this.config.productIdentifier,\n      deviceFingerprint: this.deviceFingerprint!,\n    }\n\n    if (options?.eulaUri) {\n      postData.eulaUri = options.eulaUri\n    }\n\n    if (options?.email) {\n      postData.email = options.email\n    }\n\n    if (this.hasCert()) {\n      postData.consumerId = this.licenseCert.consumerId\n      postData.renewalToken = this.licenseCert.renewalToken\n    }\n\n    type ResponseDataFormat = {\n      licenseKey?: string\n      x509?: string\n      detachedEntitlementsCount?: number\n      message?: string\n      errorId?: string\n      info?: Record<string, any>\n    }\n\n    type PostRequestResponse = Awaited<\n      ReturnType<typeof postRequest<ResponseDataFormat>>\n    >\n\n    let response: PostRequestResponse\n\n    try {\n      response = await postRequest<{\n        licenseKey?: string\n        x509?: string\n        message?: string\n        errorId?: string\n        info?: Record<string, any>\n      }>(`${this.config.server!}/activate`, postData, {\n        timeoutInMs: 10000,\n        productIdentifier: this.config.productIdentifier,\n      })\n    } catch (error) {\n      this.log(\n        'license activation failed: ' + (error as Error).message,\n        LogLevel.WARN\n      )\n      throw new Error((error as Error).message)\n    }\n\n    if (response.status == 200) {\n      if (\n        !response.data.hasOwnProperty('licenseKey') ||\n        !response.data.hasOwnProperty('x509')\n      ) {\n        this.log('unexpected server response', LogLevel.WARN)\n        throw new Error('unexpected server response')\n      }\n      const containerStr = this.stringifyCertContainer({\n        licenseKey: response.data.licenseKey,\n        x509: response.data.x509,\n      } as TLicenseContainer)\n      await this.config.saveCertStr(containerStr)\n      await this.initCert()\n      this.log('license successfully activated', LogLevel.INFO)\n      if (response.data.detachedEntitlementsCount ?? 0 > 0) {\n        this.log(\n          `skipped importing ${response.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n          LogLevel.INFO\n        )\n      }\n    } else {\n      const errorMsg = `license activation failed: ${\n        response.data.message ?? 'unknown reason'\n      }`\n      const e = new Error(errorMsg) as Error & { errorId?: string; info?: Record<string, any> }\n\n      if (response.data.errorId) {\n        e.errorId = response.data.errorId\n      }\n\n      if (response.data.info) {\n        e.info = response.data.info\n      }\n\n      this.log(errorMsg, LogLevel.WARN)\n      throw e\n    }\n  }\n\n  async renew() {\n    return this._renew({ cause: 'request' })\n  }\n\n  async _renew({\n    detachFloatingEntitlements = false,\n    cause = 'unknown',\n  }: {\n    detachFloatingEntitlements?: Boolean\n    cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown'\n  } = {}) {\n    if (!this.hasCert()) {\n      throw new Error('renewal failed because current cert is not initialized')\n    }\n\n    if (this.licenseCert.isEphemeral) {\n      return\n    }\n\n    if (this.isTerminated()) {\n      throw new Error('renewal failed because current cert was terminated')\n    }\n\n    if (this.config.offlineMode) {\n      throw new Error('renewal failed because SDK is in offline mode')\n    }\n\n    if (this.config.tenantId !== this.licenseCert.tenantId) {\n      throw new Error('renewal failed because tenant ID does not match')\n    }\n\n    // error out if device fingerprint does not match but allow renewal on explicit request\n    // as the consumer might have been changed to more permissive settings on the server\n    if (\n      cause !== 'request' &&\n      this.licenseCert.deviceLock &&\n      this.deviceFingerprint !== this.licenseCert.deviceFingerprint\n    ) {\n      throw new Error(\n        'renewal failed because device fingerprint does not match'\n      )\n    }\n\n    const [usageMetrics, passthroughData] = await Promise.all([\n      this.config.collectUsageMetrics ? this.config.collectUsageMetrics() : [],\n      this.config.collectPassthroughData\n        ? this.config.collectPassthroughData()\n        : {},\n    ])\n\n    type ResponseDataFormat = {\n      licenseKey?: string\n      x509?: string\n      detachedEntitlementsCount?: number\n      message?: string\n      errorId?: string\n    }\n\n    type PostRequestResponse = Awaited<\n      ReturnType<typeof postRequest<ResponseDataFormat>>\n    >\n\n    let response: PostRequestResponse\n\n    try {\n      response = await postRequest<ResponseDataFormat>(\n        `${this.config.server!}/renew`,\n        {\n          consumerId: this.licenseCert.consumerId,\n          tenantId: this.config.tenantId,\n          deviceFingerprint: this.deviceFingerprint,\n          productIdentifier: this.config.productIdentifier,\n          renewalToken: this.licenseCert.renewalToken,\n          detachFloatingEntitlements,\n          cause,\n          usageMetrics,\n          passthroughData,\n        },\n        { timeoutInMs: 10000, productIdentifier: this.config.productIdentifier }\n      )\n    } catch (error) {\n      this.log(\n        'license renewal failed: ' + (error as Error).message,\n        LogLevel.WARN\n      )\n      throw new Error((error as Error).message)\n    }\n\n    const responseData = response.data\n\n    if (response.status == 200) {\n      if (\n        !responseData.hasOwnProperty('licenseKey') ||\n        !responseData.hasOwnProperty('x509')\n      ) {\n        this.log(\n          'license renewal failed: unexpected server response',\n          LogLevel.WARN\n        )\n        throw new Error('unexpected server response')\n      }\n      const containerStr = this.stringifyCertContainer({\n        licenseKey: responseData.licenseKey,\n        x509: responseData.x509,\n      } as TLicenseContainer)\n      await this.config.saveCertStr(containerStr)\n\n      this.log('license successfully renewed', LogLevel.INFO)\n\n      this.config.onLicenseRenewed?.()\n\n      if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n        if (detachFloatingEntitlements) {\n          this.log(\n            `${responseData.detachedEntitlementsCount} floating entitlements were returned to the pool`,\n            LogLevel.INFO\n          )\n        } else {\n          this.log(\n            `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n            LogLevel.INFO\n          )\n        }\n      }\n\n      await this.initCert()\n    } else {\n      const errorMsg = `license renewal failed: ${\n        responseData.message ?? 'unknown reason'\n      }`\n\n      this.log(errorMsg, LogLevel.WARN)\n\n      const e = new Error(errorMsg) as Error & { errorId?: string }\n\n      if (responseData.errorId) {\n        e.errorId = responseData.errorId\n\n        if (\n          ['NOT_FOUND', 'CONSUMER_TERMINATED'].includes(responseData.errorId)\n        ) {\n          this.log(\n            'license was terminated by the server. Deleting local cert.',\n            LogLevel.WARN\n          )\n          await this.config.saveCertStr('')\n          await this.initCert()\n        } else if (responseData.errorId === 'FINGERPRINT_MISMATCH') {\n          // pause auto-renewal as subsequent requests will also fail\n          this.disableAutoRenewals()\n        }\n      }\n\n      throw e\n    }\n  }\n\n  private hasCert(): this is { licenseCert: TLicenseCertObj } {\n    return !!this.licenseCert\n  }\n\n  isTerminated(): boolean {\n    if (!this.hasCert()) {\n      throw new Error('Cert is not initialized')\n    }\n\n    const now = new Date()\n\n    return this.licenseCert.terminatesAt < now\n  }\n\n  getExpiryDate(): Date {\n    if (!this.hasCert()) {\n      throw new Error('Cert is not initialized')\n    }\n\n    return this.licenseCert.expiresAt\n  }\n\n  getTerminationDate(): Date {\n    if (!this.hasCert()) {\n      throw new Error('Cert is not initialized')\n    }\n\n    return this.licenseCert.terminatesAt\n  }\n\n  isValid(useLogger = true): boolean {\n    const logError = (msg: string) => {\n      if (useLogger) {\n        const debugMetadata = this.hasCert()\n          ? `: (autorenewalsEnabled: ${this.config.autoRenewEnabled}, expiredAt: ${this.licenseCert?.expiresAt}, issuedAt: ${this.licenseCert?.issuedAt})`\n          : ''\n\n        this.log(`${msg}${debugMetadata}`, LogLevel.ERROR)\n      }\n    }\n\n    if (!this.hasCert()) {\n      logError('cert is invalid because it is undefined')\n      return false\n    }\n\n    const cert = this.licenseCert as TLicenseCertObj\n    const now = new Date()\n\n    if (cert.expiresAt < now) {\n      logError('cert is invalid because it has expired')\n      return false\n    }\n\n    if (cert.terminatesAt < now) {\n      logError('cert is invalid because it was terminated')\n      return false\n    }\n\n    //allow clocks to be out of sync by no more than 300,000 ms / = 5 minutes\n    if (cert.createdAt.getTime() - 300000 > now.getTime()) {\n      logError('cert is invalid because system clock is out of sync')\n      return false\n    }\n\n    if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n      logError('cert is invalid because device fingerprint does not match')\n      return false\n    }\n\n    if (this.config.tenantId !== cert.tenantId) {\n      logError('cert is invalid because tenant ID does not match')\n      return false\n    }\n\n    return true\n  }\n\n  hasFeatureEnabled(\n    feature: string,\n    requireValidCert: boolean = true\n  ): boolean {\n    return this.getFeatureValue(feature, requireValidCert) ? true : false\n  }\n\n  hasFeatureDefined(\n    feature: string,\n    requireValidCert: boolean = true\n  ): boolean {\n    return this.getFeatureValue(feature, requireValidCert) !== undefined\n      ? true\n      : false\n  }\n\n  hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean {\n    const quota = this.getFeatureValue(quotaFeatureName)\n\n    if (quota === undefined) {\n      return false\n    }\n\n    if (typeof quota !== 'number') {\n      throw new Error(\n        `${quotaFeatureName} cannot be used as quota as it is not numeric`\n      )\n    }\n\n    // -1 means unlimited quota!\n    if (quota === -1) {\n      return true\n    }\n\n    return Math.ceil(currentConsumption) < Math.ceil(quota)\n  }\n\n  getFeatureValue(\n    feature: string,\n    requireValidCert: boolean = true\n  ): undefined | boolean | number | string {\n    if (!this.hasCert()) {\n      return undefined\n    }\n\n    if (requireValidCert && !this.isValid()) {\n      return undefined\n    }\n\n    const currentFeatures = this.getFeatures()\n\n    if (!currentFeatures.hasOwnProperty(feature)) {\n      return undefined\n    }\n\n    return currentFeatures[feature]\n  }\n\n  private updateCurrentFeatures() {\n    if (!this.hasCert()) {\n      return\n    }\n\n    const now = new Date()\n\n    if (\n      this.licenseCert.expiresAt < now ||\n      this.licenseCert.terminatesAt < now\n    ) {\n      this.currentFeatures = {} as TFeatures\n    }\n\n    this.currentFeatures = this.licenseCert.entitlements\n      .filter(\n        (entitlement) =>\n          entitlement.validFrom <= now && entitlement.validTo > now\n      )\n      .sort(\n        (entitlement1, entitlement2) =>\n          entitlement1.validFrom.getTime() - entitlement2.validFrom.getTime()\n      )\n      .reduce((currentFeatures, entitlement) => {\n        return {\n          ...currentFeatures,\n          ...entitlement.features,\n          ...entitlement.featureOverrides,\n        }\n      }, {} as TFeatures)\n  }\n\n  getFeatures() {\n    if (!this.hasCert()) {\n      return {}\n    }\n\n    return this.currentFeatures ?? {}\n  }\n\n  getCurrentEntitlements() {\n    if (!this.hasCert()) {\n      return []\n    }\n\n    const now = new Date()\n\n    return this.licenseCert.entitlements.filter(\n      (entitlement) => entitlement.validFrom <= now && entitlement.validTo > now\n    )\n  }\n\n  getManagementJwt() {\n    if (!this.licenseCert) {\n      return ''\n    }\n\n    return this.licenseCert.managementJwt\n  }\n\n  async getCertStr(): Promise<TLicenseBlock> {\n    return this.config.loadCertStr()\n  }\n\n  getConsumerId() {\n    return this.licenseCert?.consumerId\n  }\n\n  isRenewalDue(): boolean {\n    if (!this.licenseCert || this.licenseCert.isEphemeral) {\n      return false\n    }\n\n    const now = Date.now()\n    const mins15inMs = 1000 * 60 * 15\n    const mins20inMs = 1000 * 60 * 20\n    const expiry = this.licenseCert.expiresAt.getTime()\n    const issuedAt = this.licenseCert.issuedAt.getTime()\n    const termination = this.licenseCert.terminatesAt.getTime()\n\n    //consumerRenewalDue is TRUE when current time is close enough to consumer expiry and not after consumer termination\n    const consumerRenewalDue =\n      now > expiry - this.config.autoRenewOffset! * 1000 && now < termination\n\n    //entitlementRenewalDue is TRUE when one currently valid entitlement will expire in the next 15 minutes\n    //and the Cert was issued more than 20 minutes ago\n    const entitlementRenewalDue =\n      this.getCurrentEntitlements().find(\n        (entitlement) =>\n          now >= entitlement.validTo.getTime() - mins15inMs &&\n          now <= entitlement.validTo.getTime()\n      ) !== undefined && issuedAt < now - mins20inMs\n\n    return consumerRenewalDue || entitlementRenewalDue\n  }\n\n  private formatDuration(seconds: number): string {\n    const hours = Math.floor(seconds / 3600)\n    const minutes = Math.floor((seconds % 3600) / 60)\n    const remainingSeconds = seconds % 60\n\n    return `${hours}h ${minutes}m ${remainingSeconds}s`\n  }\n\n  toString() {\n    const isValid = this.isValid(false)\n    const isRenewalDue = this.isRenewalDue()\n    const hasDetachedEntitlements =\n      (this.licenseCert?.detachedEntitlementsCount ?? 0) > 0\n\n    // Helper function to format values with warnings\n    const formatWithWarning = (value: any, condition: any) =>\n      `${value}${condition ? ' (!)' : ''}`\n\n    // Helper function to display value or default\n    const formatValue = (value: any, defaultValue = '<n/a>') =>\n      value ?? defaultValue\n\n    // Build sections of the output\n    const consumerConfig = [\n      '## CONSUMER CONFIG ##',\n      `tenantId: ${formatValue(this.config.tenantId)}`,\n      `productIdentifier: ${formatValue(this.config.productIdentifier)}`,\n      `deviceFingerprint: ${formatValue(this.deviceFingerprint)}`,\n      `autoRenewalEnabled: ${formatWithWarning(\n        this.config.autoRenewEnabled ? 'true' : 'false',\n        !this.config.autoRenewEnabled\n      )}`,\n      `autoRenewalOffset: ${\n        this.config.autoRenewOffset\n      } (= ${this.formatDuration(this.config.autoRenewOffset ?? 0)})`,\n    ].join('\\n')\n\n    const licenseCert = [\n      '## LICENSE CERT ##',\n      `version: ${formatValue(this.licenseCert?.version)}`,\n      `tenantId: ${formatWithWarning(\n        formatValue(this.licenseCert?.tenantId),\n        this.licenseCert?.tenantId !== this.config.tenantId\n      )}`,\n      `consumerId: ${formatValue(this.licenseCert?.consumerId)}`,\n      `deviceFingerprint: ${formatWithWarning(\n        formatValue(this.licenseCert?.deviceFingerprint),\n        this.licenseCert?.deviceFingerprint !== this.deviceFingerprint\n      )}`,\n      `createdAt: ${formatValue(this.licenseCert?.createdAt)}`,\n      `issuedAt: ${formatValue(this.licenseCert?.issuedAt)}`,\n      `expiresAt: ${formatValue(this.licenseCert?.expiresAt)}`,\n      `terminatesAt: ${formatValue(this.licenseCert?.terminatesAt)}`,\n      `isEphemeral: ${formatValue(this.licenseCert?.isEphemeral)}`,\n      `isValid: ${formatWithWarning(isValid, !isValid)}`,\n      `isRenewalDue: ${formatWithWarning(isRenewalDue, isRenewalDue)}`,\n      `detachedEntitlementsCount: ${formatWithWarning(\n        formatValue(this.licenseCert?.detachedEntitlementsCount),\n        hasDetachedEntitlements\n      )}`,\n      `entitlements: ${this.licenseCert?.entitlements?.length ?? 0}`,\n    ].join('\\n')\n\n    // Format entitlements\n    const entitlements =\n      this.licenseCert?.entitlements\n        ?.map((entitlement, index) =>\n          [\n            '## ENTITLEMENT ' + (index + 1) + ' ##',\n            `id: ${entitlement.id}`,\n            `productId: ${entitlement.productId}`,\n            `validFrom: ${entitlement.validFrom}`,\n            `validTo: ${entitlement.validTo}`,\n            `features: ${JSON.stringify(entitlement.features)}`,\n            `featureOverrides: ${JSON.stringify(entitlement.featureOverrides)}`,\n          ].join('\\n')\n        )\n        .join('\\n--\\n') || ''\n\n    // Combine all sections with proper separators\n    return [\n      consumerConfig,\n      '--',\n      licenseCert,\n      entitlements ? '--\\n' + entitlements : '',\n    ].join('\\n')\n  }\n\n  private triggerOnFeatureChangeCallback() {\n    if (this.config.onFeatureChange) {\n      this.config.onFeatureChange(this.currentFeatures ?? {})\n    }\n  }\n\n  private setTimerForNextEntitlementChange() {\n    if (!this.hasCert()) {\n      return\n    }\n\n    const now = Date.now()\n    const offsets = new Set<number>()\n\n    offsets.add(this.licenseCert.expiresAt.getTime() - now)\n    offsets.add(this.licenseCert.terminatesAt.getTime() - now)\n\n    if (this.config.onExpirySoon && this.config.expirySoonOffsetMins) {\n      const expirySoonTimeMs =\n        this.licenseCert.expiresAt.getTime() -\n        this.config.expirySoonOffsetMins * 60 * 1000\n      offsets.add(expirySoonTimeMs - now)\n    }\n\n    const upcomingEventOffsets = [\n      ...this.licenseCert.entitlements.reduce((offsets, entitlement) => {\n        offsets.add(entitlement.validFrom.getTime() - now)\n        offsets.add(entitlement.validTo.getTime() - now)\n        return offsets\n      }, offsets),\n    ]\n      .filter((offset) => offset >= 0 && offset <= AUTORENEWAL_INTERVAL) // keep if offset is within the next 15 minutes\n      .sort((a, b) => a - b)\n\n    //console.dir(upcomingEventOffsets.map((offset) => offset / 1000 / 60))\n\n    if (upcomingEventOffsets.length === 0) {\n      return\n    }\n\n    const timeTillNextEventInMs = upcomingEventOffsets[0]\n\n    this.clearSingleTimer(this.entitlementChangeTimer)\n    this.entitlementChangeTimer = this.setupSingleTimer(() => {\n      this.updateCurrentFeatures()\n      this.triggerOnFeatureChangeCallback()\n      this.checkAndTriggerExpirySoonCallback()\n      this.setTimerForNextEntitlementChange()\n    }, timeTillNextEventInMs + 1000)\n  }\n\n  private checkAndTriggerExpirySoonCallback() {\n    if (\n      !this.hasCert() ||\n      !this.config.onExpirySoon ||\n      !this.config.expirySoonOffsetMins ||\n      this.expirySoonCallbackFired\n    ) {\n      return\n    }\n\n    const timeUntilExpiryMs = this.licenseCert.expiresAt.getTime() - Date.now()\n    const callbackWindowMs = this.config.expirySoonOffsetMins * 60 * 1000\n\n    if (timeUntilExpiryMs > 0 && timeUntilExpiryMs <= callbackWindowMs) {\n      try {\n        this.config.onExpirySoon()\n        this.expirySoonCallbackFired = true\n      } catch (error) {\n        this.log(\n          `Failed to run onExpirySoon callback: ${error}`,\n          LogLevel.ERROR\n        )\n      }\n    }\n  }\n\n  private async renewalCron({ force }: { force: boolean }) {\n    if (force || this.isRenewalDue()) {\n      this.log('attempting license renewal', LogLevel.INFO)\n      try {\n        await this._renew({ cause: force ? 'startup' : 'auto' })\n      } catch (e) {}\n    }\n  }\n\n  private async initCert() {\n    if (this.isShuttingDown) {\n      return\n    }\n\n    try {\n      const containerStr = await this.getCertStr()\n      if (!containerStr) {\n        this.licenseCert = undefined\n        return\n      }\n      if (containerStr.length < 50) {\n        throw new Error('cert string is undefined or too short')\n      }\n      const { x509, licenseKey } =\n        this.parseLicenseCertContainerStr(containerStr)\n      this.x509Cert = new X509Certificate(x509)\n      const hasApprovedIssuer = this.x509Cert.checkIssued(this.getIssuerCert())\n      if (!hasApprovedIssuer) {\n        throw new Error('cert was not issued by an approved issuer')\n      }\n      const publicKey = this.x509Cert.publicKey.export({\n        format: 'pem',\n        type: 'pkcs1',\n      })\n      this.key = new NodeRSA(publicKey)\n      this.licenseCert = this.parseLicenseKeyStr(licenseKey)\n      this.updateCurrentFeatures()\n      this.setTimerForNextEntitlementChange()\n      this.expirySoonCallbackFired = false\n    } catch (e) {\n      this.log(\n        `cert could not be initialized. ${e instanceof Error ? e.message : ''}`,\n        LogLevel.ERROR\n      )\n    }\n  }\n\n  private stringifyCertContainer(container: TLicenseContainer): string {\n    const containerStr = JSON.stringify(container)\n    return Buffer.from(containerStr).toString('base64')\n  }\n\n  private parseLicenseCertContainerStr(\n    stringifiedContainer: string\n  ): TLicenseContainer {\n    const containerStr = Buffer.from(stringifiedContainer, 'base64').toString(\n      'ascii'\n    )\n    const container = JSON.parse(containerStr)\n    if (\n      !container.hasOwnProperty('licenseKey') ||\n      !container.hasOwnProperty('x509')\n    ) {\n      throw new Error('license cert container could not be parsed')\n    }\n\n    return container as TLicenseContainer\n  }\n\n  private parseLicenseKeyStr(certStr: string): TLicenseCertObj {\n    const certPayload = this.validateLicenseKey(certStr)\n\n    const cert = { ...certPayload } as TLicenseCertObj\n\n    // turn timestamp strings into Date objects\n    cert.createdAt = new Date(certPayload.createdAt)\n    cert.issuedAt = new Date(certPayload.issuedAt)\n    cert.expiresAt = new Date(certPayload.expiresAt)\n    cert.terminatesAt = new Date(certPayload.terminatesAt)\n\n    // make sure detachedEntitlementsCount is a number (certs issues before this field was introduced will have it missing)\n    cert.detachedEntitlementsCount = certPayload.detachedEntitlementsCount ?? 0\n\n    cert.entitlements = cert.entitlements.map((entitlement) => {\n      entitlement.validFrom = new Date(entitlement.validFrom)\n      entitlement.validTo = new Date(entitlement.validTo)\n      return entitlement\n    })\n\n    return cert\n  }\n\n  private validateLicenseKey(licenseKey: string) {\n    //remove all line breaks\n    licenseKey = licenseKey.replace(/(\\r\\n|\\n|\\r)/gm, '')\n\n    //extract parts\n    const match = licenseKey.match(\n      /^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\\|\\|)(?<encryptedData>.+)\\|\\|(?<signature>.+)-----END LICENSE KEY-----$/\n    )\n\n    if (!match) {\n      throw new Error('license key could not be parsed')\n    }\n\n    const encryptedSymmetricKey = match.groups!.encryptedSymmetricKey\n    const payload = match.groups!.encryptedData\n    const signature = match.groups!.signature\n\n    let symmetricKey, decryptedData\n\n    //decrypt the random symmetric key\n    try {\n      symmetricKey = this.key!.decryptPublic(encryptedSymmetricKey, 'utf8')\n    } catch (e) {\n      throw new Error('Invalid data: Could not extract symmetric key')\n    }\n\n    //decrypt the payload\n    try {\n      decryptedData = CryptoJS.AES.decrypt(payload, symmetricKey).toString(\n        CryptoJS.enc.Utf8\n      )\n    } catch (e) {\n      throw new Error('Invalid Data: Could not decrypt data with key found')\n    }\n\n    //verify the signature.\n    if (\n      this.key!.verify(Buffer.from(decryptedData), signature, 'utf8', 'base64')\n    ) {\n      //return the decrypted data.\n      return JSON.parse(decryptedData)\n    } else {\n      throw new Error('License Key signature invalid')\n    }\n  }\n\n  public getIssuerCert() {\n    return this.x509IssuerCert\n  }\n\n  /**\n   * Detaches any floating entitlements and clears the local license cert.\n   */\n  public async clear() {\n    try {\n      await this.detachFloatingEntitlements()\n    } catch (err) {\n      this.log(\n        `failed to detach floating entitlements (${err}). Continuing with clearing license certificate`,\n        LogLevel.WARN\n      )\n    } finally {\n      await this.config.saveCertStr('')\n      await this.initCert()\n    }\n  }\n\n  public async shutdown() {\n    this.isShuttingDown = true\n\n    this.clearRepeatingTimer(this.renewalTimer)\n    this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n    this.clearSingleTimer(this.entitlementChangeTimer)\n    this.clearSingleTimer(this.expirySoonTimer)\n\n    if (this.config.detachFloatingOnShutdown) {\n      await this.detachFloatingEntitlements()\n    }\n  }\n\n  private async detachFloatingEntitlements() {\n    if (!this.hasCert()) {\n      return\n    }\n\n    const hasFloatableEntitlements = this.licenseCert.entitlements.some(\n      (entitlement) => entitlement.isFloatable ?? false\n    )\n\n    if (hasFloatableEntitlements) {\n      await this._renew({\n        detachFloatingEntitlements: true,\n        cause: 'shutdown',\n      })\n    }\n  }\n\n  /** Enable periodical renewal of the license. */\n  public enableAutoRenewals() {\n    if (this.config.autoRenewEnabled === true) return\n\n    this.config.autoRenewEnabled = true\n    this.log('License auto-renewals enabled', LogLevel.INFO)\n\n    this.clearRepeatingTimer(this.renewalTimer)\n    this.renewalTimer = this.setupRepeatingTimer(\n      () => this.renewalCron({ force: false }),\n      AUTORENEWAL_INTERVAL\n    )\n  }\n\n  /** Disable periodical renewal of the license. */\n  public disableAutoRenewals() {\n    if (this.config.autoRenewEnabled === false) return\n\n    this.config.autoRenewEnabled = false\n    this.log('License auto-renewals disabled', LogLevel.INFO)\n\n    this.clearRepeatingTimer(this.renewalTimer)\n    this.renewalTimer = undefined\n  }\n}\n","import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n  const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n  return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n  getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n  getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n  ...(httpProxy ? { 'http:': httpProxy } : {}),\n  ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n  (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n  ''\n)\n  .split(',')\n  .map((rule) => rule.trim())\n  .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n  const { host, protocol } = url\n\n  if (protocol === 'http:' && !httpProxy) {\n    return false\n  }\n\n  if (protocol === 'https:' && !httpsProxy) {\n    return false\n  }\n\n  if (noProxyRules.some((rule) => host.endsWith(rule))) {\n    return false\n  }\n\n  return true\n}\n\nexport async function postRequest<T>(\n  url: string,\n  data: Record<string, unknown>,\n  options: {\n    timeoutInMs?: number\n    productIdentifier?: string\n  } = {}\n) {\n  const targetUrl = new URL(url)\n\n  let proxyAgent: ProxyAgent | undefined\n\n  if (shouldUseProxy(targetUrl)) {\n    proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n  }\n\n  try {\n    const response = await fetch(url, {\n      method: 'POST',\n      body: JSON.stringify(data),\n      headers: {\n        'Content-Type': 'application/json',\n        'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n          process.version\n        }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n      },\n      signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n      ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n    })\n\n    return {\n      status: response.status,\n      data: (await response.json()) as T,\n    }\n  } catch (err) {\n    const error = new Error('Connection Error: ' + (err as any).message)\n    ;(error as any).cause = err\n    throw error\n  }\n}\n\nexport default {\n  postRequest,\n}\n","// '2.25.0' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.25.0'\n"],"mappings":"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","names":["CryptoJS","machineId","NodeRSA","ok","X509Certificate","fetch","ProxyAgent","URL","SDK_VERSION","getProxyAgent","envVar","proxyURI","ProxyAgent","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","URL","proxyAgent","response","fetch","SDK_VERSION","err","error","AUTORENEWAL_INTERVAL","LicenseManager","config","X509Certificate","msg","logLevel","logRenewalMessage","message","isRenewalRequired","hasDetachedEntitlements","isDueForRenewal","ok","AUTORENEWAL_INTERVAL","callback","interval","timer","date","durationInMs","machineId","reservationId","options","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","passthroughData","responseData","now","useLogger","logError","debugMetadata","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","seconds","hours","minutes","remainingSeconds","isValid","isRenewalDue","formatWithWarning","value","condition","formatValue","defaultValue","consumerConfig","licenseCert","entitlements","index","offsets","expirySoonTimeMs","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","timeUntilExpiryMs","callbackWindowMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS","err"]}