├── .gitignore ├── LICENSE ├── README.md ├── internal └── HelperMethods.js ├── main.js ├── methods ├── Data.js ├── Helpers.js └── Key.js ├── package-lock.json ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 - 2021 Cryptolens AB and Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cryptolens Client API for NodeJS 2 | 3 | This library contains helper methods to verify licenses in NodeJS. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm add cryptolens 9 | ``` 10 | 11 | ## Example 12 | 13 | ### Key Verification 14 | To verify a license key, you can use the code below. The RSAPublicKey, token and the product id can be found on [this page](https://help.cryptolens.io/examples/key-verification). 15 | 16 | ```js 17 | const key = require('cryptolens').Key; 18 | const Helpers = require('cryptolens').Helpers; 19 | 20 | var RSAPubKey = "Your RSA Public key, which can be found here: https://app.cryptolens.io/User/Security"; 21 | var result = key.Activate(token="Access token with with Activate permission", RSAPubKey, ProductId=3349, Key="GEBNC-WZZJD-VJIHG-GCMVD", MachineCode=Helpers.GetMachineCode()); 22 | 23 | result.then(function(license) { 24 | 25 | // success 26 | 27 | // Please see https://app.cryptolens.io/docs/api/v3/model/LicenseKey for a complete list of parameters. 28 | console.log(license.Created); 29 | 30 | }).catch(function(error) { 31 | // in case of an error, an Error object is returned. 32 | console.log(error.message); 33 | }); 34 | ``` 35 | 36 | ### Offline activation (saving/loading licenses) 37 | Assuming the license key verification was successful, we can save the result in a file so that we can use it instead of contacting Cryptolens. 38 | 39 | First, we need to add the reference to the helper methods: 40 | 41 | ```js 42 | const Helpers = require('cryptolens').Helpers; 43 | ``` 44 | 45 | We can now proceed and save it as a string. 46 | 47 | ```js 48 | var licenseString = Helpers.SaveAsString(license); 49 | ``` 50 | 51 | When loading it back, we can use the code below: 52 | ```js 53 | var license = Helpers.LoadFromString(RSAPubKey, licenseString); 54 | ``` 55 | 56 | If you want to make sure that the license file is not too old, you can specify the maximum number of days as shown below (after 30 days, this method will return null). 57 | ```js 58 | var license = Helpers.LoadFromString(RSAPubKey, licenseString, 30); 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /internal/HelperMethods.js: -------------------------------------------------------------------------------- 1 | const got = require("got"); 2 | module.exports = class HelperMethods { 3 | 4 | /** 5 | * Verify that a response obtained from Key.Activate has not been tampered with. 6 | * @param {object} response 7 | * @param {string} rsaPubKey 8 | */ 9 | static VerifySignature(response, rsaPubKey) { 10 | const NodeRSA = require('node-rsa'); 11 | const key = new NodeRSA(); 12 | const pubKey = HelperMethods.GetPublicKeyParams(rsaPubKey); 13 | key.importKey({ n: pubKey.modulus, e: pubKey.exponent }, 'components-public'); 14 | return key.verify(Buffer.from(this.GetValueCaseInsensitive(response,"licenseKey"), "base64"), Buffer.from(this.GetValueCaseInsensitive(response,"signature"), "base64")); 15 | } 16 | 17 | /** 18 | * Returns a dictionary with the modulus and exponent obtained from an RSA Public key string. 19 | */ 20 | static GetPublicKeyParams(str) { 21 | 22 | const modulus_str = str.substring(str.indexOf('') + 8, str.indexOf('')); 23 | const exponent_str = str.substring(str.indexOf('') + 9, str.indexOf('')); 24 | 25 | return { 26 | modulus: new Buffer.from(modulus_str, 'base64'), 27 | exponent: new Buffer.from(exponent_str, 'base64') 28 | } 29 | } 30 | 31 | static CallAPI(url, formBody) { 32 | return new Promise((resolve, reject) => { 33 | (async () => { 34 | try { 35 | const body = await got.post(url, { 36 | form: formBody 37 | }).json(); 38 | 39 | if (body.result === 1) { 40 | reject(new Error(body.message)); 41 | } else { 42 | resolve(body); 43 | } 44 | } catch(error){ 45 | if (error.name === "HTTPError") { 46 | try { 47 | reject(new Error(JSON.parse(error.response.body).message)); 48 | } catch (e) { 49 | reject(new Error("Could not parse the error message returned from the server. "+ 50 | "If this error persists, please check that the LicenseServerUrl does not end with '/'. "+ 51 | "E.g. 'https://api.cryptolens.io' is correct whereas 'https://api.cryptolens.io/' is not.")); 52 | } 53 | } else { 54 | reject(error); 55 | } 56 | } 57 | })(); 58 | }); 59 | } 60 | 61 | static GetValueCaseInsensitive(obj, key) { 62 | for (var prop in obj) { 63 | if (prop.toLowerCase() === key.toLowerCase()) { 64 | return obj[prop]; 65 | } 66 | } 67 | return undefined; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const key = require('./methods/Key.js'); 2 | const data = require('./methods/Data'); 3 | const helpers = require('./methods/Helpers.js'); 4 | 5 | module.exports = { 6 | Key : key, 7 | Helpers : helpers, 8 | Data: data 9 | } 10 | -------------------------------------------------------------------------------- /methods/Data.js: -------------------------------------------------------------------------------- 1 | const got = require('got'); 2 | const helpers = require('../internal/HelperMethods.js'); 3 | 4 | module.exports = class Key { 5 | 6 | static AddDataObjectToKey(token, ProductId, Key, CheckForDuplicates = false, Name = null, StringValue = null, IntValue= 0, LicenseServerUrl = "https://api.cryptolens.io") { 7 | 8 | return new Promise(async (resolve, reject) => { 9 | try { 10 | const formBody = { 11 | token: token, 12 | productId: ProductId, 13 | key: Key, 14 | checkForDuplicates: CheckForDuplicates, 15 | name: Name, 16 | stringValue: StringValue, 17 | intValue: IntValue, 18 | } 19 | 20 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/data/AddDataObjectToKey`, formBody) 21 | resolve(res.id) 22 | } catch (error) { 23 | reject(error); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /methods/Helpers.js: -------------------------------------------------------------------------------- 1 | const helpers = require('../internal/HelperMethods.js'); 2 | const { execSync } = require("child_process"); 3 | const crypto = require('crypto'); 4 | 5 | 6 | module.exports = class Helpers { 7 | 8 | /** 9 | * Save the license as a string that can later be read by LoadFromString. 10 | * @param {object} licenseKey The license key object to serialize. 11 | */ 12 | static SaveAsString(licenseKey) { 13 | if (licenseKey.RawResponse) { 14 | return JSON.stringify(licenseKey.RawResponse); 15 | } 16 | console.warn("The license key does not have a raw response field."); 17 | return null; 18 | } 19 | 20 | /** 21 | * Loads a license from a string generated by SaveAsString. 22 | * Note: if an error occurs, null will be returned. An error can occur 23 | * if the license string has been tampered with or if the public key is 24 | * incorrectly formatted. 25 | * @param {string} rsaPubKey The RSA Public key 26 | * @param {string} string 27 | * @param {number} SignatureExpirationInterval If the license key was signed, 28 | * this method will check so that no more than "signatureExpirationInterval" 29 | * days have passed since the last activation. 30 | */ 31 | static LoadFromString(rsaPubKey, string, signatureExpirationInterval = 0) { 32 | try { 33 | const response = JSON.parse(string); 34 | 35 | if (helpers.VerifySignature(response, rsaPubKey)) { 36 | const licenseKey = JSON.parse(Buffer.from(helpers.GetValueCaseInsensitive(response,"licenseKey"), 'base64').toString("utf-8")); 37 | const signed = new Date(licenseKey.SignDate * 1000); 38 | const exp = new Date(signed.getFullYear(), signed.getMonth(), signed.getDate() + signatureExpirationInterval); 39 | if (signatureExpirationInterval > 0 && new Date() > exp) { 40 | console.warn("The license has expired."); 41 | return null; 42 | } 43 | licenseKey.RawResponse = response; 44 | return licenseKey; 45 | } 46 | return null; 47 | } catch (error) { 48 | return null; 49 | } 50 | } 51 | 52 | 53 | /** 54 | * Returns a machine code of the current device. 55 | */ 56 | static GetMachineCode() { 57 | 58 | let res = ""; 59 | 60 | if (process.platform === "win32") { 61 | res = (execSync('cmd /c powershell.exe -Command "(Get-CimInstance -Class Win32_ComputerSystemProduct).UUID"', { encoding: 'utf8' })); 62 | res = res.substring(res.indexOf("UUID")).trim(); 63 | } else if (process.platform === "linux") { 64 | res = (execSync("findmnt --output=UUID --noheadings --target=/boot", { encoding: 'utf8' })); 65 | } else if (process.platform === "darwin") { 66 | res = (execSync("system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }'", { encoding: 'utf8' })); 67 | } 68 | 69 | return crypto.createHash('sha256').update(res).digest('hex'); 70 | } 71 | 72 | /** 73 | * Compute a shorter version of the machine code that is more easily to type for end users. 74 | * Note, please use the corresponding Helpers.IsOnRightMachineShort method instead, when verifying 75 | * if a license has been activated on this machine. 76 | */ 77 | static GetMachineCodeShort() { 78 | return this.GetMachineCode().slice(0, 20); 79 | } 80 | 81 | /** 82 | * Check if the current license has expired. 83 | * @param licenseKey a license key object. 84 | * @return True if it has expired and false otherwise. 85 | */ 86 | static HasExpired(licenseKey) { 87 | if (licenseKey == null) { 88 | return false; 89 | } 90 | 91 | let unixTime = new Date() / 1000; 92 | 93 | if (licenseKey.Expires < unixTime) { 94 | return true; 95 | } 96 | 97 | return false; 98 | } 99 | 100 | /** 101 | * Check if the current license has not expired. 102 | * @param licenseKey a license key object. 103 | * @return True if it has not expired and false otherwise. 104 | */ 105 | static HasNotExpired(licenseKey) { 106 | return !Helpers.HasExpired(licenseKey); 107 | } 108 | 109 | 110 | /** 111 | * Check if the license has a certain feature enabled (i.e. set to true). If the feature parameter is an integer, then 112 | * this method will check against the 8 built in feature flags (F1..F8). If feature parameter is a string, the method 113 | * will use a built in data object to determine if a certain feature exists. Below is more information about that: 114 | * 115 | * Formatting: The name of the data object should be 'cryptolens_features' and it should be structured as a JSON array. 116 | * 117 | * For example,
["f1", "f2"]

means f1 and f2 are true. You can also have feature bundling, eg.

["f1", ["f2",["voice","image"]]]
118 | * which means that f1 and f2 are true, as well as f2.voice and f2.image. You can set any depth, eg. you can have 119 | *
["f1", ["f2",[["voice",["all"]], "image"]]]
means f2.voice.all is true as well as f2.voice and f2. 120 | * The dots symbol is used to specify the "sub-features". 121 | 122 | * Read more here: https://help.cryptolens.io/web-interface/feature-templates 123 | * 124 | * @param licenseKey a license key object. 125 | * @param feature The feature, eg 1 to 8. 126 | * @return If the feature is set to true, true is returned and false otherwise. 127 | */ 128 | static HasFeature(licenseKey, feature) { 129 | 130 | if (licenseKey == null) { 131 | return false; 132 | } 133 | 134 | if (!isNaN(feature)) { 135 | if (feature === 1 && licenseKey.F1) 136 | return true; 137 | if (feature === 2 && licenseKey.F2) 138 | return true; 139 | if (feature === 3 && licenseKey.F3) 140 | return true; 141 | if (feature === 4 && licenseKey.F4) 142 | return true; 143 | if (feature === 5 && licenseKey.F5) 144 | return true; 145 | if (feature === 6 && licenseKey.F6) 146 | return true; 147 | if (feature === 7 && licenseKey.F7) 148 | return true; 149 | if (feature === 8 && licenseKey.F8) 150 | return true; 151 | 152 | return false; 153 | } 154 | 155 | if (!licenseKey["DataObjects"]) { 156 | return false; 157 | } 158 | 159 | var features = null; 160 | 161 | for(const dobj of licenseKey["DataObjects"] ) { 162 | if(dobj["Name"] == 'cryptolens_features') { 163 | features = dobj["StringValue"]; 164 | break; 165 | } 166 | } 167 | 168 | if (features == null || feature.trim() == "") { 169 | return false; 170 | } 171 | 172 | var array = JSON.parse(features); 173 | 174 | var featurePath = feature.split("\."); 175 | 176 | var found = false; 177 | 178 | for (let i = 0; i < featurePath.length; i++) { 179 | found = false; 180 | 181 | var index = -1; 182 | 183 | for (let j = 0; j < array.length; j++) { 184 | 185 | if (!Array.isArray(array[j]) && array[j]==featurePath[i]) { 186 | found = true; 187 | break; 188 | } else if(Array.isArray(array[j]) && array[j][0] == featurePath[i]) { 189 | found = true; 190 | index = j; 191 | break; 192 | } 193 | } 194 | if(!found) { 195 | return false; 196 | } 197 | 198 | if(i+1 < featurePath.length && index != -1) { 199 | array = array[index][1]; 200 | } 201 | 202 | } 203 | 204 | if(!found){ 205 | return false; 206 | } 207 | 208 | return true; 209 | } 210 | 211 | 212 | 213 | /** 214 | * Check if the device is registered with the license key. 215 | * @param license The license key object. 216 | * @param isFloatingLicense If this is a floating license, this parameter has to be set to true. 217 | * You can enable floating licenses by setting @see ActivateModel.FloatingTimeInterval. 218 | * @param allowOverdraft If floating licensing is enabled with overdraft, this parameter should be set to true. 219 | * You can enable overdraft by setting ActivateModel.MaxOverdraft" to a value greater than 0. 220 | * 221 | * @return True if the license is registered with this machine and False otherwise. 222 | */ 223 | static IsOnRightMachine(license, isFloatingLicense, allowOverdraft) { 224 | return this.IsOnRightMachineCustom(license, this.GetMachineCode(), isFloatingLicense, allowOverdraft); 225 | } 226 | 227 | /** 228 | * Check if the device is registered with the license key. This method uses a shorter version of the machine code, 229 | * computed using Helpers.GetMachineCodeShort. 230 | * @param license The license key object. 231 | * @param isFloatingLicense If this is a floating license, this parameter has to be set to true. 232 | * You can enable floating licenses by setting @see ActivateModel.FloatingTimeInterval. 233 | * @param allowOverdraft If floating licensing is enabled with overdraft, this parameter should be set to true. 234 | * You can enable overdraft by setting ActivateModel.MaxOverdraft" to a value greater than 0. 235 | * 236 | * @return True if the license is registered with this machine and False otherwise. 237 | */ 238 | static IsOnRightMachineShort(license, isFloatingLicense, allowOverdraft) { 239 | return this.IsOnRightMachineCustom(license, this.GetMachineCodeShort(), isFloatingLicense, allowOverdraft); 240 | } 241 | 242 | /** 243 | * Check if the device is registered with the license key. This method allows you to pass in a custom machine code. 244 | * @param license The license key object. 245 | * @param machineCode The machine code of the current device. 246 | * @param isFloatingLicense If this is a floating license, this parameter has to be set to true. 247 | * You can enable floating licenses by setting @see ActivateModel.FloatingTimeInterval. 248 | * @param allowOverdraft If floating licensing is enabled with overdraft, this parameter should be set to true. 249 | * You can enable overdraft by setting ActivateModel.MaxOverdraft" to a value greater than 0. 250 | * 251 | * @return True if the license is registered with this machine and False otherwise. 252 | */ 253 | static IsOnRightMachineCustom(license, machineCode, isFloatingLicense, allowOverdraft) { 254 | 255 | if (license == null || license.ActivatedMachines == null) { 256 | return false; 257 | } 258 | 259 | if (machineCode == null) { 260 | machineCode = this.GetMachineCode(); 261 | } 262 | 263 | let res = false; 264 | 265 | console.log(isFloatingLicense); 266 | 267 | if (isFloatingLicense) { 268 | console.log("floating"); 269 | license.ActivatedMachines.forEach(machine => { 270 | if (machine.Mid.length >= 9 && machine.Mid.substring(9) === machineCode || 271 | allowOverdraft && machine.Mid.length >= 19 && machine.Mid.substring(19) === machineCode) { 272 | res = true; 273 | } 274 | }) 275 | } else { 276 | 277 | license.ActivatedMachines.forEach(machine => { 278 | if (machine.Mid === machineCode) { 279 | res = true; 280 | } 281 | }); 282 | } 283 | return res; 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /methods/Key.js: -------------------------------------------------------------------------------- 1 | const got = require('got'); 2 | const helpers = require('../internal/HelperMethods.js'); 3 | 4 | module.exports = class Key { 5 | 6 | static Activate(token, rsaPubKey, ProductId, Key, MachineCode = "", FriendlyName = "", FieldsToReturn = 0, Metadata = false, FloatingTimeInterval = 0, MaxOverdraft = 0, LicenseServerUrl = "https://api.cryptolens.io") { 7 | return new Promise(async (resolve, reject) => { 8 | try { 9 | const formBody = { 10 | token: token, 11 | ProductId: ProductId, 12 | Key: Key, 13 | MachineCode: MachineCode, 14 | FriendlyName: FriendlyName, 15 | FieldsToReturn: FieldsToReturn, 16 | Metadata: Metadata, 17 | FloatingTimeInterval: FloatingTimeInterval, 18 | MaxOverdraft: MaxOverdraft, 19 | Sign: true, 20 | SignMethod: 1 21 | } 22 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/Activate`, formBody) 23 | 24 | if (helpers.VerifySignature(res, rsaPubKey)) { 25 | const license = JSON.parse(Buffer.from(helpers.GetValueCaseInsensitive(res,"licenseKey"), "base64").toString("utf-8")); 26 | license.RawResponse = res; 27 | resolve(license); 28 | } else { 29 | reject(new Error("Signature verification failed.")); 30 | } 31 | } catch (error) { 32 | reject(error); 33 | } 34 | }); 35 | } 36 | 37 | static Deactivate(token, ProductId, Key, MachineCode = "", Floating = false, OSInfo = null, LicenseServerUrl = "https://api.cryptolens.io") { 38 | return new Promise(async (resolve, reject) => { 39 | try { 40 | const formBody = { 41 | token: token, 42 | ProductId: ProductId, 43 | Key: Key, 44 | MachineCode: MachineCode, 45 | Floating: Floating, 46 | OSInfo: OSInfo 47 | } 48 | 49 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/Deactivate`, formBody) 50 | resolve(res.message) 51 | } catch (error) { 52 | reject(error); 53 | } 54 | }); 55 | } 56 | 57 | static GetKey(token, rsaPubKey, ProductId, Key, FieldsToReturn = 0, Metadata = false, LicenseServerUrl = "https://api.cryptolens.io") { 58 | 59 | return new Promise((resolve, reject) => { 60 | (async () => { 61 | try { 62 | const body = await got.post(`${LicenseServerUrl}/api/key/GetKey`, { 63 | form: { 64 | token: token, 65 | ProductId: ProductId, 66 | Key: Key, 67 | FieldsToReturn: FieldsToReturn, 68 | Metadata: Metadata, 69 | Sign: true, 70 | SignMethod: 1 71 | } 72 | }).json(); 73 | 74 | if (body.result === "1") { 75 | reject(new Error(body.message)); 76 | } else { 77 | if (helpers.VerifySignature(body, rsaPubKey)) { 78 | const license = JSON.parse(Buffer.from(helpers.GetValueCaseInsensitive(body,"licenseKey"), "base64").toString("utf-8")); 79 | license.RawResponse = body; 80 | resolve(license); 81 | } else { 82 | reject(new Error("Signature verification failed.")); 83 | } 84 | } 85 | } catch (error) { 86 | if (error.name === "HTTPError") { 87 | reject(new Error(JSON.parse(error.response.body).message)); 88 | } else { 89 | reject(error); 90 | } 91 | } 92 | })(); 93 | }); 94 | } 95 | 96 | static CreateKeyFromTemplate(token, LicenseTemplateId, LicenseServerUrl = "https://api.cryptolens.io") { 97 | return new Promise(async (resolve, reject) => { 98 | try { 99 | const formBody = { 100 | token: token, 101 | LicenseTemplateId: LicenseTemplateId 102 | } 103 | 104 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/CreateKeyFromTemplate`, formBody) 105 | resolve(res.key) 106 | } catch (error) { 107 | reject(error); 108 | } 109 | }); 110 | } 111 | 112 | static CreateTrialKey(token, ProductId, MachineCode = "", LicenseServerUrl = "https://api.cryptolens.io") { 113 | return new Promise(async (resolve, reject) => { 114 | try { 115 | const body = await got 116 | .post(`${LicenseServerUrl}/api/key/CreateTrialKey`, { 117 | form: { 118 | token: token, 119 | ProductId: ProductId, 120 | MachineCode: MachineCode, 121 | }, 122 | }) 123 | .json(); 124 | console.log(body); 125 | if (body.result == "1") { 126 | console.warn(body.message); 127 | resolve(null); 128 | } else { 129 | console.warn(body.message); 130 | resolve(body.key); 131 | } 132 | } catch (error) { 133 | reject(error); 134 | } 135 | }); 136 | } 137 | 138 | static CreateKey( 139 | token, 140 | ProductId, 141 | Period, 142 | Notes = "", 143 | Block = false, 144 | CustomerId = null, 145 | TrialActivation = false, 146 | MaxNoOfMachines = 0, 147 | AllowedMachines = null, 148 | ResellerId = 0, 149 | NoOfKeys = 1, 150 | F1 = false, 151 | F2 = false, 152 | F3 = false, 153 | F4 = false, 154 | F5 = false, 155 | F6 = false, 156 | F7 = false, 157 | F8 = false, 158 | NewCustomer = false, 159 | AddOrUseExistingCustomer = false, 160 | LicenseServerUrl = "https://api.cryptolens.io" 161 | ) { 162 | return new Promise((resolve, reject) => { 163 | (async () => { 164 | try { 165 | const body = await got 166 | .post(`${LicenseServerUrl}/api/key/CreateKey`, { 167 | form: { 168 | token: token, 169 | ProductId: ProductId, 170 | Period: Period, 171 | Notes: Notes, 172 | Block: Block, 173 | CustomerId: CustomerId, 174 | TrialActivation: TrialActivation, 175 | MaxNoOfMachines: MaxNoOfMachines, 176 | AllowedMachines: AllowedMachines, 177 | ResellerId: ResellerId, 178 | NoOfKeys: NoOfKeys, 179 | F1: F1, 180 | F2: F2, 181 | F3: F3, 182 | F4: F4, 183 | F5: F5, 184 | F6: F6, 185 | F7: F7, 186 | F8: F8, 187 | NewCustomer : NewCustomer, 188 | AddOrUseExistingCustomer : AddOrUseExistingCustomer 189 | }, 190 | }) 191 | .json(); 192 | 193 | if (body.result == "1") { 194 | console.warn(body.message); 195 | resolve(null); 196 | } else { 197 | console.warn(body.message); 198 | resolve(body); 199 | } 200 | } catch (error) { 201 | reject(error); 202 | } 203 | })(); 204 | }); 205 | } 206 | 207 | 208 | static ExtendLicense(token, ProductId, Key, NoOfDays = 0, LicenseServerUrl = "https://api.cryptolens.io") { 209 | return new Promise(async (resolve, reject) => { 210 | try { 211 | const formBody = { 212 | token: token, 213 | productId: ProductId, 214 | key: Key, 215 | noOfDays: NoOfDays 216 | } 217 | 218 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/ExtendLicense`, formBody) 219 | resolve(res) 220 | } catch (error) { 221 | reject(error); 222 | } 223 | }); 224 | } 225 | 226 | static AddFeature(token, ProductId, Key, Feature, LicenseServerUrl = "https://api.cryptolens.io") { 227 | return new Promise(async (resolve, reject) => { 228 | try { 229 | const formBody = { 230 | token: token, 231 | productId: ProductId, 232 | key: Key, 233 | feature: Feature 234 | } 235 | 236 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/AddFeature`, formBody) 237 | resolve(res) 238 | } catch (error) { 239 | reject(error); 240 | } 241 | }); 242 | } 243 | 244 | static RemoveFeature(token, ProductId, Key, Feature, LicenseServerUrl = "https://api.cryptolens.io") { 245 | return new Promise(async (resolve, reject) => { 246 | try { 247 | const formBody = { 248 | token: token, 249 | productId: ProductId, 250 | key: Key, 251 | feature: Feature 252 | } 253 | 254 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/RemoveFeature`, formBody) 255 | resolve(res) 256 | } catch (error) { 257 | reject(error); 258 | } 259 | }); 260 | } 261 | 262 | static ChangeNotes(token, ProductId, Key, Notes, LicenseServerUrl = "https://api.cryptolens.io") { 263 | return new Promise(async (resolve, reject) => { 264 | try { 265 | const formBody = { 266 | token: token, 267 | productId: ProductId, 268 | key: Key, 269 | notes: Notes 270 | } 271 | 272 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/ChangeNotes`, formBody) 273 | resolve(res) 274 | } catch (error) { 275 | reject(error); 276 | } 277 | }); 278 | } 279 | 280 | static BlockKey(token, ProductId, Key, LicenseServerUrl = "https://api.cryptolens.io") { 281 | return new Promise(async (resolve, reject) => { 282 | try { 283 | const formBody = { 284 | token: token, 285 | productId: ProductId, 286 | key: Key, 287 | } 288 | 289 | const res = await helpers.CallAPI(`${LicenseServerUrl}/api/key/BlockKey`, formBody) 290 | resolve(res) 291 | } catch (error) { 292 | reject(error); 293 | } 294 | }); 295 | } 296 | 297 | } 298 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptolens", 3 | "version": "1.0.11", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "cryptolens", 9 | "version": "1.0.9", 10 | "license": "MIT", 11 | "dependencies": { 12 | "got": "11.8.5", 13 | "node-rsa": "^1.1.1" 14 | } 15 | }, 16 | "node_modules/@sindresorhus/is": { 17 | "version": "4.6.0", 18 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 19 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 20 | "engines": { 21 | "node": ">=10" 22 | }, 23 | "funding": { 24 | "url": "https://github.com/sindresorhus/is?sponsor=1" 25 | } 26 | }, 27 | "node_modules/@szmarczak/http-timer": { 28 | "version": "4.0.6", 29 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 30 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 31 | "dependencies": { 32 | "defer-to-connect": "^2.0.0" 33 | }, 34 | "engines": { 35 | "node": ">=10" 36 | } 37 | }, 38 | "node_modules/@types/cacheable-request": { 39 | "version": "6.0.2", 40 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 41 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 42 | "dependencies": { 43 | "@types/http-cache-semantics": "*", 44 | "@types/keyv": "*", 45 | "@types/node": "*", 46 | "@types/responselike": "*" 47 | } 48 | }, 49 | "node_modules/@types/http-cache-semantics": { 50 | "version": "4.0.1", 51 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 52 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" 53 | }, 54 | "node_modules/@types/json-buffer": { 55 | "version": "3.0.0", 56 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 57 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" 58 | }, 59 | "node_modules/@types/keyv": { 60 | "version": "3.1.4", 61 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 62 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 63 | "dependencies": { 64 | "@types/node": "*" 65 | } 66 | }, 67 | "node_modules/@types/node": { 68 | "version": "17.0.29", 69 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", 70 | "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" 71 | }, 72 | "node_modules/@types/responselike": { 73 | "version": "1.0.0", 74 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 75 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 76 | "dependencies": { 77 | "@types/node": "*" 78 | } 79 | }, 80 | "node_modules/asn1": { 81 | "version": "0.2.6", 82 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", 83 | "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", 84 | "dependencies": { 85 | "safer-buffer": "~2.1.0" 86 | } 87 | }, 88 | "node_modules/cacheable-lookup": { 89 | "version": "5.0.4", 90 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 91 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", 92 | "engines": { 93 | "node": ">=10.6.0" 94 | } 95 | }, 96 | "node_modules/cacheable-request": { 97 | "version": "7.0.2", 98 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 99 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 100 | "dependencies": { 101 | "clone-response": "^1.0.2", 102 | "get-stream": "^5.1.0", 103 | "http-cache-semantics": "^4.0.0", 104 | "keyv": "^4.0.0", 105 | "lowercase-keys": "^2.0.0", 106 | "normalize-url": "^6.0.1", 107 | "responselike": "^2.0.0" 108 | }, 109 | "engines": { 110 | "node": ">=8" 111 | } 112 | }, 113 | "node_modules/clone-response": { 114 | "version": "1.0.2", 115 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 116 | "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", 117 | "dependencies": { 118 | "mimic-response": "^1.0.0" 119 | } 120 | }, 121 | "node_modules/compress-brotli": { 122 | "version": "1.3.6", 123 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", 124 | "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", 125 | "dependencies": { 126 | "@types/json-buffer": "~3.0.0", 127 | "json-buffer": "~3.0.1" 128 | }, 129 | "engines": { 130 | "node": ">= 12" 131 | } 132 | }, 133 | "node_modules/decompress-response": { 134 | "version": "6.0.0", 135 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 136 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 137 | "dependencies": { 138 | "mimic-response": "^3.1.0" 139 | }, 140 | "engines": { 141 | "node": ">=10" 142 | }, 143 | "funding": { 144 | "url": "https://github.com/sponsors/sindresorhus" 145 | } 146 | }, 147 | "node_modules/decompress-response/node_modules/mimic-response": { 148 | "version": "3.1.0", 149 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 150 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 151 | "engines": { 152 | "node": ">=10" 153 | }, 154 | "funding": { 155 | "url": "https://github.com/sponsors/sindresorhus" 156 | } 157 | }, 158 | "node_modules/defer-to-connect": { 159 | "version": "2.0.1", 160 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 161 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 162 | "engines": { 163 | "node": ">=10" 164 | } 165 | }, 166 | "node_modules/end-of-stream": { 167 | "version": "1.4.4", 168 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 169 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 170 | "dependencies": { 171 | "once": "^1.4.0" 172 | } 173 | }, 174 | "node_modules/get-stream": { 175 | "version": "5.2.0", 176 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 177 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 178 | "dependencies": { 179 | "pump": "^3.0.0" 180 | }, 181 | "engines": { 182 | "node": ">=8" 183 | }, 184 | "funding": { 185 | "url": "https://github.com/sponsors/sindresorhus" 186 | } 187 | }, 188 | "node_modules/got": { 189 | "version": "11.8.5", 190 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 191 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 192 | "dependencies": { 193 | "@sindresorhus/is": "^4.0.0", 194 | "@szmarczak/http-timer": "^4.0.5", 195 | "@types/cacheable-request": "^6.0.1", 196 | "@types/responselike": "^1.0.0", 197 | "cacheable-lookup": "^5.0.3", 198 | "cacheable-request": "^7.0.2", 199 | "decompress-response": "^6.0.0", 200 | "http2-wrapper": "^1.0.0-beta.5.2", 201 | "lowercase-keys": "^2.0.0", 202 | "p-cancelable": "^2.0.0", 203 | "responselike": "^2.0.0" 204 | }, 205 | "engines": { 206 | "node": ">=10.19.0" 207 | }, 208 | "funding": { 209 | "url": "https://github.com/sindresorhus/got?sponsor=1" 210 | } 211 | }, 212 | "node_modules/http-cache-semantics": { 213 | "version": "4.1.0", 214 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 215 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 216 | }, 217 | "node_modules/http2-wrapper": { 218 | "version": "1.0.3", 219 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 220 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 221 | "dependencies": { 222 | "quick-lru": "^5.1.1", 223 | "resolve-alpn": "^1.0.0" 224 | }, 225 | "engines": { 226 | "node": ">=10.19.0" 227 | } 228 | }, 229 | "node_modules/json-buffer": { 230 | "version": "3.0.1", 231 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 232 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 233 | }, 234 | "node_modules/keyv": { 235 | "version": "4.2.2", 236 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", 237 | "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", 238 | "dependencies": { 239 | "compress-brotli": "^1.3.6", 240 | "json-buffer": "3.0.1" 241 | } 242 | }, 243 | "node_modules/lowercase-keys": { 244 | "version": "2.0.0", 245 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 246 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 247 | "engines": { 248 | "node": ">=8" 249 | } 250 | }, 251 | "node_modules/mimic-response": { 252 | "version": "1.0.1", 253 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 254 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 255 | "engines": { 256 | "node": ">=4" 257 | } 258 | }, 259 | "node_modules/node-rsa": { 260 | "version": "1.1.1", 261 | "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", 262 | "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", 263 | "dependencies": { 264 | "asn1": "^0.2.4" 265 | } 266 | }, 267 | "node_modules/normalize-url": { 268 | "version": "6.1.0", 269 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 270 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 271 | "engines": { 272 | "node": ">=10" 273 | }, 274 | "funding": { 275 | "url": "https://github.com/sponsors/sindresorhus" 276 | } 277 | }, 278 | "node_modules/once": { 279 | "version": "1.4.0", 280 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 281 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 282 | "dependencies": { 283 | "wrappy": "1" 284 | } 285 | }, 286 | "node_modules/p-cancelable": { 287 | "version": "2.1.1", 288 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 289 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", 290 | "engines": { 291 | "node": ">=8" 292 | } 293 | }, 294 | "node_modules/pump": { 295 | "version": "3.0.0", 296 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 297 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 298 | "dependencies": { 299 | "end-of-stream": "^1.1.0", 300 | "once": "^1.3.1" 301 | } 302 | }, 303 | "node_modules/quick-lru": { 304 | "version": "5.1.1", 305 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 306 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 307 | "engines": { 308 | "node": ">=10" 309 | }, 310 | "funding": { 311 | "url": "https://github.com/sponsors/sindresorhus" 312 | } 313 | }, 314 | "node_modules/resolve-alpn": { 315 | "version": "1.2.1", 316 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 317 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 318 | }, 319 | "node_modules/responselike": { 320 | "version": "2.0.0", 321 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", 322 | "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", 323 | "dependencies": { 324 | "lowercase-keys": "^2.0.0" 325 | } 326 | }, 327 | "node_modules/safer-buffer": { 328 | "version": "2.1.2", 329 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 330 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 331 | }, 332 | "node_modules/wrappy": { 333 | "version": "1.0.2", 334 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 335 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 336 | } 337 | }, 338 | "dependencies": { 339 | "@sindresorhus/is": { 340 | "version": "4.6.0", 341 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 342 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" 343 | }, 344 | "@szmarczak/http-timer": { 345 | "version": "4.0.6", 346 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 347 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 348 | "requires": { 349 | "defer-to-connect": "^2.0.0" 350 | } 351 | }, 352 | "@types/cacheable-request": { 353 | "version": "6.0.2", 354 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 355 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 356 | "requires": { 357 | "@types/http-cache-semantics": "*", 358 | "@types/keyv": "*", 359 | "@types/node": "*", 360 | "@types/responselike": "*" 361 | } 362 | }, 363 | "@types/http-cache-semantics": { 364 | "version": "4.0.1", 365 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 366 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" 367 | }, 368 | "@types/json-buffer": { 369 | "version": "3.0.0", 370 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 371 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" 372 | }, 373 | "@types/keyv": { 374 | "version": "3.1.4", 375 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 376 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 377 | "requires": { 378 | "@types/node": "*" 379 | } 380 | }, 381 | "@types/node": { 382 | "version": "17.0.29", 383 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", 384 | "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" 385 | }, 386 | "@types/responselike": { 387 | "version": "1.0.0", 388 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 389 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 390 | "requires": { 391 | "@types/node": "*" 392 | } 393 | }, 394 | "asn1": { 395 | "version": "0.2.6", 396 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", 397 | "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", 398 | "requires": { 399 | "safer-buffer": "~2.1.0" 400 | } 401 | }, 402 | "cacheable-lookup": { 403 | "version": "5.0.4", 404 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 405 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" 406 | }, 407 | "cacheable-request": { 408 | "version": "7.0.2", 409 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 410 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 411 | "requires": { 412 | "clone-response": "^1.0.2", 413 | "get-stream": "^5.1.0", 414 | "http-cache-semantics": "^4.0.0", 415 | "keyv": "^4.0.0", 416 | "lowercase-keys": "^2.0.0", 417 | "normalize-url": "^6.0.1", 418 | "responselike": "^2.0.0" 419 | } 420 | }, 421 | "clone-response": { 422 | "version": "1.0.2", 423 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 424 | "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", 425 | "requires": { 426 | "mimic-response": "^1.0.0" 427 | } 428 | }, 429 | "compress-brotli": { 430 | "version": "1.3.6", 431 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", 432 | "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", 433 | "requires": { 434 | "@types/json-buffer": "~3.0.0", 435 | "json-buffer": "~3.0.1" 436 | } 437 | }, 438 | "decompress-response": { 439 | "version": "6.0.0", 440 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 441 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 442 | "requires": { 443 | "mimic-response": "^3.1.0" 444 | }, 445 | "dependencies": { 446 | "mimic-response": { 447 | "version": "3.1.0", 448 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 449 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" 450 | } 451 | } 452 | }, 453 | "defer-to-connect": { 454 | "version": "2.0.1", 455 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 456 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" 457 | }, 458 | "end-of-stream": { 459 | "version": "1.4.4", 460 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 461 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 462 | "requires": { 463 | "once": "^1.4.0" 464 | } 465 | }, 466 | "get-stream": { 467 | "version": "5.2.0", 468 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 469 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 470 | "requires": { 471 | "pump": "^3.0.0" 472 | } 473 | }, 474 | "got": { 475 | "version": "11.8.5", 476 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 477 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 478 | "requires": { 479 | "@sindresorhus/is": "^4.0.0", 480 | "@szmarczak/http-timer": "^4.0.5", 481 | "@types/cacheable-request": "^6.0.1", 482 | "@types/responselike": "^1.0.0", 483 | "cacheable-lookup": "^5.0.3", 484 | "cacheable-request": "^7.0.2", 485 | "decompress-response": "^6.0.0", 486 | "http2-wrapper": "^1.0.0-beta.5.2", 487 | "lowercase-keys": "^2.0.0", 488 | "p-cancelable": "^2.0.0", 489 | "responselike": "^2.0.0" 490 | } 491 | }, 492 | "http-cache-semantics": { 493 | "version": "4.1.0", 494 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 495 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 496 | }, 497 | "http2-wrapper": { 498 | "version": "1.0.3", 499 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 500 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 501 | "requires": { 502 | "quick-lru": "^5.1.1", 503 | "resolve-alpn": "^1.0.0" 504 | } 505 | }, 506 | "json-buffer": { 507 | "version": "3.0.1", 508 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 509 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 510 | }, 511 | "keyv": { 512 | "version": "4.2.2", 513 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", 514 | "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", 515 | "requires": { 516 | "compress-brotli": "^1.3.6", 517 | "json-buffer": "3.0.1" 518 | } 519 | }, 520 | "lowercase-keys": { 521 | "version": "2.0.0", 522 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 523 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" 524 | }, 525 | "mimic-response": { 526 | "version": "1.0.1", 527 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 528 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" 529 | }, 530 | "node-rsa": { 531 | "version": "1.1.1", 532 | "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", 533 | "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", 534 | "requires": { 535 | "asn1": "^0.2.4" 536 | } 537 | }, 538 | "normalize-url": { 539 | "version": "6.1.0", 540 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 541 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" 542 | }, 543 | "once": { 544 | "version": "1.4.0", 545 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 546 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 547 | "requires": { 548 | "wrappy": "1" 549 | } 550 | }, 551 | "p-cancelable": { 552 | "version": "2.1.1", 553 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 554 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" 555 | }, 556 | "pump": { 557 | "version": "3.0.0", 558 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 559 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 560 | "requires": { 561 | "end-of-stream": "^1.1.0", 562 | "once": "^1.3.1" 563 | } 564 | }, 565 | "quick-lru": { 566 | "version": "5.1.1", 567 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 568 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" 569 | }, 570 | "resolve-alpn": { 571 | "version": "1.2.1", 572 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 573 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 574 | }, 575 | "responselike": { 576 | "version": "2.0.0", 577 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", 578 | "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", 579 | "requires": { 580 | "lowercase-keys": "^2.0.0" 581 | } 582 | }, 583 | "safer-buffer": { 584 | "version": "2.1.2", 585 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 586 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 587 | }, 588 | "wrappy": { 589 | "version": "1.0.2", 590 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 591 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 592 | } 593 | } 594 | } 595 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptolens", 3 | "version": "1.0.15.1", 4 | "description": "Client API for NodeJS to access Cryptolens Software Licensing API.", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Cryptolens/cryptolens-nodejs.git" 12 | }, 13 | "keywords": [ 14 | "licensing as a service", 15 | "licensing library", 16 | "licensing", 17 | "cryptolens", 18 | "software licensing" 19 | ], 20 | "author": "Cryptolens AB", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/Cryptolens/cryptolens-nodejs/issues" 24 | }, 25 | "homepage": "https://github.com/Cryptolens/cryptolens-nodejs#readme", 26 | "dependencies": { 27 | "got": "11.8.5", 28 | "node-rsa": "^1.1.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var key = require("./methods/Key.js") 2 | const Helpers = require('./methods/Helpers.js'); 3 | 4 | //var RSAPubKey = "sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==AQAB"; 5 | 6 | //var result = Key.Activate(token="", RSAPubKey, ProductId=3349, Key="GEBNC-WZZJD-VJIHG-GCMVD", MachineCode="test"); 7 | //result.then((s)=> console.log(Helpers.LoadFromString(RSAPubKey, Helpers.SaveAsString(s)))); 8 | 9 | //var result2 = Key.GetKey(token="", RSAPubKey, ProductId=3349, Key="GEBNC-WZZJD-VJIHG-GCMVD"); 10 | //result2.then((s)=> console.log(Helpers.LoadFromString(RSAPubKey, Helpers.SaveAsString(s)))); 11 | 12 | var result = key.CreateKey(token ="", ProductId=15189, MachineCode="test") 13 | result.then((s) => console.log(s)); 14 | 15 | 16 | //console.log(Helpers.GetMachineCode()); 17 | 18 | var test = {}; 19 | 20 | test = {"ActivatedMachines" :[{"Mid":"floating:" + Helpers.GetMachineCode()}]}; 21 | 22 | console.log(Helpers.IsOnRightMachine(test,true)); 23 | 24 | console.log(Helpers.GetMachineCodeShort()); --------------------------------------------------------------------------------