From 5b4b95dc4933d8036b55f5b4e6b10249c25fda2e Mon Sep 17 00:00:00 2001 From: Alexandre Bodin Date: Wed, 1 Jul 2020 09:43:28 +0200 Subject: [PATCH] Add check Signed-off-by: Alexandre Bodin --- packages/strapi-admin/.npmignore | 3 +- packages/strapi-admin/index.js | 2 +- packages/strapi-admin/is_ee_env.js | 5 +- packages/strapi-admin/webpack.config.js | 7 ++- packages/strapi/lib/Strapi.js | 3 ++ packages/strapi/lib/core/load-admin.js | 3 +- packages/strapi/lib/utils/ee.js | 54 +++++++++++++++++++++ packages/strapi/lib/utils/resources/key.pub | 9 ++++ 8 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 packages/strapi/lib/utils/ee.js create mode 100644 packages/strapi/lib/utils/resources/key.pub diff --git a/packages/strapi-admin/.npmignore b/packages/strapi-admin/.npmignore index db3ed6c652..6ebf882384 100644 --- a/packages/strapi-admin/.npmignore +++ b/packages/strapi-admin/.npmignore @@ -101,4 +101,5 @@ node_modules test testApp coverage -ee \ No newline at end of file +ee +webpack.config.dev.js \ No newline at end of file diff --git a/packages/strapi-admin/index.js b/packages/strapi-admin/index.js index 7167ea8494..4310a76df1 100644 --- a/packages/strapi-admin/index.js +++ b/packages/strapi-admin/index.js @@ -12,7 +12,7 @@ const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`)) function getCustomWebpackConfig(dir, config) { const adminConfigPath = path.join(dir, 'admin', 'admin.config.js'); - let webpackConfig = getWebpackConfig(config); + let webpackConfig = getWebpackConfig({ dir, ...config }); if (fs.existsSync(adminConfigPath)) { const adminConfig = require(path.resolve(adminConfigPath)); diff --git a/packages/strapi-admin/is_ee_env.js b/packages/strapi-admin/is_ee_env.js index 2906269c0a..e1b57f1302 100644 --- a/packages/strapi-admin/is_ee_env.js +++ b/packages/strapi-admin/is_ee_env.js @@ -4,4 +4,7 @@ const fs = require('fs-extra'); const path = require('path'); const appAdminPath = path.join(__dirname, 'admin'); -module.exports = fs.existsSync(path.join(appAdminPath, 'ee')); +// eslint-disable-next-line node/no-extraneous-require +const hasEE = require('strapi/lib/utils/ee'); + +module.exports = dir => dir && hasEE({ dir }) && fs.existsSync(path.join(appAdminPath, 'ee')); diff --git a/packages/strapi-admin/webpack.config.js b/packages/strapi-admin/webpack.config.js index 3fcab2287d..0c6a312eb6 100644 --- a/packages/strapi-admin/webpack.config.js +++ b/packages/strapi-admin/webpack.config.js @@ -10,13 +10,15 @@ const TerserPlugin = require('terser-webpack-plugin'); const WebpackBar = require('webpackbar'); const isWsl = require('is-wsl'); const alias = require('./webpack.alias.js'); -const IS_EE = require('./is_ee_env'); +const loadEE = require('./is_ee_env'); + // TODO: parametrize const URLs = { mode: 'host', }; module.exports = ({ + dir, entry, dest, env, @@ -26,6 +28,7 @@ module.exports = ({ publicPath: '/admin/', }, }) => { + const isEE = loadEE(dir); const isProduction = env === 'production'; const webpackPlugins = isProduction ? [ @@ -192,7 +195,7 @@ module.exports = ({ const wantedPath = containerPathName.length === 1 ? componentPathName[0] : containerPathName[0]; - if (IS_EE) { + if (isEE) { resource.request = resource.request.replace( /ee_else_ce/, path.join(wantedPath, '..', 'ee') diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index 71f06ca0df..5f2d32a402 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -26,6 +26,7 @@ const { createCoreStore, coreStoreModel } = require('./services/core-store'); const createEntityService = require('./services/entity-service'); const createEntityValidator = require('./services/entity-validator'); const createTelemetry = require('./services/metrics'); +const ee = require('./utils/ee'); /** * Construct an Strapi instance. @@ -50,11 +51,13 @@ class Strapi { }; this.dir = opts.dir || process.cwd(); + this.admin = {}; this.plugins = {}; this.config = loadConfiguration(this.dir, opts); this.isLoaded = false; + this.EE = ee({ dir: this.dir, logger }); // internal services. this.fs = createStrapiFs(this); this.eventHub = createEventHub(); diff --git a/packages/strapi/lib/core/load-admin.js b/packages/strapi/lib/core/load-admin.js index a2cffe0a30..ecd652c6ca 100644 --- a/packages/strapi/lib/core/load-admin.js +++ b/packages/strapi/lib/core/load-admin.js @@ -23,7 +23,8 @@ module.exports = async strapi => { // load ee files if they exist let eeFiles = {}; let eeConfig = {}; - if (process.env.STRAPI_DISABLE_EE !== 'true') { + + if (process.env.STRAPI_DISABLE_EE !== 'true' && strapi.EE) { const eeAdminPath = `${adminPath}/ee`; [eeFiles, eeConfig] = await Promise.all([ loadFiles(eeAdminPath, '!(config|test)/*.*(js|json)'), diff --git a/packages/strapi/lib/utils/ee.js b/packages/strapi/lib/utils/ee.js new file mode 100644 index 0000000000..2f50043eef --- /dev/null +++ b/packages/strapi/lib/utils/ee.js @@ -0,0 +1,54 @@ +const path = require('path'); +const fs = require('fs'); +const crypto = require('crypto'); + +const publicKey = fs.readFileSync(path.join(__dirname, '../utils/resources/key.pub')); + +const defaultLogger = { + warn: console.warn.bind(console), + info: console.log.bind(console), +}; + +module.exports = ({ dir, logger = defaultLogger }) => { + const warnAndReturn = (msg = 'Invalid license. Starting in CE.') => { + logger.warn(msg); + return false; + }; + + const licensePath = path.join(dir, 'license.txt'); + + let license; + if (process.env.STRAPI_LICENSE) { + license = process.env.STRAPI_LICENSE; + } else if (fs.existsSync(licensePath)) { + license = fs.readFileSync(licensePath); + } + + if (!license) return false; + + try { + const plainLicense = Buffer.from(license, 'base64').toString(); + const [signatureb64, contentb64] = plainLicense.split('\n'); + + const signature = Buffer.from(signatureb64, 'base64'); + const content = Buffer.from(contentb64, 'base64').toString(); + + const verifier = crypto.createVerify('RSA-SHA256'); + verifier.update(content); + verifier.end(); + + const isValid = verifier.verify(publicKey, signature); + if (!isValid) return warnAndReturn(); + + const ctx = JSON.parse(content); + + if (ctx.expireAt < new Date().getTime()) { + return warnAndReturn('License expired'); + } + } catch (err) { + return warnAndReturn(); + } + + logger.info('License checked. Starting in EE.'); + return true; +}; diff --git a/packages/strapi/lib/utils/resources/key.pub b/packages/strapi/lib/utils/resources/key.pub new file mode 100644 index 0000000000..ca67c8c397 --- /dev/null +++ b/packages/strapi/lib/utils/resources/key.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApuI1XlPkYos3WsSeVPtS +l1Q2k8GnLEO5vFZ4EuSghMbqI+yE0tWVEaiptdV3KgERaALRXmH+IFrHqvSRjKQC +1ORUarBU5ntWbNEr713R3K0BPOzz9OOoWHdk+Wmr4ViOTk0iD1u4bw/97RpyMoBm ++pXeBLHbEESK2kelk+LEmKUoY5nXp6KzZV5wxgD5QweZheU7mjXL5WMpIBJva8kp +RZMYXEF+uSZIep0q5FHEo2AazGUMAU3GjY/dpXisLmtleOa1xlKZmkvaXl/D2Mhb +BBqPbDMa72ToZg2J8K5UP9zXUP41FHr7o9rwSJ2uOkuZPg5nhDXeoVbrJwxP/U1M +nQIDAQAB +-----END PUBLIC KEY-----