@digicms/cms
Version:
An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite
103 lines (80 loc) • 2.62 kB
JavaScript
;
const fs = require('fs');
const { join } = require('path');
const crypto = require('crypto');
const fetch = require('node-fetch');
const machineId = require('../lib/utils/machine-id');
const DEFAULT_FEATURES = {
bronze: [],
silver: [],
gold: ['sso', { name: 'audit-logs', options: { retentionDays: 90 } }],
};
const publicKey = fs.readFileSync(join(__dirname, 'resources/key.pub'));
class LicenseCheckError extends Error {
constructor(message, shouldFallback = false) {
super(message);
this.shouldFallback = shouldFallback;
}
}
const readLicense = (directory) => {
try {
const path = join(directory, 'license.txt');
return fs.readFileSync(path).toString();
} catch (error) {
if (error.code !== 'ENOENT') {
throw Error('License file not readable, review its format and access rules.');
}
}
};
const verifyLicense = (license) => {
const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\n');
if (!signature || !base64Content) {
throw new Error('Invalid license.');
}
const stringifiedContent = Buffer.from(base64Content, 'base64').toString();
const verify = crypto.createVerify('RSA-SHA256');
verify.update(stringifiedContent);
verify.end();
const verified = verify.verify(publicKey, signature, 'base64');
if (!verified) {
throw new Error('Invalid license.');
}
const licenseInfo = JSON.parse(stringifiedContent);
if (!licenseInfo.features) {
licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];
}
Object.freeze(licenseInfo.features);
return licenseInfo;
};
const throwError = () => {
throw new LicenseCheckError('Could not proceed to the online validation of your license.', true);
};
const fetchLicense = async (key, projectId) => {
const response = await fetch(`https://license.strapi.io/api/licenses/validate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key, projectId, deviceId: machineId() }),
}).catch(throwError);
const contentType = response.headers.get('Content-Type');
if (contentType.includes('application/json')) {
const { data, error } = await response.json();
switch (response.status) {
case 200:
return data.license;
case 400:
throw new LicenseCheckError(error.message);
case 404:
throw new LicenseCheckError('The license used does not exists.');
default:
throwError();
}
} else {
throwError();
}
};
module.exports = Object.freeze({
readLicense,
verifyLicense,
fetchLicense,
LicenseCheckError,
});