{"version":3,"file":"license.mjs","sources":["../../src/ee/license.ts"],"sourcesContent":["import fs from 'fs';\nimport { join, resolve } from 'path';\nimport crypto from 'crypto';\nimport type { Strapi } from '@strapi/types';\n\nimport machineId from '../utils/machine-id';\n\ninterface LicenseInfo {\n  type: 'bronze' | 'silver' | 'gold';\n  expireAt?: string;\n  seats?: number;\n  features?: Array<{ name: string; options?: Record<string, unknown> }>;\n}\n\nconst DEFAULT_FEATURES = {\n  bronze: [],\n  silver: [],\n  gold: [\n    { name: 'sso' },\n    // Set a null retention duration to allow the user to override it\n    // The default of 90 days is set in the audit logs service\n    { name: 'audit-logs', options: { retentionDays: null } },\n    { name: 'review-workflows' },\n    { name: 'cms-content-releases' },\n  ],\n};\n\nconst publicKey = fs.readFileSync(resolve(__dirname, '../../resources/key.pub'));\n\nclass LicenseCheckError extends Error {\n  shouldFallback = false;\n\n  constructor(message: string, shouldFallback = false) {\n    super(message);\n\n    this.shouldFallback = shouldFallback;\n  }\n}\n\nconst readLicense = (directory: string) => {\n  try {\n    const path = join(directory, 'license.txt');\n    return fs.readFileSync(path).toString();\n  } catch (error) {\n    if (typeof error === 'object' && error !== null && 'code' in error && error.code !== 'ENOENT') {\n      throw Error('License file not readable, review its format and access rules.');\n    }\n  }\n};\n\nconst verifyLicense = (license: string) => {\n  const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\\n');\n\n  if (!signature || !base64Content) {\n    throw new Error('Invalid license.');\n  }\n\n  const stringifiedContent = Buffer.from(base64Content, 'base64').toString();\n\n  const verify = crypto.createVerify('RSA-SHA256');\n  verify.update(stringifiedContent);\n  verify.end();\n\n  const verified = verify.verify(publicKey, signature, 'base64');\n\n  if (!verified) {\n    throw new Error('Invalid license.');\n  }\n\n  const licenseInfo: LicenseInfo = JSON.parse(stringifiedContent);\n\n  if (!licenseInfo.features) {\n    licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];\n  }\n\n  Object.freeze(licenseInfo.features);\n  return licenseInfo;\n};\n\nconst throwError = () => {\n  throw new LicenseCheckError('Could not proceed to the online validation of your license.', true);\n};\n\nconst fetchLicense = async ({ strapi }: { strapi: Strapi }, key: string, projectId: string) => {\n  const response = await strapi\n    .fetch(`https://license.strapi.io/api/licenses/validate`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ key, projectId, deviceId: machineId() }),\n    })\n    .catch(throwError);\n\n  const contentType = response.headers.get('Content-Type');\n\n  if (contentType?.includes('application/json')) {\n    const { data, error } = await response.json();\n\n    switch (response.status) {\n      case 200:\n        return data.license;\n      case 400:\n        throw new LicenseCheckError(error.message);\n      case 404:\n        throw new LicenseCheckError('The license used does not exists.');\n      default:\n        throwError();\n    }\n  } else {\n    throwError();\n  }\n};\n\nexport { readLicense, verifyLicense, fetchLicense, LicenseCheckError };\n"],"names":[],"mappings":";;;;AAcA,MAAM,mBAAmB;AAAA,EACvB,QAAQ,CAAC;AAAA,EACT,QAAQ,CAAC;AAAA,EACT,MAAM;AAAA,IACJ,EAAE,MAAM,MAAM;AAAA;AAAA;AAAA,IAGd,EAAE,MAAM,cAAc,SAAS,EAAE,eAAe,OAAO;AAAA,IACvD,EAAE,MAAM,mBAAmB;AAAA,IAC3B,EAAE,MAAM,uBAAuB;AAAA,EACjC;AACF;AAEA,MAAM,YAAY,GAAG,aAAa,QAAQ,WAAW,yBAAyB,CAAC;AAE/E,MAAM,0BAA0B,MAAM;AAAA,EACpC,iBAAiB;AAAA,EAEjB,YAAY,SAAiB,iBAAiB,OAAO;AACnD,UAAM,OAAO;AAEb,SAAK,iBAAiB;AAAA,EACxB;AACF;AAEM,MAAA,cAAc,CAAC,cAAsB;AACrC,MAAA;AACI,UAAA,OAAO,KAAK,WAAW,aAAa;AAC1C,WAAO,GAAG,aAAa,IAAI,EAAE,SAAS;AAAA,WAC/B,OAAO;AACV,QAAA,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,MAAM,SAAS,UAAU;AAC7F,YAAM,MAAM,gEAAgE;AAAA,IAC9E;AAAA,EACF;AACF;AAEM,MAAA,gBAAgB,CAAC,YAAoB;AACzC,QAAM,CAAC,WAAW,aAAa,IAAI,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAA,EAAW,MAAM,IAAI;AAEnF,MAAA,CAAC,aAAa,CAAC,eAAe;AAC1B,UAAA,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,QAAM,qBAAqB,OAAO,KAAK,eAAe,QAAQ,EAAE;AAE1D,QAAA,SAAS,OAAO,aAAa,YAAY;AAC/C,SAAO,OAAO,kBAAkB;AAChC,SAAO,IAAI;AAEX,QAAM,WAAW,OAAO,OAAO,WAAW,WAAW,QAAQ;AAE7D,MAAI,CAAC,UAAU;AACP,UAAA,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEM,QAAA,cAA2B,KAAK,MAAM,kBAAkB;AAE1D,MAAA,CAAC,YAAY,UAAU;AACb,gBAAA,WAAW,iBAAiB,YAAY,IAAI;AAAA,EAC1D;AAEO,SAAA,OAAO,YAAY,QAAQ;AAC3B,SAAA;AACT;AAEA,MAAM,aAAa,MAAM;AACjB,QAAA,IAAI,kBAAkB,+DAA+D,IAAI;AACjG;AAEA,MAAM,eAAe,OAAO,EAAE,UAA8B,KAAa,cAAsB;AAC7F,QAAM,WAAW,MAAM,OACpB,MAAM,mDAAmD;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,WAAW,UAAU,UAAU,GAAG;AAAA,EAAA,CAC/D,EACA,MAAM,UAAU;AAEnB,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEnD,MAAA,aAAa,SAAS,kBAAkB,GAAG;AAC7C,UAAM,EAAE,MAAM,MAAA,IAAU,MAAM,SAAS,KAAK;AAE5C,YAAQ,SAAS,QAAQ;AAAA,MACvB,KAAK;AACH,eAAO,KAAK;AAAA,MACd,KAAK;AACG,cAAA,IAAI,kBAAkB,MAAM,OAAO;AAAA,MAC3C,KAAK;AACG,cAAA,IAAI,kBAAkB,mCAAmC;AAAA,MACjE;AACa;IACf;AAAA,EAAA,OACK;AACM;EACb;AACF;"}