{"version":3,"file":"index.mjs","sources":["../../src/ee/index.ts"],"sourcesContent":["import { pick, isEqual } from 'lodash/fp';\nimport type { Logger } from '@strapi/logger';\nimport type { Core } from '@strapi/types';\nimport { createStrapiFetch } from '../utils/fetch';\nimport {\n  readLicense,\n  verifyLicense,\n  fetchLicense,\n  LicenseCheckError,\n  LICENSE_REGISTRY_URI,\n} from './license';\nimport { shiftCronExpression } from '../utils/cron';\n\nconst ONE_MINUTE = 1000 * 60;\n\ninterface EE {\n  enabled: boolean;\n  licenseInfo: {\n    licenseKey?: string;\n    features?: Array<{ name: string; [key: string]: any } | string>;\n    expireAt?: string;\n    seats?: number;\n    type?: string;\n    isTrial: boolean;\n    subscriptionId?: string;\n    planPriceId?: string;\n  };\n  logger?: Logger;\n}\n\nconst ee: EE = {\n  enabled: false,\n  licenseInfo: {\n    isTrial: false,\n  },\n};\n\nconst disable = (message: string) => {\n  // Prevent emitting ee.disable if it was already disabled\n  const shouldEmitEvent = ee.enabled !== false;\n\n  ee.logger?.warn(`${message} Switching to CE.`);\n  // Only keep the license key and isTrial for potential re-enabling during a later check\n  ee.licenseInfo = pick(['licenseKey', 'isTrial'], ee.licenseInfo);\n\n  ee.licenseInfo.isTrial = false;\n\n  ee.enabled = false;\n\n  if (shouldEmitEvent) {\n    // Notify EE features that they should be disabled\n    strapi.eventHub.emit('ee.disable');\n  }\n};\n\nconst enable = () => {\n  // Prevent emitting ee.enable if it was already enabled\n  const shouldEmitEvent = ee.enabled !== true;\n\n  ee.enabled = true;\n\n  if (shouldEmitEvent) {\n    // Notify EE features that they should be disabled\n    strapi.eventHub.emit('ee.enable');\n  }\n};\n\nlet initialized = false;\n\n/**\n * Optimistically enable EE if the format of the license is valid, only run once.\n */\nconst init = (licenseDir: string, logger?: Logger) => {\n  if (initialized) {\n    return;\n  }\n\n  initialized = true;\n  ee.logger = logger;\n\n  if (process.env.STRAPI_DISABLE_EE?.toLowerCase() === 'true') {\n    return;\n  }\n\n  try {\n    const license = process.env.STRAPI_LICENSE || readLicense(licenseDir);\n\n    if (license) {\n      ee.licenseInfo = verifyLicense(license);\n      enable();\n    }\n  } catch (error) {\n    if (error instanceof Error) {\n      disable(error.message);\n    } else {\n      disable('Invalid license.');\n    }\n  }\n};\n\n/**\n * Contact the license registry to update the license to its latest state.\n *\n * Store the result in database to avoid unecessary requests, and will fallback to that in case of a network failure.\n */\nconst onlineUpdate = async ({ strapi }: { strapi: Core.Strapi }) => {\n  const { get, commit, rollback } = (await strapi.db?.transaction()) as any;\n  const transaction = get();\n\n  try {\n    const storedInfo = await strapi.db\n      ?.queryBuilder('strapi::core-store')\n      .where({ key: 'ee_information' })\n      .select('value')\n      .first()\n      .transacting(transaction)\n      .forUpdate()\n      .execute()\n      .then((result: any) => (result ? JSON.parse(result.value) : result));\n\n    const shouldContactRegistry = (storedInfo?.lastCheckAt ?? 0) < Date.now() - ONE_MINUTE;\n    const result: {\n      license?: string | null;\n      error?: string;\n      lastCheckAt?: number;\n    } = { lastCheckAt: Date.now() };\n\n    const fallback = (error: Error) => {\n      if (error instanceof LicenseCheckError && error.shouldFallback && storedInfo?.license) {\n        ee.logger?.warn(\n          `${error.message} The last stored one will be used as a potential fallback.`\n        );\n        return storedInfo.license;\n      }\n\n      result.error = error.message;\n      disable(error.message);\n    };\n\n    if (!ee?.licenseInfo?.licenseKey) {\n      throw new Error('Missing license key.');\n    }\n\n    const license = shouldContactRegistry\n      ? await fetchLicense({ strapi }, ee.licenseInfo.licenseKey, strapi.config.get('uuid')).catch(\n          fallback\n        )\n      : storedInfo.license;\n\n    if (license) {\n      try {\n        // Verify license and check if its info changed\n        const newLicenseInfo = verifyLicense(license);\n        const licenseInfoChanged =\n          !isEqual(newLicenseInfo.features, ee.licenseInfo.features) ||\n          newLicenseInfo.seats !== ee.licenseInfo.seats ||\n          newLicenseInfo.type !== ee.licenseInfo.type;\n\n        // Store the new license info\n        ee.licenseInfo = newLicenseInfo;\n        const wasEnabled = ee.enabled;\n        validateInfo();\n\n        // Notify EE features\n        if (licenseInfoChanged && wasEnabled) {\n          strapi.eventHub.emit('ee.update');\n        }\n      } catch (error) {\n        if (error instanceof Error) {\n          disable(error.message);\n        } else {\n          disable('Invalid license.');\n        }\n      }\n    } else if (!shouldContactRegistry) {\n      disable(storedInfo.error);\n    }\n\n    if (shouldContactRegistry) {\n      result.license = license ?? null;\n      const query = strapi.db.queryBuilder('strapi::core-store').transacting(transaction);\n\n      if (!storedInfo) {\n        query.insert({ key: 'ee_information', value: JSON.stringify(result) });\n      } else {\n        query.update({ value: JSON.stringify(result) }).where({ key: 'ee_information' });\n      }\n\n      await query.execute();\n    }\n\n    await commit();\n  } catch (error) {\n    // Example of errors: SQLite does not support FOR UPDATE\n    await rollback();\n  }\n};\n\nconst validateInfo = () => {\n  if (typeof ee.licenseInfo.expireAt === 'undefined') {\n    throw new Error('Missing license key.');\n  }\n\n  const expirationTime = new Date(ee.licenseInfo.expireAt).getTime();\n\n  if (expirationTime < new Date().getTime()) {\n    return disable('License expired.');\n  }\n\n  enable();\n};\n\nconst checkLicense = async ({ strapi }: { strapi: Core.Strapi }) => {\n  const shouldStayOffline =\n    ee.licenseInfo.type === 'gold' &&\n    // This env variable support is temporarily used to ease the migration between online vs offline\n    process.env.STRAPI_DISABLE_LICENSE_PING?.toLowerCase() === 'true';\n\n  if (!shouldStayOffline) {\n    await onlineUpdate({ strapi });\n\n    strapi.cron.add({\n      onlineUpdate: {\n        task: () => onlineUpdate({ strapi }),\n        options: shiftCronExpression('0 0 */12 * * *'),\n      },\n    });\n  } else {\n    if (!ee.licenseInfo.expireAt) {\n      return disable('Your license does not have offline support.');\n    }\n\n    validateInfo();\n  }\n};\n\nconst getTrialEndDate = async ({\n  strapi,\n}: {\n  strapi: Core.Strapi;\n}): Promise<{ trialEndsAt: string } | null> => {\n  const silentFetch = createStrapiFetch(strapi, {\n    logs: false,\n  });\n\n  const res = await silentFetch(\n    `${LICENSE_REGISTRY_URI}/api/licenses/${ee.licenseInfo.licenseKey}/trial-countdown`,\n    {\n      method: 'GET',\n      headers: { 'Content-Type': 'application/json' },\n    }\n  ).catch(() => {\n    throw new LicenseCheckError(\n      'Could not proceed to retrieve the trial time left for your license.',\n      true\n    );\n  });\n\n  const data = await res.json();\n\n  return data;\n};\n\nconst list = () => {\n  return (\n    ee.licenseInfo.features?.map((feature) =>\n      typeof feature === 'object' ? feature : { name: feature }\n    ) || []\n  );\n};\n\nconst get = (featureName: string) => list().find((feature) => feature.name === featureName);\n\nexport default Object.freeze({\n  init,\n  checkLicense,\n  getTrialEndDate,\n\n  get isEE() {\n    return ee.enabled;\n  },\n\n  get seats() {\n    return ee.licenseInfo.seats;\n  },\n\n  get type() {\n    return ee.licenseInfo.type;\n  },\n\n  get isTrial() {\n    return ee.licenseInfo.isTrial;\n  },\n\n  get planPriceId() {\n    return ee.licenseInfo.planPriceId;\n  },\n\n  get subscriptionId() {\n    return ee.licenseInfo.subscriptionId;\n  },\n\n  features: Object.freeze({\n    list,\n    get,\n    isEnabled: (featureName: string) => get(featureName) !== undefined,\n  }),\n});\n"],"names":["ONE_MINUTE","ee","enabled","licenseInfo","isTrial","disable","message","shouldEmitEvent","logger","warn","pick","strapi","eventHub","emit","enable","initialized","init","licenseDir","process","env","STRAPI_DISABLE_EE","toLowerCase","license","STRAPI_LICENSE","readLicense","verifyLicense","error","Error","onlineUpdate","get","commit","rollback","db","transaction","storedInfo","queryBuilder","where","key","select","first","transacting","forUpdate","execute","then","result","JSON","parse","value","shouldContactRegistry","lastCheckAt","Date","now","fallback","LicenseCheckError","shouldFallback","licenseKey","fetchLicense","config","catch","newLicenseInfo","licenseInfoChanged","isEqual","features","seats","type","wasEnabled","validateInfo","query","insert","stringify","update","expireAt","expirationTime","getTime","checkLicense","shouldStayOffline","STRAPI_DISABLE_LICENSE_PING","cron","add","task","options","shiftCronExpression","getTrialEndDate","silentFetch","createStrapiFetch","logs","res","LICENSE_REGISTRY_URI","method","headers","data","json","list","map","feature","name","featureName","find","Object","freeze","isEE","planPriceId","subscriptionId","isEnabled","undefined"],"mappings":"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"}