"use strict";
/*
 * nodejs-license-file
 * https://github.com/bushev/nodejs-license-file
 *
 * Copyright (c) 2016 Yury Bushev
 * Licensed under the MIT license.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.LicenseFile = void 0;
var fs = require("fs");
var crypto = require("crypto");
var stringify = require("json-stable-stringify");
/**
 * LicenseFile Class
 */
var LicenseFile = /** @class */ (function () {
    function LicenseFile() {
    }
    /**
     *  Generate license file
     *
     * @param options
     * @param options.data {object|string} - data to sign
     * @param options.template - custom license file template
     * @param [options.privateKeyPath] {string} - path to private key
     * @param [options.privateKey] {string} - private key content
     */
    LicenseFile.generate = function (options) {
        var privateKey;
        if (!options.data) {
            throw new Error('LicenseFile::generate: options.data is required');
        }
        if (!options.template) {
            throw new Error('LicenseFile::generate: options.template is required');
        }
        if (typeof options.privateKey === 'string') {
            privateKey = options.privateKey;
        }
        else if (typeof options.privateKeyPath === 'string') {
            privateKey = fs.readFileSync(options.privateKeyPath, 'utf8');
        }
        else {
            throw new Error('LicenseFile::generate: privateKeyPath or privateKey is required');
        }
        var serial = LicenseFile._generateSerial(Object.assign({}, options, { privateKey: privateKey }));
        if (typeof options.data === 'string') {
            options.data = { string: options.data };
        }
        options.data.serial = serial;
        return LicenseFile._render(options.template, LicenseFile._prepareDataObject(options.data));
    };
    /**
     * Parse license file
     *
     * @param options
     * @param options.template - custom license file template
     * @param [options.publicKeyPath] {string} - path to public key
     * @param [options.publicKey] {string} - path to public key
     * @param [options.licenseFilePath] {string} - path to license file
     * @param [options.licenseFile] {string} - license file content
     */
    LicenseFile.parse = function (options) {
        var publicKey;
        var licenseFile;
        if (!options.template) {
            throw new Error('LicenseFile::parse: options.template is required');
        }
        if (typeof options.publicKey === 'string') {
            publicKey = options.publicKey;
        }
        else if (typeof options.publicKeyPath === 'string') {
            publicKey = fs.readFileSync(options.publicKeyPath, 'utf8');
        }
        else {
            throw new Error('LicenseFile::parse: publicKeyPath or publicKey is required');
        }
        if (typeof options.licenseFile === 'string') {
            licenseFile = options.licenseFile;
        }
        else if (typeof options.licenseFilePath === 'string') {
            licenseFile = fs.readFileSync(options.licenseFilePath, 'utf8');
        }
        else {
            throw new Error('LicenseFile::parse: licenseFilePath or licenseFile is required');
        }
        var tokens = [];
        var regExpString = options.template.replace(/{{&(\w+)}}/g, function (match, token) {
            tokens.push(token);
            return '(.*)';
        });
        var result = licenseFile.match(new RegExp(regExpString));
        if (!result) {
            throw new Error("License file corrupted");
        }
        if (result.length - tokens.length !== 1) {
            throw new Error("License file corrupted, tokens expected: " + tokens.length + ", actual: " + (result.length - 1));
        }
        var dataObj = {
            data: {}, serial: ""
        };
        for (var i = 0; i < tokens.length; i++) {
            if (tokens[i] === 'serial') {
                dataObj[tokens[i]] = result[i + 1];
            }
            else {
                dataObj['data'][tokens[i]] = result[i + 1];
            }
        }
        var verify = crypto.createVerify('RSA-SHA256');
        verify.update(stringify(dataObj.data));
        var valid = verify.verify(publicKey, dataObj.serial, 'base64');
        return {
            valid: valid,
            serial: dataObj.serial,
            data: dataObj.data
        };
    };
    /**
     *
     * @param options
     * @param options.data
     * @param options.privateKey
     * @private
     */
    LicenseFile._generateSerial = function (options) {
        var sign = crypto.createSign('RSA-SHA256');
        var data = options.data;
        if (typeof options.data === 'object') {
            data = stringify(LicenseFile._prepareDataObject(options.data));
        }
        sign.update(data);
        return sign.sign(options.privateKey, 'base64');
    };
    LicenseFile._render = function (template, data) {
        for (var property in data) {
            if (data.hasOwnProperty(property)) {
                var regExp = new RegExp("{{&" + property + "}}", "g");
                template = template.replace(regExp, data[property]);
            }
        }
        return template;
    };
    LicenseFile._prepareDataObject = function (data) {
        var result = {};
        for (var property in data) {
            if (data.hasOwnProperty(property)) {
                result[property] = typeof data[property] === 'string' ? data[property] : data[property] + '';
            }
        }
        return result;
    };
    return LicenseFile;
}());
exports.LicenseFile = LicenseFile;
//# sourceMappingURL=license-file.js.map