@n8n_io/license-sdk 2.20.0 → 2.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LicenseManager.js +8 -30
- package/dist/LicenseManager.js.map +1 -1
- package/dist/LicenseManager.mjs +8 -30
- package/dist/LicenseManager.mjs.map +1 -1
- package/dist/_tsup-dts-rollup.d.mts +2 -2
- package/dist/_tsup-dts-rollup.d.ts +2 -2
- package/dist/httpRequest.js +1 -1
- package/dist/httpRequest.js.map +1 -1
- package/dist/httpRequest.mjs +1 -1
- package/dist/httpRequest.mjs.map +1 -1
- package/package.json +1 -1
package/dist/LicenseManager.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var D=Object.create;var d=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var N=(a,e)=>{for(var t in e)d(a,t,{get:e[t],enumerable:!0})},T=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of L(e))!O.call(a,n)&&n!==t&&d(a,n,{get:()=>e[n],enumerable:!(i=S(e,n))||i.enumerable});return a};var E=(a,e,t)=>(t=a!=null?D(x(a)):{},T(e||!a||!a.__esModule?d(t,"default",{value:a,enumerable:!0}):t,a)),M=a=>T(d({},"__esModule",{value:!0}),a);var B={};N(B,{AUTORENEWAL_INTERVAL:()=>u,LicenseManager:()=>y});module.exports=M(B);var C=E(require("crypto-js")),b=require("node-machine-id"),F=E(require("node-rsa")),A=require("assert"),v=require("crypto");var f=require("undici"),R=require("url");var I="2.20.1";function g(a){let e=process.env[a]||process.env[a.toUpperCase()];return e?new f.ProxyAgent(e):!1}var m=g("http_proxy_license_server")||g("http_proxy"),p=g("https_proxy_license_server")||g("https_proxy"),P={...m?{"http:":m}:{},...p?{"https:":p}:{}},k=((process.env.no_proxy||process.env.NO_PROXY)??"").split(",").map(a=>a.trim()).filter(a=>a.length>0),z=a=>{let{host:e,protocol:t}=a;return!(t==="http:"&&!m||t==="https:"&&!p||k.some(i=>e.endsWith(i)))};async function w(a,e,t={}){let i=new R.URL(a),n;z(i)&&(n=P[i.protocol]);try{let r=await(0,f.fetch)(a,{method:"POST",body:JSON.stringify(e),headers:{"Content-Type":"application/json","User-Agent":`License-SDK/${I} (Node.js ${process.version}; ${process.platform}) ${t.productIdentifier??""}`},signal:AbortSignal.timeout(t.timeoutInMs??3e4),...n?{dispatcher:n}:{}});return{status:r.status,data:await r.json()}}catch(r){let s=new Error("Connection Error: "+r.message);throw s.cause=r,s}}var u=15*60*1e3;var y=class{constructor(e){this.isShuttingDown=!1;this.config=e,this.config.logger?this.logger=this.config.logger:this.logger={error(){console.log("ERROR:",...arguments)},warn(){console.log("WARN:",...arguments)},info(){console.log("INFO:",...arguments)},debug(){console.log("DEBUG:",...arguments)}},this.x509IssuerCert=new v.X509Certificate(`-----BEGIN CERTIFICATE-----
|
|
2
2
|
MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE
|
|
3
3
|
RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp
|
|
4
4
|
Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL
|
|
@@ -26,34 +26,12 @@ uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP
|
|
|
26
26
|
A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD
|
|
27
27
|
4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT
|
|
28
28
|
/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ
|
|
29
|
-
-----END CERTIFICATE-----`),this.config.autoRenewEnabled=this.config.autoRenewEnabled??!0,this.config.renewOnInit=this.config.renewOnInit??!1,this.config.offlineMode=this.config.offlineMode??!1,this.config.autoRenewOffset=this.config.autoRenewOffset??60*60*72,this.config.detachFloatingOnShutdown=this.config.detachFloatingOnShutdown??!0,this.config.server=this.config.server??"https://license.n8n.io/v1"}get isInitialized(){return!!this.initializationPromise}log(e,t){this.logger[t](`[license SDK] ${e}`)}async initialize(){return this.initializationPromise?this.initializationPromise:(this.initializationPromise=this._doInitialization(),await this.initializationPromise)}async _doInitialization(){(0,
|
|
30
|
-
tenantId: ${this.config.tenantId
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
autoRenewalEnabled: ${this.config.autoRenewEnabled?"true":"false (!)"}
|
|
34
|
-
autoRenewalOffset: ${this.config.autoRenewOffset} (= ${this.formatDuration(this.config.autoRenewOffset??0)})
|
|
29
|
+
-----END CERTIFICATE-----`),this.config.autoRenewEnabled=this.config.autoRenewEnabled??!0,this.config.renewOnInit=this.config.renewOnInit??!1,this.config.offlineMode=this.config.offlineMode??!1,this.config.autoRenewOffset=this.config.autoRenewOffset??60*60*72,this.config.detachFloatingOnShutdown=this.config.detachFloatingOnShutdown??!0,this.config.server=this.config.server??"https://license.n8n.io/v1"}get isInitialized(){return!!this.initializationPromise}log(e,t){this.logger[t](`[license SDK] ${e}`)}async initialize(){return this.initializationPromise?this.initializationPromise:(this.initializationPromise=this._doInitialization(),await this.initializationPromise)}async _doInitialization(){(0,A.ok)(!this.initializationPromise,"Initialization already in progress"),this.deviceFingerprint=await this.computeDeviceFingerprint(),this.log(`initializing for deviceFingerprint ${this.deviceFingerprint}`,"debug"),await this.initCert(),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.upcomingEntitlementChangesCheckTimer=this.setupRepeatingTimer(()=>this.setTimerForNextEntitlementChange(),u),this.config.renewOnInit&&this.config.autoRenewEnabled&&this.hasCert()&&(this.licenseCert.detachedEntitlementsCount>0||this.isRenewalDue())?await this.renewalCron({force:!0}):this.log("Skipping renewal on init because renewal is not due yet or cert is not initialized","info"),this.config.autoRenewEnabled&&(this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),u))}setupSingleTimer(e,t){return setTimeout(e,t)}clearSingleTimer(e){e&&clearTimeout(e)}setupRepeatingTimer(e,t){return setInterval(e,t)}clearRepeatingTimer(e){e&&clearInterval(e)}isOlderThan(e,t){return Date.now()-e.getTime()>t}async reload(){await this.reset(),await this.initialize()}async reset(){this.initializationPromise&&await this.initializationPromise,this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0,this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.upcomingEntitlementChangesCheckTimer=void 0,this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=void 0,this.licenseCert=void 0,this.deviceFingerprint=void 0,this.initializationPromise=void 0}async computeDeviceFingerprint(){return this.config.deviceFingerprint&&typeof this.config.deviceFingerprint=="function"?await this.config.deviceFingerprint():await(0,b.machineId)()}async activate(e){if(!this.isInitialized)throw new Error("activation failed because SDK was not yet initialized");if(this.isShuttingDown)throw new Error("activation failed because SDK is shutting down");if(this.config.offlineMode)throw new Error("activation failed because SDK is in offline mode");let t={reservationId:e,tenantId:this.config.tenantId,productIdentifier:this.config.productIdentifier,deviceFingerprint:this.deviceFingerprint};this.hasCert()&&(t.consumerId=this.licenseCert.consumerId,t.renewalToken=this.licenseCert.renewalToken);let i;try{i=await w(`${this.config.server}/activate`,t,{timeoutInMs:1e4,productIdentifier:this.config.productIdentifier})}catch(n){throw this.log("license activation failed: "+n.message,"warn"),new Error(n.message)}if(i.status==200){if(!i.data.hasOwnProperty("licenseKey")||!i.data.hasOwnProperty("x509"))throw this.log("unexpected server response","warn"),new Error("unexpected server response");let n=this.stringifyCertContainer({licenseKey:i.data.licenseKey,x509:i.data.x509});await this.config.saveCertStr(n),await this.initCert(),this.log("license successfully activated","info"),(i.data.detachedEntitlementsCount??!1)&&this.log(`skipped importing ${i.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,"info")}else{let n=`license activation failed: ${i.data.message??"unknown reason"}`,r=new Error(n);throw i.data.errorId&&(r.errorId=i.data.errorId),this.log(n,"warn"),r}}async renew(){return this._renew({cause:"request"})}async _renew({detachFloatingEntitlements:e=!1,cause:t="unknown"}={}){if(!this.hasCert())throw new Error("renewal failed because current cert is not initialized");if(this.licenseCert.isEphemeral)return;if(this.isTerminated())throw new Error("renewal failed because current cert was terminated");if(this.config.offlineMode)throw new Error("renewal failed because SDK is in offline mode");if(this.config.tenantId!==this.licenseCert.tenantId)throw new Error("renewal failed because tenant ID does not match");if(t!=="request"&&this.licenseCert.deviceLock&&this.deviceFingerprint!==this.licenseCert.deviceFingerprint)throw new Error("renewal failed because device fingerprint does not match");let[i,n]=await Promise.all([this.config.collectUsageMetrics?this.config.collectUsageMetrics():[],this.config.collectPassthroughData?this.config.collectPassthroughData():{}]),r;try{r=await w(`${this.config.server}/renew`,{consumerId:this.licenseCert.consumerId,tenantId:this.config.tenantId,deviceFingerprint:this.deviceFingerprint,productIdentifier:this.config.productIdentifier,renewalToken:this.licenseCert.renewalToken,detachFloatingEntitlements:e,cause:t,usageMetrics:i,passthroughData:n},{timeoutInMs:1e4,productIdentifier:this.config.productIdentifier})}catch(o){throw this.log("license renewal failed: "+o.message,"warn"),new Error(o.message)}let s=r.data;if(r.status==200){if(!s.hasOwnProperty("licenseKey")||!s.hasOwnProperty("x509"))throw this.log("license renewal failed: unexpected server response","warn"),new Error("unexpected server response");let o=this.stringifyCertContainer({licenseKey:s.licenseKey,x509:s.x509});await this.config.saveCertStr(o),this.log("license successfully renewed","info"),(s.detachedEntitlementsCount??!1)&&(e?this.log(`${s.detachedEntitlementsCount} floating entitlements were returned to the pool`,"info"):this.log(`skipped importing ${s.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,"info")),await this.initCert()}else{let o=`license renewal failed: ${s.message??"unknown reason"}`;this.log(o,"warn");let l=new Error(o);throw s.errorId&&(l.errorId=s.errorId,["NOT_FOUND","CONSUMER_TERMINATED"].includes(s.errorId)?(this.log("license was terminated by the server. Deleting local cert.","warn"),await this.config.saveCertStr(""),await this.initCert()):s.errorId==="FINGERPRINT_MISMATCH"&&this.disableAutoRenewals()),l}}hasCert(){return!!this.licenseCert}isTerminated(){if(!this.hasCert())throw new Error("Cert is not initialized");let e=new Date;return this.licenseCert.terminatesAt<e}getExpiryDate(){if(!this.hasCert())throw new Error("Cert is not initialized");return this.licenseCert.expiresAt}getTerminationDate(){if(!this.hasCert())throw new Error("Cert is not initialized");return this.licenseCert.terminatesAt}isValid(e=!0){let t=r=>{if(e){let s=this.hasCert()?`: (autorenewalsEnabled: ${this.config.autoRenewEnabled}, expiredAt: ${this.licenseCert?.expiresAt}, issuedAt: ${this.licenseCert?.issuedAt})`:"";this.log(`${r}${s}`,"error")}};if(!this.hasCert())return t("cert is invalid because it is undefined"),!1;let i=this.licenseCert,n=new Date;return i.expiresAt<n?(t("cert is invalid because it has expired"),!1):i.terminatesAt<n?(t("cert is invalid because it was terminated"),!1):i.createdAt.getTime()-3e5>n.getTime()?(t("cert is invalid because system clock is out of sync"),!1):i.deviceLock&&this.deviceFingerprint!==i.deviceFingerprint?(t("cert is invalid because device fingerprint does not match"),!1):this.config.tenantId!==i.tenantId?(t("cert is invalid because tenant ID does not match"),!1):!0}hasFeatureEnabled(e,t=!0){return!!this.getFeatureValue(e,t)}hasFeatureDefined(e,t=!0){return this.getFeatureValue(e,t)!==void 0}hasQuotaLeft(e,t){let i=this.getFeatureValue(e);if(i===void 0)return!1;if(typeof i!="number")throw new Error(`${e} cannot be used as quota as it is not numeric`);return i===-1?!0:Math.ceil(t)<Math.ceil(i)}getFeatureValue(e,t=!0){if(!this.hasCert()||t&&!this.isValid())return;let i=this.getFeatures();if(i.hasOwnProperty(e))return i[e]}updateCurrentFeatures(){if(!this.hasCert())return;let e=new Date;(this.licenseCert.expiresAt<e||this.licenseCert.terminatesAt<e)&&(this.currentFeatures={}),this.currentFeatures=this.licenseCert.entitlements.filter(t=>t.validFrom<=e&&t.validTo>e).sort((t,i)=>t.validFrom.getTime()-i.validFrom.getTime()).reduce((t,i)=>({...t,...i.features,...i.featureOverrides}),{})}getFeatures(){return this.hasCert()?this.currentFeatures??{}:{}}getCurrentEntitlements(){if(!this.hasCert())return[];let e=new Date;return this.licenseCert.entitlements.filter(t=>t.validFrom<=e&&t.validTo>e)}getManagementJwt(){return this.licenseCert?this.licenseCert.managementJwt:""}async getCertStr(){return this.config.loadCertStr()}getConsumerId(){return this.licenseCert?.consumerId}isRenewalDue(){if(!this.licenseCert||this.licenseCert.isEphemeral)return!1;let e=Date.now(),t=1e3*60*15,i=1e3*60*20,n=this.licenseCert.expiresAt.getTime(),r=this.licenseCert.issuedAt.getTime(),s=this.licenseCert.terminatesAt.getTime(),o=e>n-this.config.autoRenewOffset*1e3&&e<s,l=this.getCurrentEntitlements().find(c=>e>=c.validTo.getTime()-t&&e<=c.validTo.getTime())!==void 0&&r<e-i;return o||l}formatDuration(e){let t=Math.floor(e/3600),i=Math.floor(e%3600/60),n=e%60;return`${t}h ${i}m ${n}s`}toString(){let e=this.isValid(!1),t=this.isRenewalDue(),i=(this.licenseCert?.detachedEntitlementsCount??0)>0,n=(c,h)=>`${c}${h?" (!)":""}`,r=(c,h="<n/a>")=>c??h,s=["## CONSUMER CONFIG ##",`tenantId: ${r(this.config.tenantId)}`,`productIdentifier: ${r(this.config.productIdentifier)}`,`deviceFingerprint: ${r(this.deviceFingerprint)}`,`autoRenewalEnabled: ${n(this.config.autoRenewEnabled?"true":"false",!this.config.autoRenewEnabled)}`,`autoRenewalOffset: ${this.config.autoRenewOffset} (= ${this.formatDuration(this.config.autoRenewOffset??0)})`].join(`
|
|
30
|
+
`),o=["## LICENSE CERT ##",`version: ${r(this.licenseCert?.version)}`,`tenantId: ${n(r(this.licenseCert?.tenantId),this.licenseCert?.tenantId!==this.config.tenantId)}`,`consumerId: ${r(this.licenseCert?.consumerId)}`,`deviceFingerprint: ${n(r(this.licenseCert?.deviceFingerprint),this.licenseCert?.deviceFingerprint!==this.deviceFingerprint)}`,`createdAt: ${r(this.licenseCert?.createdAt)}`,`issuedAt: ${r(this.licenseCert?.issuedAt)}`,`expiresAt: ${r(this.licenseCert?.expiresAt)}`,`terminatesAt: ${r(this.licenseCert?.terminatesAt)}`,`isEphemeral: ${r(this.licenseCert?.isEphemeral)}`,`isValid: ${n(e,!e)}`,`isRenewalDue: ${n(t,t)}`,`detachedEntitlementsCount: ${n(r(this.licenseCert?.detachedEntitlementsCount),i)}`,`entitlements: ${this.licenseCert?.entitlements?.length??0}`].join(`
|
|
31
|
+
`),l=this.licenseCert?.entitlements?.map((c,h)=>["## ENTITLEMENT "+(h+1)+" ##",`id: ${c.id}`,`productId: ${c.productId}`,`validFrom: ${c.validFrom}`,`validTo: ${c.validTo}`,`features: ${JSON.stringify(c.features)}`,`featureOverrides: ${JSON.stringify(c.featureOverrides)}`].join(`
|
|
32
|
+
`)).join(`
|
|
35
33
|
--
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
consumerId: ${this.licenseCert?.consumerId??"<n/a>"}
|
|
40
|
-
deviceFingerprint: ${this.licenseCert?.deviceFingerprint??"<n/a>"} ${this.licenseCert?.deviceFingerprint!==this.deviceFingerprint?"(!)":""}
|
|
41
|
-
createdAt: ${this.licenseCert?.createdAt??"<n/a>"}
|
|
42
|
-
issuedAt: ${this.licenseCert?.issuedAt??"<n/a>"}
|
|
43
|
-
expiresAt: ${this.licenseCert?.expiresAt??"<n/a>"}
|
|
44
|
-
terminatesAt: ${this.licenseCert?.terminatesAt??"<n/a>"}
|
|
45
|
-
isEphemeral: ${this.licenseCert?.isEphemeral??"<n/a>"}
|
|
46
|
-
isValid: ${this.isValid(!1)}
|
|
47
|
-
isRenewalDue: ${this.isRenewalDue()}
|
|
48
|
-
detachedEntitlementsCount: ${this.licenseCert?.detachedEntitlementsCount??"<n/a>"}
|
|
49
|
-
entitlements: ${this.licenseCert?.entitlements.length??0}
|
|
50
|
-
`+this.licenseCert?.entitlements.map((e,t)=>`--
|
|
51
|
-
## ENTITLEMENT ${t+1} ##
|
|
52
|
-
id: ${e.id}
|
|
53
|
-
productId: ${e.productId}
|
|
54
|
-
validFrom: ${e.validFrom}
|
|
55
|
-
validTo: ${e.validTo}
|
|
56
|
-
features: ${JSON.stringify(e.features)}
|
|
57
|
-
featureOverrides: ${JSON.stringify(e.featureOverrides)}
|
|
58
|
-
`).join("")}triggerOnFeatureChangeCallback(){this.config.onFeatureChange&&this.config.onFeatureChange(this.currentFeatures??{})}setTimerForNextEntitlementChange(){if(!this.hasCert())return;let e=Date.now(),t=new Set;t.add(this.licenseCert.expiresAt.getTime()-e),t.add(this.licenseCert.terminatesAt.getTime()-e);let i=[...this.licenseCert.entitlements.reduce((r,a)=>(r.add(a.validFrom.getTime()-e),r.add(a.validTo.getTime()-e),r),t)].filter(r=>r>=0&&r<=l).sort((r,a)=>r-a);if(i.length===0)return;let n=i[0];this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=this.setupSingleTimer(()=>{this.updateCurrentFeatures(),this.triggerOnFeatureChangeCallback(),this.setTimerForNextEntitlementChange()},n+1e3)}async renewalCron({force:e}){if(e||this.isRenewalDue()){this.log("attempting license renewal","debug");try{await this._renew({cause:e?"startup":"auto"})}catch{}}}async initCert(){if(!this.isShuttingDown)try{let e=await this.getCertStr();if(!e){this.licenseCert=void 0;return}if(e.length<50)throw new Error("cert string is undefined or too short");let{x509:t,licenseKey:i}=this.parseLicenseCertContainerStr(e);if(this.x509Cert=new w.X509Certificate(t),!this.x509Cert.checkIssued(this.getIssuerCert()))throw new Error("cert was not issued by an approved issuer");let r=this.x509Cert.publicKey.export({format:"pem",type:"pkcs1"});this.key=new b.default(r),this.licenseCert=this.parseLicenseKeyStr(i),this.updateCurrentFeatures(),this.setTimerForNextEntitlementChange()}catch(e){this.log(`cert could not be initialized. ${e instanceof Error?e.message:""}`,"error")}}stringifyCertContainer(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}parseLicenseCertContainerStr(e){let t=Buffer.from(e,"base64").toString("ascii"),i=JSON.parse(t);if(!i.hasOwnProperty("licenseKey")||!i.hasOwnProperty("x509"))throw new Error("license cert container could not be parsed");return i}parseLicenseKeyStr(e){let t=this.validateLicenseKey(e),i={...t};return i.createdAt=new Date(t.createdAt),i.issuedAt=new Date(t.issuedAt),i.expiresAt=new Date(t.expiresAt),i.terminatesAt=new Date(t.terminatesAt),i.detachedEntitlementsCount=t.detachedEntitlementsCount??0,i.entitlements=i.entitlements.map(n=>(n.validFrom=new Date(n.validFrom),n.validTo=new Date(n.validTo),n)),i}validateLicenseKey(e){e=e.replace(/(\r\n|\n|\r)/gm,"");let t=e.match(/^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\|\|)(?<encryptedData>.+)\|\|(?<signature>.+)-----END LICENSE KEY-----$/);if(!t)throw new Error("license key could not be parsed");let i=t.groups.encryptedSymmetricKey,n=t.groups.encryptedData,r=t.groups.signature,a,o;try{a=this.key.decryptPublic(i,"utf8")}catch{throw new Error("Invalid data: Could not extract symmetric key")}try{o=p.default.AES.decrypt(n,a).toString(p.default.enc.Utf8)}catch{throw new Error("Invalid Data: Could not decrypt data with key found")}if(this.key.verify(Buffer.from(o),r,"utf8","base64"))return JSON.parse(o);throw new Error("License Key signature invalid")}getIssuerCert(){return this.x509IssuerCert}async clear(){try{await this.detachFloatingEntitlements()}catch(e){this.log(`failed to detach floating entitlements (${e}). Continuing with clearing license certificate`,"warn")}finally{await this.config.saveCertStr(""),await this.initCert()}}async shutdown(){this.isShuttingDown=!0,this.clearRepeatingTimer(this.renewalTimer),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.clearSingleTimer(this.entitlementChangeTimer),this.config.detachFloatingOnShutdown&&await this.detachFloatingEntitlements()}async detachFloatingEntitlements(){if(!this.hasCert())return;this.licenseCert.entitlements.some(t=>t.isFloatable??!1)&&await this._renew({detachFloatingEntitlements:!0,cause:"shutdown"})}enableAutoRenewals(){this.config.autoRenewEnabled!==!0&&(this.config.autoRenewEnabled=!0,this.log("License auto-renewals enabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),l))}disableAutoRenewals(){this.config.autoRenewEnabled!==!1&&(this.config.autoRenewEnabled=!1,this.log("License auto-renewals disabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0)}};0&&(module.exports={AUTORENEWAL_INTERVAL,LicenseManager});
|
|
34
|
+
`)||"";return[s,"--",o,l?`--
|
|
35
|
+
`+l:""].join(`
|
|
36
|
+
`)}triggerOnFeatureChangeCallback(){this.config.onFeatureChange&&this.config.onFeatureChange(this.currentFeatures??{})}setTimerForNextEntitlementChange(){if(!this.hasCert())return;let e=Date.now(),t=new Set;t.add(this.licenseCert.expiresAt.getTime()-e),t.add(this.licenseCert.terminatesAt.getTime()-e);let i=[...this.licenseCert.entitlements.reduce((r,s)=>(r.add(s.validFrom.getTime()-e),r.add(s.validTo.getTime()-e),r),t)].filter(r=>r>=0&&r<=u).sort((r,s)=>r-s);if(i.length===0)return;let n=i[0];this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=this.setupSingleTimer(()=>{this.updateCurrentFeatures(),this.triggerOnFeatureChangeCallback(),this.setTimerForNextEntitlementChange()},n+1e3)}async renewalCron({force:e}){if(e||this.isRenewalDue()){this.log("attempting license renewal","info");try{await this._renew({cause:e?"startup":"auto"})}catch{}}}async initCert(){if(!this.isShuttingDown)try{let e=await this.getCertStr();if(!e){this.licenseCert=void 0;return}if(e.length<50)throw new Error("cert string is undefined or too short");let{x509:t,licenseKey:i}=this.parseLicenseCertContainerStr(e);if(this.x509Cert=new v.X509Certificate(t),!this.x509Cert.checkIssued(this.getIssuerCert()))throw new Error("cert was not issued by an approved issuer");let r=this.x509Cert.publicKey.export({format:"pem",type:"pkcs1"});this.key=new F.default(r),this.licenseCert=this.parseLicenseKeyStr(i),this.updateCurrentFeatures(),this.setTimerForNextEntitlementChange()}catch(e){this.log(`cert could not be initialized. ${e instanceof Error?e.message:""}`,"error")}}stringifyCertContainer(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}parseLicenseCertContainerStr(e){let t=Buffer.from(e,"base64").toString("ascii"),i=JSON.parse(t);if(!i.hasOwnProperty("licenseKey")||!i.hasOwnProperty("x509"))throw new Error("license cert container could not be parsed");return i}parseLicenseKeyStr(e){let t=this.validateLicenseKey(e),i={...t};return i.createdAt=new Date(t.createdAt),i.issuedAt=new Date(t.issuedAt),i.expiresAt=new Date(t.expiresAt),i.terminatesAt=new Date(t.terminatesAt),i.detachedEntitlementsCount=t.detachedEntitlementsCount??0,i.entitlements=i.entitlements.map(n=>(n.validFrom=new Date(n.validFrom),n.validTo=new Date(n.validTo),n)),i}validateLicenseKey(e){e=e.replace(/(\r\n|\n|\r)/gm,"");let t=e.match(/^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\|\|)(?<encryptedData>.+)\|\|(?<signature>.+)-----END LICENSE KEY-----$/);if(!t)throw new Error("license key could not be parsed");let i=t.groups.encryptedSymmetricKey,n=t.groups.encryptedData,r=t.groups.signature,s,o;try{s=this.key.decryptPublic(i,"utf8")}catch{throw new Error("Invalid data: Could not extract symmetric key")}try{o=C.default.AES.decrypt(n,s).toString(C.default.enc.Utf8)}catch{throw new Error("Invalid Data: Could not decrypt data with key found")}if(this.key.verify(Buffer.from(o),r,"utf8","base64"))return JSON.parse(o);throw new Error("License Key signature invalid")}getIssuerCert(){return this.x509IssuerCert}async clear(){try{await this.detachFloatingEntitlements()}catch(e){this.log(`failed to detach floating entitlements (${e}). Continuing with clearing license certificate`,"warn")}finally{await this.config.saveCertStr(""),await this.initCert()}}async shutdown(){this.isShuttingDown=!0,this.clearRepeatingTimer(this.renewalTimer),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.clearSingleTimer(this.entitlementChangeTimer),this.config.detachFloatingOnShutdown&&await this.detachFloatingEntitlements()}async detachFloatingEntitlements(){if(!this.hasCert())return;this.licenseCert.entitlements.some(t=>t.isFloatable??!1)&&await this._renew({detachFloatingEntitlements:!0,cause:"shutdown"})}enableAutoRenewals(){this.config.autoRenewEnabled!==!0&&(this.config.autoRenewEnabled=!0,this.log("License auto-renewals enabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),u))}disableAutoRenewals(){this.config.autoRenewEnabled!==!1&&(this.config.autoRenewEnabled=!1,this.log("License auto-renewals disabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0)}};0&&(module.exports={AUTORENEWAL_INTERVAL,LicenseManager});
|
|
59
37
|
//# sourceMappingURL=LicenseManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { ok } from 'node:assert'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\n/** How often to consider periodic license renewal (in ms) */\nexport const AUTORENEWAL_INTERVAL = 15 * 60 * 1000 // 15 minutes\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n\n /**\n * Whether to renew the license periodically.\n *\n * @default true\n */\n autoRenewEnabled?: boolean\n /**\n * Whether to return any floatable entitlements to the pool on SDK shutdown.\n *\n * @default true\n */\n detachFloatingOnShutdown?: boolean\n offlineMode?: boolean\n renewOnInit?: boolean\n autoRenewOffset?: number\n loadCertStr: () => Promise<TLicenseBlock>\n saveCertStr: (cert: TLicenseBlock) => Promise<void>\n collectUsageMetrics?: () => Promise<Array<TUsageMetric>>\n collectPassthroughData?: () => Promise<TPassthroughData>\n deviceFingerprint?: () => string | Promise<string>\n onFeatureChange?: (features: TFeatures) => any\n logger?: TLogger\n}\n\nexport type TLicenseBlock = string\n\nexport type TLicenseContainer = {\n licenseKey: string\n x509: string\n}\n\nexport type TFeatures = { [key: string]: boolean | number | string }\n\nexport type TUsageMetric = { name: string; value: number }\n\nexport type TPassthroughData = Record<string, unknown>\n\nexport type TMetadata = {\n [key: string]: boolean | number | string | Array<any> | {}\n}\n\nexport type TEntitlement = {\n id: string\n productId: string\n productMetadata: TMetadata\n features: TFeatures\n featureOverrides: TFeatures\n validFrom: Date\n validTo: Date\n isFloatable: boolean\n}\n\nexport type TLicenseCertObj = {\n consumerId: string\n consumerRef?: string\n version: number\n tenantId: number\n renewalToken: string\n deviceLock: boolean\n deviceFingerprint: string\n createdAt: Date\n issuedAt: Date\n expiresAt: Date\n terminatesAt: Date\n entitlements: TEntitlement[]\n /**\n * Indicates the number of floating entitlements that are not attached to the consumer\n * because they are in use elsewhere at the time of renewal.\n */\n detachedEntitlementsCount: number\n managementJwt: string\n /**\n * Specifies whether the license is ephemeral and therefore does not have corresponding entries in the license server DB.\n */\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\n\ntype SingleTimer = NodeJS.Timeout\ntype RepeatingTimer = NodeJS.Timeout\n\nconst enum LogLevel {\n ERROR = 'error',\n WARN = 'warn',\n INFO = 'info',\n DEBUG = 'debug',\n}\n\nexport class LicenseManager {\n public config: TLicenseManagerConfig\n\n private initializationPromise?: Promise<void>\n private key?: NodeRSA\n private logger: TLogger\n protected licenseCert?: TLicenseCertObj\n private x509Cert?: X509Certificate\n private x509IssuerCert: X509Certificate\n private deviceFingerprint?: string\n private renewalTimer?: RepeatingTimer\n private upcomingEntitlementChangesCheckTimer?: RepeatingTimer\n private entitlementChangeTimer?: SingleTimer\n private currentFeatures?: TFeatures\n private isShuttingDown = false\n\n get isInitialized() {\n return !!this.initializationPromise\n }\n\n constructor(config: TLicenseManagerConfig) {\n this.config = config\n\n if (this.config.logger) {\n this.logger = this.config.logger\n } else {\n this.logger = {\n error() {\n console.log('ERROR:', ...arguments)\n },\n warn() {\n console.log('WARN:', ...arguments)\n },\n info() {\n console.log('INFO:', ...arguments)\n },\n debug() {\n console.log('DEBUG:', ...arguments)\n },\n }\n }\n\n this.x509IssuerCert = new X509Certificate(\n '-----BEGIN CERTIFICATE-----\\n' +\n 'MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE\\n' +\n 'RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp\\n' +\n 'Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL\\n' +\n 'MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw\\n' +\n 'FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\\n' +\n 'AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q\\n' +\n 'IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+\\n' +\n 'btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU\\n' +\n 'zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED\\n' +\n '+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS\\n' +\n 'dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po\\n' +\n 'Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S\\n' +\n '28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM\\n' +\n 'K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs\\n' +\n 'sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL\\n' +\n 'JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ\\n' +\n 'KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8\\n' +\n 'ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3\\n' +\n 'Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl\\n' +\n '/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP\\n' +\n 'Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK\\n' +\n 'LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc\\n' +\n 'Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw\\n' +\n 'uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP\\n' +\n 'A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD\\n' +\n '4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT\\n' +\n '/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ\\n' +\n '-----END CERTIFICATE-----'\n )\n\n //set defaults for not set config properties:\n this.config.autoRenewEnabled = this.config.autoRenewEnabled ?? true\n this.config.renewOnInit = this.config.renewOnInit ?? false\n this.config.offlineMode = this.config.offlineMode ?? false\n this.config.autoRenewOffset = this.config.autoRenewOffset ?? 60 * 60 * 72 // default: 72 hours\n this.config.detachFloatingOnShutdown =\n this.config.detachFloatingOnShutdown ?? true\n this.config.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license SDK] ${msg}`)\n }\n\n async initialize() {\n if (this.initializationPromise) {\n return this.initializationPromise\n }\n\n this.initializationPromise = this._doInitialization()\n\n return await this.initializationPromise\n }\n\n /** Initializes the license manager */\n private async _doInitialization() {\n ok(!this.initializationPromise, 'Initialization already in progress')\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n\n await this.initCert() // doesn't throw!\n\n // Clear and set up periodic timer for entitlement changes\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = this.setupRepeatingTimer(\n () => this.setTimerForNextEntitlementChange(),\n AUTORENEWAL_INTERVAL\n )\n\n // Renew license on init if necessary\n // If detachedEntitlementsCount > 0, renewing is important in order to attempt re-attaching floating entitlements!\n if (\n this.config.renewOnInit &&\n this.config.autoRenewEnabled &&\n this.hasCert() &&\n (this.licenseCert.detachedEntitlementsCount > 0 || this.isRenewalDue())\n ) {\n await this.renewalCron({ force: true })\n } else {\n this.log(\n 'Skipping renewal on init because renewal is not due yet or cert is not initialized',\n LogLevel.DEBUG\n )\n }\n\n // Set up periodic renewal if enabled\n if (this.config.autoRenewEnabled) {\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n }\n\n private setupSingleTimer(\n callback: () => void,\n interval: number\n ): SingleTimer {\n return setTimeout(callback, interval)\n }\n\n clearSingleTimer(timer: SingleTimer | undefined) {\n if (timer) {\n clearTimeout(timer)\n }\n }\n\n setupRepeatingTimer(callback: () => void, interval: number): RepeatingTimer {\n return setInterval(callback, interval)\n }\n\n clearRepeatingTimer(timer: RepeatingTimer | undefined) {\n if (timer) {\n clearInterval(timer)\n }\n }\n\n private isOlderThan(date: Date, durationInMs: number) {\n return Date.now() - date.getTime() > durationInMs\n }\n\n async reload() {\n await this.reset()\n await this.initialize()\n }\n\n async reset() {\n // Make sure initialization is not ongoing before resetting\n if (this.initializationPromise) {\n await this.initializationPromise\n }\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = undefined\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = undefined\n\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.initializationPromise = undefined\n }\n\n async computeDeviceFingerprint() {\n if (\n this.config.deviceFingerprint &&\n typeof this.config.deviceFingerprint === 'function'\n ) {\n return await this.config.deviceFingerprint()\n }\n return await machineId()\n }\n\n async activate(reservationId: string) {\n if (!this.isInitialized) {\n throw new Error('activation failed because SDK was not yet initialized')\n }\n\n if (this.isShuttingDown) {\n throw new Error('activation failed because SDK is shutting down')\n }\n\n if (this.config.offlineMode) {\n throw new Error('activation failed because SDK is in offline mode')\n }\n\n const postData: {\n reservationId: string\n tenantId: number\n productIdentifier: string\n deviceFingerprint: string\n consumerId?: string\n renewalToken?: string\n } = {\n reservationId,\n tenantId: this.config.tenantId,\n productIdentifier: this.config.productIdentifier,\n deviceFingerprint: this.deviceFingerprint!,\n }\n\n if (this.hasCert()) {\n postData.consumerId = this.licenseCert.consumerId\n postData.renewalToken = this.licenseCert.renewalToken\n }\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<{\n licenseKey?: string\n x509?: string\n message?: string\n errorId?: string\n }>(`${this.config.server!}/activate`, postData, {\n timeoutInMs: 10000,\n productIdentifier: this.config.productIdentifier,\n })\n } catch (error) {\n this.log(\n 'license activation failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n if (response.status == 200) {\n if (\n !response.data.hasOwnProperty('licenseKey') ||\n !response.data.hasOwnProperty('x509')\n ) {\n this.log('unexpected server response', LogLevel.WARN)\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: response.data.licenseKey,\n x509: response.data.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n await this.initCert()\n this.log('license successfully activated', LogLevel.INFO)\n if (response.data.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${response.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n } else {\n const errorMsg = `license activation failed: ${\n response.data.message ?? 'unknown reason'\n }`\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (response.data.errorId) {\n e.errorId = response.data.errorId\n }\n\n this.log(errorMsg, LogLevel.WARN)\n throw e\n }\n }\n\n async renew() {\n return this._renew({ cause: 'request' })\n }\n\n async _renew({\n detachFloatingEntitlements = false,\n cause = 'unknown',\n }: {\n detachFloatingEntitlements?: Boolean\n cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown'\n } = {}) {\n if (!this.hasCert()) {\n throw new Error('renewal failed because current cert is not initialized')\n }\n\n if (this.licenseCert.isEphemeral) {\n return\n }\n\n if (this.isTerminated()) {\n throw new Error('renewal failed because current cert was terminated')\n }\n\n if (this.config.offlineMode) {\n throw new Error('renewal failed because SDK is in offline mode')\n }\n\n if (this.config.tenantId !== this.licenseCert.tenantId) {\n throw new Error('renewal failed because tenant ID does not match')\n }\n\n // error out if device fingerprint does not match but allow renewal on explicit request\n // as the consumer might have been changed to more permissive settings on the server\n if (\n cause !== 'request' &&\n this.licenseCert.deviceLock &&\n this.deviceFingerprint !== this.licenseCert.deviceFingerprint\n ) {\n throw new Error(\n 'renewal failed because device fingerprint does not match'\n )\n }\n\n const [usageMetrics, passthroughData] = await Promise.all([\n this.config.collectUsageMetrics ? this.config.collectUsageMetrics() : [],\n this.config.collectPassthroughData\n ? this.config.collectPassthroughData()\n : {},\n ])\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<ResponseDataFormat>(\n `${this.config.server!}/renew`,\n {\n consumerId: this.licenseCert.consumerId,\n tenantId: this.config.tenantId,\n deviceFingerprint: this.deviceFingerprint,\n productIdentifier: this.config.productIdentifier,\n renewalToken: this.licenseCert.renewalToken,\n detachFloatingEntitlements,\n cause,\n usageMetrics,\n passthroughData,\n },\n { timeoutInMs: 10000, productIdentifier: this.config.productIdentifier }\n )\n } catch (error) {\n this.log(\n 'license renewal failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n const responseData = response.data\n\n if (response.status == 200) {\n if (\n !responseData.hasOwnProperty('licenseKey') ||\n !responseData.hasOwnProperty('x509')\n ) {\n this.log(\n 'license renewal failed: unexpected server response',\n LogLevel.WARN\n )\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: responseData.licenseKey,\n x509: responseData.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n\n this.log('license successfully renewed', LogLevel.DEBUG)\n\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n if (detachFloatingEntitlements) {\n this.log(\n `${responseData.detachedEntitlementsCount} floating entitlements were returned to the pool`,\n LogLevel.INFO\n )\n } else {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n }\n\n await this.initCert()\n } else {\n const errorMsg = `license renewal failed: ${\n responseData.message ?? 'unknown reason'\n }`\n\n this.log(errorMsg, LogLevel.WARN)\n\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (responseData.errorId) {\n e.errorId = responseData.errorId\n\n if (\n ['NOT_FOUND', 'CONSUMER_TERMINATED'].includes(responseData.errorId)\n ) {\n this.log(\n 'license was terminated by the server. Deleting local cert.',\n LogLevel.WARN\n )\n await this.config.saveCertStr('')\n await this.initCert()\n } else if (responseData.errorId === 'FINGERPRINT_MISMATCH') {\n // pause auto-renewal as subsequent requests will also fail\n this.disableAutoRenewals()\n }\n }\n\n throw e\n }\n }\n\n private hasCert(): this is { licenseCert: TLicenseCertObj } {\n return !!this.licenseCert\n }\n\n isTerminated(): boolean {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n const now = new Date()\n\n return this.licenseCert.terminatesAt < now\n }\n\n getExpiryDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.expiresAt\n }\n\n getTerminationDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.terminatesAt\n }\n\n isValid(useLogger = true): boolean {\n const error = (msg: string) => {\n if (useLogger) {\n this.log(msg, LogLevel.ERROR)\n }\n }\n\n if (!this.hasCert()) {\n error('cert is invalid because it is undefined')\n return false\n }\n\n const cert = this.licenseCert as TLicenseCertObj\n const now = new Date()\n\n if (cert.expiresAt < now) {\n error('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n error('cert is invalid because it was terminated')\n return false\n }\n\n //allow clocks to be out of sync by no more than 300,000 ms / = 5 minutes\n if (cert.createdAt.getTime() - 300000 > now.getTime()) {\n error('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n error('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n error('cert is invalid because tenant ID does not match')\n return false\n }\n\n return true\n }\n\n hasFeatureEnabled(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) ? true : false\n }\n\n hasFeatureDefined(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) !== undefined\n ? true\n : false\n }\n\n hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean {\n const quota = this.getFeatureValue(quotaFeatureName)\n\n if (quota === undefined) {\n return false\n }\n\n if (typeof quota !== 'number') {\n throw new Error(\n `${quotaFeatureName} cannot be used as quota as it is not numeric`\n )\n }\n\n // -1 means unlimited quota!\n if (quota === -1) {\n return true\n }\n\n return Math.ceil(currentConsumption) < Math.ceil(quota)\n }\n\n getFeatureValue(\n feature: string,\n requireValidCert: boolean = true\n ): undefined | boolean | number | string {\n if (!this.hasCert()) {\n return undefined\n }\n\n if (requireValidCert && !this.isValid()) {\n return undefined\n }\n\n const currentFeatures = this.getFeatures()\n\n if (!currentFeatures.hasOwnProperty(feature)) {\n return undefined\n }\n\n return currentFeatures[feature]\n }\n\n private updateCurrentFeatures() {\n if (!this.hasCert()) {\n return\n }\n\n const now = new Date()\n\n if (\n this.licenseCert.expiresAt < now ||\n this.licenseCert.terminatesAt < now\n ) {\n this.currentFeatures = {} as TFeatures\n }\n\n this.currentFeatures = this.licenseCert.entitlements\n .filter(\n (entitlement) =>\n entitlement.validFrom <= now && entitlement.validTo > now\n )\n .sort(\n (entitlement1, entitlement2) =>\n entitlement1.validFrom.getTime() - entitlement2.validFrom.getTime()\n )\n .reduce((currentFeatures, entitlement) => {\n return {\n ...currentFeatures,\n ...entitlement.features,\n ...entitlement.featureOverrides,\n }\n }, {} as TFeatures)\n }\n\n getFeatures() {\n if (!this.hasCert()) {\n return {}\n }\n\n return this.currentFeatures ?? {}\n }\n\n getCurrentEntitlements() {\n if (!this.hasCert()) {\n return []\n }\n\n const now = new Date()\n\n return this.licenseCert.entitlements.filter(\n (entitlement) => entitlement.validFrom <= now && entitlement.validTo > now\n )\n }\n\n getManagementJwt() {\n if (!this.licenseCert) {\n return ''\n }\n\n return this.licenseCert.managementJwt\n }\n\n async getCertStr(): Promise<TLicenseBlock> {\n return this.config.loadCertStr()\n }\n\n getConsumerId() {\n return this.licenseCert?.consumerId\n }\n\n isRenewalDue(): boolean {\n if (!this.licenseCert || this.licenseCert.isEphemeral) {\n return false\n }\n\n const now = Date.now()\n const mins15inMs = 1000 * 60 * 15\n const mins20inMs = 1000 * 60 * 20\n const expiry = this.licenseCert.expiresAt.getTime()\n const issuedAt = this.licenseCert.issuedAt.getTime()\n const termination = this.licenseCert.terminatesAt.getTime()\n\n //consumerRenewalDue is TRUE when current time is close enough to consumer expiry and not after consumer termination\n const consumerRenewalDue =\n now > expiry - this.config.autoRenewOffset! * 1000 && now < termination\n\n //entitlementRenewalDue is TRUE when one currently valid entitlement will expire in the next 15 minutes\n //and the Cert was issued more than 20 minutes ago\n const entitlementRenewalDue =\n this.getCurrentEntitlements().find(\n (entitlement) =>\n now >= entitlement.validTo.getTime() - mins15inMs &&\n now <= entitlement.validTo.getTime()\n ) !== undefined && issuedAt < now - mins20inMs\n\n return consumerRenewalDue || entitlementRenewalDue\n }\n\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const remainingSeconds = seconds % 60\n\n return `${hours}h ${minutes}m ${remainingSeconds}s`\n }\n\n toString() {\n return (\n `## CONSUMER CONFIG ##\\n` +\n `tenantId: ${this.config.tenantId ?? '<n/a>'}\\n` +\n `productIdentifier: ${this.config.productIdentifier ?? '<n/a>'}\\n` +\n `deviceFingerprint: ${this.deviceFingerprint ?? '<n/a>'}\\n` +\n `autoRenewalEnabled: ${\n this.config.autoRenewEnabled ? 'true' : 'false (!)'\n }\\n` +\n `autoRenewalOffset: ${\n this.config.autoRenewOffset\n } (= ${this.formatDuration(this.config.autoRenewOffset ?? 0)})\\n` +\n '--\\n' +\n `## LICENSE CERT ##\\n` +\n `version: ${this.licenseCert?.version ?? '<n/a>'}\\n` +\n `tenantId: ${this.licenseCert?.tenantId ?? '<n/a>'} ${\n this.licenseCert?.tenantId !== this.config.tenantId ? '(!)' : ''\n }\\n` +\n `consumerId: ${this.licenseCert?.consumerId ?? '<n/a>'}\\n` +\n `deviceFingerprint: ${this.licenseCert?.deviceFingerprint ?? '<n/a>'} ${\n this.licenseCert?.deviceFingerprint !== this.deviceFingerprint\n ? '(!)'\n : ''\n }\\n` +\n `createdAt: ${this.licenseCert?.createdAt ?? '<n/a>'}\\n` +\n `issuedAt: ${this.licenseCert?.issuedAt ?? '<n/a>'}\\n` +\n `expiresAt: ${this.licenseCert?.expiresAt ?? '<n/a>'}\\n` +\n `terminatesAt: ${this.licenseCert?.terminatesAt ?? '<n/a>'}\\n` +\n `isEphemeral: ${this.licenseCert?.isEphemeral ?? '<n/a>'}\\n` +\n `isValid: ${this.isValid(false)}\\n` +\n `isRenewalDue: ${this.isRenewalDue()}\\n` +\n `detachedEntitlementsCount: ${\n this.licenseCert?.detachedEntitlementsCount ?? '<n/a>'\n }\\n` +\n `entitlements: ${this.licenseCert?.entitlements.length ?? 0}\\n` +\n this.licenseCert?.entitlements\n .map((entitlement, index) => {\n return (\n '--\\n' +\n `## ENTITLEMENT ${index + 1} ##\\n` +\n `id: ${entitlement.id}\\n` +\n `productId: ${entitlement.productId}\\n` +\n `validFrom: ${entitlement.validFrom}\\n` +\n `validTo: ${entitlement.validTo}\\n` +\n `features: ${JSON.stringify(entitlement.features)}\\n` +\n `featureOverrides: ${JSON.stringify(\n entitlement.featureOverrides\n )}\\n`\n )\n })\n .join('')\n )\n }\n\n private triggerOnFeatureChangeCallback() {\n if (this.config.onFeatureChange) {\n this.config.onFeatureChange(this.currentFeatures ?? {})\n }\n }\n\n private setTimerForNextEntitlementChange() {\n if (!this.hasCert()) {\n return\n }\n\n const now = Date.now()\n const offsets = new Set<number>()\n\n offsets.add(this.licenseCert.expiresAt.getTime() - now)\n offsets.add(this.licenseCert.terminatesAt.getTime() - now)\n\n const upcomingEventOffsets = [\n ...this.licenseCert.entitlements.reduce((offsets, entitlement) => {\n offsets.add(entitlement.validFrom.getTime() - now)\n offsets.add(entitlement.validTo.getTime() - now)\n return offsets\n }, offsets),\n ]\n .filter((offset) => offset >= 0 && offset <= AUTORENEWAL_INTERVAL) // keep if offset is within the next 15 minutes\n .sort((a, b) => a - b)\n\n //console.dir(upcomingEventOffsets.map((offset) => offset / 1000 / 60))\n\n if (upcomingEventOffsets.length === 0) {\n return\n }\n\n const timeTillNextEventInMs = upcomingEventOffsets[0]\n\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = this.setupSingleTimer(() => {\n this.updateCurrentFeatures()\n this.triggerOnFeatureChangeCallback()\n this.setTimerForNextEntitlementChange()\n }, timeTillNextEventInMs + 1000)\n }\n\n private async renewalCron({ force }: { force: boolean }) {\n if (force || this.isRenewalDue()) {\n this.log('attempting license renewal', LogLevel.DEBUG)\n try {\n await this._renew({ cause: force ? 'startup' : 'auto' })\n } catch (e) {}\n }\n }\n\n private async initCert() {\n if (this.isShuttingDown) {\n return\n }\n\n try {\n const containerStr = await this.getCertStr()\n if (!containerStr) {\n this.licenseCert = undefined\n return\n }\n if (containerStr.length < 50) {\n throw new Error('cert string is undefined or too short')\n }\n const { x509, licenseKey } =\n this.parseLicenseCertContainerStr(containerStr)\n this.x509Cert = new X509Certificate(x509)\n const hasApprovedIssuer = this.x509Cert.checkIssued(this.getIssuerCert())\n if (!hasApprovedIssuer) {\n throw new Error('cert was not issued by an approved issuer')\n }\n const publicKey = this.x509Cert.publicKey.export({\n format: 'pem',\n type: 'pkcs1',\n })\n this.key = new NodeRSA(publicKey)\n this.licenseCert = this.parseLicenseKeyStr(licenseKey)\n this.updateCurrentFeatures()\n this.setTimerForNextEntitlementChange()\n } catch (e) {\n this.log(\n `cert could not be initialized. ${e instanceof Error ? e.message : ''}`,\n LogLevel.ERROR\n )\n }\n }\n\n private stringifyCertContainer(container: TLicenseContainer): string {\n const containerStr = JSON.stringify(container)\n return Buffer.from(containerStr).toString('base64')\n }\n\n private parseLicenseCertContainerStr(\n stringifiedContainer: string\n ): TLicenseContainer {\n const containerStr = Buffer.from(stringifiedContainer, 'base64').toString(\n 'ascii'\n )\n const container = JSON.parse(containerStr)\n if (\n !container.hasOwnProperty('licenseKey') ||\n !container.hasOwnProperty('x509')\n ) {\n throw new Error('license cert container could not be parsed')\n }\n\n return container as TLicenseContainer\n }\n\n private parseLicenseKeyStr(certStr: string): TLicenseCertObj {\n const certPayload = this.validateLicenseKey(certStr)\n\n const cert = { ...certPayload } as TLicenseCertObj\n\n // turn timestamp strings into Date objects\n cert.createdAt = new Date(certPayload.createdAt)\n cert.issuedAt = new Date(certPayload.issuedAt)\n cert.expiresAt = new Date(certPayload.expiresAt)\n cert.terminatesAt = new Date(certPayload.terminatesAt)\n\n // make sure detachedEntitlementsCount is a number (certs issues before this field was introduced will have it missing)\n cert.detachedEntitlementsCount = certPayload.detachedEntitlementsCount ?? 0\n\n cert.entitlements = cert.entitlements.map((entitlement) => {\n entitlement.validFrom = new Date(entitlement.validFrom)\n entitlement.validTo = new Date(entitlement.validTo)\n return entitlement\n })\n\n return cert\n }\n\n private validateLicenseKey(licenseKey: string) {\n //remove all line breaks\n licenseKey = licenseKey.replace(/(\\r\\n|\\n|\\r)/gm, '')\n\n //extract parts\n const match = licenseKey.match(\n /^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\\|\\|)(?<encryptedData>.+)\\|\\|(?<signature>.+)-----END LICENSE KEY-----$/\n )\n\n if (!match) {\n throw new Error('license key could not be parsed')\n }\n\n const encryptedSymmetricKey = match.groups!.encryptedSymmetricKey\n const payload = match.groups!.encryptedData\n const signature = match.groups!.signature\n\n let symmetricKey, decryptedData\n\n //decrypt the random symmetric key\n try {\n symmetricKey = this.key!.decryptPublic(encryptedSymmetricKey, 'utf8')\n } catch (e) {\n throw new Error('Invalid data: Could not extract symmetric key')\n }\n\n //decrypt the payload\n try {\n decryptedData = CryptoJS.AES.decrypt(payload, symmetricKey).toString(\n CryptoJS.enc.Utf8\n )\n } catch (e) {\n throw new Error('Invalid Data: Could not decrypt data with key found')\n }\n\n //verify the signature.\n if (\n this.key!.verify(Buffer.from(decryptedData), signature, 'utf8', 'base64')\n ) {\n //return the decrypted data.\n return JSON.parse(decryptedData)\n } else {\n throw new Error('License Key signature invalid')\n }\n }\n\n public getIssuerCert() {\n return this.x509IssuerCert\n }\n\n /**\n * Detaches any floating entitlements and clears the local license cert.\n */\n public async clear() {\n try {\n await this.detachFloatingEntitlements()\n } catch (err) {\n this.log(\n `failed to detach floating entitlements (${err}). Continuing with clearing license certificate`,\n LogLevel.WARN\n )\n } finally {\n await this.config.saveCertStr('')\n await this.initCert()\n }\n }\n\n public async shutdown() {\n this.isShuttingDown = true\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.clearSingleTimer(this.entitlementChangeTimer)\n\n if (this.config.detachFloatingOnShutdown) {\n await this.detachFloatingEntitlements()\n }\n }\n\n private async detachFloatingEntitlements() {\n if (!this.hasCert()) {\n return\n }\n\n const hasFloatableEntitlements = this.licenseCert.entitlements.some(\n (entitlement) => entitlement.isFloatable ?? false\n )\n\n if (hasFloatableEntitlements) {\n await this._renew({\n detachFloatingEntitlements: true,\n cause: 'shutdown',\n })\n }\n }\n\n /** Enable periodical renewal of the license. */\n public enableAutoRenewals() {\n if (this.config.autoRenewEnabled === true) return\n\n this.config.autoRenewEnabled = true\n this.log('License auto-renewals enabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n\n /** Disable periodical renewal of the license. */\n public disableAutoRenewals() {\n if (this.config.autoRenewEnabled === false) return\n\n this.config.autoRenewEnabled = false\n this.log('License auto-renewals disabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n }\n}\n","import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.0' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.0'\n"],"mappings":"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","names":["LicenseManager_exports","__export","AUTORENEWAL_INTERVAL","LicenseManager","__toCommonJS","import_crypto_js","import_node_machine_id","import_node_rsa","import_node_assert","import_node_crypto","import_undici","import_node_url","SDK_VERSION","getProxyAgent","envVar","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","proxyAgent","response","SDK_VERSION","err","error","AUTORENEWAL_INTERVAL","LicenseManager","config","msg","logLevel","AUTORENEWAL_INTERVAL","callback","interval","timer","date","durationInMs","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","passthroughData","responseData","now","useLogger","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","seconds","hours","minutes","remainingSeconds","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS","err"]}
|
|
1
|
+
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { ok } from 'node:assert'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\n/** How often to consider periodic license renewal (in ms) */\nexport const AUTORENEWAL_INTERVAL = 15 * 60 * 1000 // 15 minutes\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n\n /**\n * Whether to renew the license periodically.\n *\n * @default true\n */\n autoRenewEnabled?: boolean\n /**\n * Whether to return any floatable entitlements to the pool on SDK shutdown.\n *\n * @default true\n */\n detachFloatingOnShutdown?: boolean\n offlineMode?: boolean\n renewOnInit?: boolean\n autoRenewOffset?: number\n loadCertStr: () => Promise<TLicenseBlock>\n saveCertStr: (cert: TLicenseBlock) => Promise<void>\n collectUsageMetrics?: () => Promise<Array<TUsageMetric>>\n collectPassthroughData?: () => Promise<TPassthroughData>\n deviceFingerprint?: () => string | Promise<string>\n onFeatureChange?: (features: TFeatures) => any\n logger?: TLogger\n}\n\nexport type TLicenseBlock = string\n\nexport type TLicenseContainer = {\n licenseKey: string\n x509: string\n}\n\nexport type TFeatures = { [key: string]: boolean | number | string }\n\nexport type TUsageMetric = { name: string; value: number }\n\nexport type TPassthroughData = Record<string, unknown>\n\nexport type TMetadata = {\n [key: string]: boolean | number | string | Array<any> | {}\n}\n\nexport type TEntitlement = {\n id: string\n productId: string\n productMetadata: TMetadata\n features: TFeatures\n featureOverrides: TFeatures\n validFrom: Date\n validTo: Date\n isFloatable: boolean\n}\n\nexport type TLicenseCertObj = {\n consumerId: string\n consumerRef?: string\n version: number\n tenantId: number\n renewalToken: string\n deviceLock: boolean\n deviceFingerprint: string\n createdAt: Date\n issuedAt: Date\n expiresAt: Date\n terminatesAt: Date\n entitlements: TEntitlement[]\n /**\n * Indicates the number of floating entitlements that are not attached to the consumer\n * because they are in use elsewhere at the time of renewal.\n */\n detachedEntitlementsCount: number\n managementJwt: string\n /**\n * Specifies whether the license is ephemeral and therefore does not have corresponding entries in the license server DB.\n */\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\n\ntype SingleTimer = NodeJS.Timeout\ntype RepeatingTimer = NodeJS.Timeout\n\nconst enum LogLevel {\n ERROR = 'error',\n WARN = 'warn',\n INFO = 'info',\n DEBUG = 'debug',\n}\n\nexport class LicenseManager {\n public config: TLicenseManagerConfig\n\n private initializationPromise?: Promise<void>\n private key?: NodeRSA\n private logger: TLogger\n protected licenseCert?: TLicenseCertObj\n private x509Cert?: X509Certificate\n private x509IssuerCert: X509Certificate\n private deviceFingerprint?: string\n private renewalTimer?: RepeatingTimer\n private upcomingEntitlementChangesCheckTimer?: RepeatingTimer\n private entitlementChangeTimer?: SingleTimer\n private currentFeatures?: TFeatures\n private isShuttingDown = false\n\n get isInitialized() {\n return !!this.initializationPromise\n }\n\n constructor(config: TLicenseManagerConfig) {\n this.config = config\n\n if (this.config.logger) {\n this.logger = this.config.logger\n } else {\n this.logger = {\n error() {\n console.log('ERROR:', ...arguments)\n },\n warn() {\n console.log('WARN:', ...arguments)\n },\n info() {\n console.log('INFO:', ...arguments)\n },\n debug() {\n console.log('DEBUG:', ...arguments)\n },\n }\n }\n\n this.x509IssuerCert = new X509Certificate(\n '-----BEGIN CERTIFICATE-----\\n' +\n 'MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE\\n' +\n 'RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp\\n' +\n 'Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL\\n' +\n 'MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw\\n' +\n 'FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\\n' +\n 'AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q\\n' +\n 'IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+\\n' +\n 'btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU\\n' +\n 'zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED\\n' +\n '+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS\\n' +\n 'dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po\\n' +\n 'Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S\\n' +\n '28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM\\n' +\n 'K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs\\n' +\n 'sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL\\n' +\n 'JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ\\n' +\n 'KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8\\n' +\n 'ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3\\n' +\n 'Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl\\n' +\n '/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP\\n' +\n 'Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK\\n' +\n 'LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc\\n' +\n 'Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw\\n' +\n 'uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP\\n' +\n 'A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD\\n' +\n '4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT\\n' +\n '/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ\\n' +\n '-----END CERTIFICATE-----'\n )\n\n //set defaults for not set config properties:\n this.config.autoRenewEnabled = this.config.autoRenewEnabled ?? true\n this.config.renewOnInit = this.config.renewOnInit ?? false\n this.config.offlineMode = this.config.offlineMode ?? false\n this.config.autoRenewOffset = this.config.autoRenewOffset ?? 60 * 60 * 72 // default: 72 hours\n this.config.detachFloatingOnShutdown =\n this.config.detachFloatingOnShutdown ?? true\n this.config.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license SDK] ${msg}`)\n }\n\n async initialize() {\n if (this.initializationPromise) {\n return this.initializationPromise\n }\n\n this.initializationPromise = this._doInitialization()\n\n return await this.initializationPromise\n }\n\n /** Initializes the license manager */\n private async _doInitialization() {\n ok(!this.initializationPromise, 'Initialization already in progress')\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n\n await this.initCert() // doesn't throw!\n\n // Clear and set up periodic timer for entitlement changes\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = this.setupRepeatingTimer(\n () => this.setTimerForNextEntitlementChange(),\n AUTORENEWAL_INTERVAL\n )\n\n // Renew license on init if necessary\n // If detachedEntitlementsCount > 0, renewing is important in order to attempt re-attaching floating entitlements!\n if (\n this.config.renewOnInit &&\n this.config.autoRenewEnabled &&\n this.hasCert() &&\n (this.licenseCert.detachedEntitlementsCount > 0 || this.isRenewalDue())\n ) {\n await this.renewalCron({ force: true })\n } else {\n this.log(\n 'Skipping renewal on init because renewal is not due yet or cert is not initialized',\n LogLevel.INFO\n )\n }\n\n // Set up periodic renewal if enabled\n if (this.config.autoRenewEnabled) {\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n }\n\n private setupSingleTimer(\n callback: () => void,\n interval: number\n ): SingleTimer {\n return setTimeout(callback, interval)\n }\n\n clearSingleTimer(timer: SingleTimer | undefined) {\n if (timer) {\n clearTimeout(timer)\n }\n }\n\n setupRepeatingTimer(callback: () => void, interval: number): RepeatingTimer {\n return setInterval(callback, interval)\n }\n\n clearRepeatingTimer(timer: RepeatingTimer | undefined) {\n if (timer) {\n clearInterval(timer)\n }\n }\n\n private isOlderThan(date: Date, durationInMs: number) {\n return Date.now() - date.getTime() > durationInMs\n }\n\n async reload() {\n await this.reset()\n await this.initialize()\n }\n\n async reset() {\n // Make sure initialization is not ongoing before resetting\n if (this.initializationPromise) {\n await this.initializationPromise\n }\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = undefined\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = undefined\n\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.initializationPromise = undefined\n }\n\n async computeDeviceFingerprint() {\n if (\n this.config.deviceFingerprint &&\n typeof this.config.deviceFingerprint === 'function'\n ) {\n return await this.config.deviceFingerprint()\n }\n return await machineId()\n }\n\n async activate(reservationId: string) {\n if (!this.isInitialized) {\n throw new Error('activation failed because SDK was not yet initialized')\n }\n\n if (this.isShuttingDown) {\n throw new Error('activation failed because SDK is shutting down')\n }\n\n if (this.config.offlineMode) {\n throw new Error('activation failed because SDK is in offline mode')\n }\n\n const postData: {\n reservationId: string\n tenantId: number\n productIdentifier: string\n deviceFingerprint: string\n consumerId?: string\n renewalToken?: string\n } = {\n reservationId,\n tenantId: this.config.tenantId,\n productIdentifier: this.config.productIdentifier,\n deviceFingerprint: this.deviceFingerprint!,\n }\n\n if (this.hasCert()) {\n postData.consumerId = this.licenseCert.consumerId\n postData.renewalToken = this.licenseCert.renewalToken\n }\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<{\n licenseKey?: string\n x509?: string\n message?: string\n errorId?: string\n }>(`${this.config.server!}/activate`, postData, {\n timeoutInMs: 10000,\n productIdentifier: this.config.productIdentifier,\n })\n } catch (error) {\n this.log(\n 'license activation failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n if (response.status == 200) {\n if (\n !response.data.hasOwnProperty('licenseKey') ||\n !response.data.hasOwnProperty('x509')\n ) {\n this.log('unexpected server response', LogLevel.WARN)\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: response.data.licenseKey,\n x509: response.data.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n await this.initCert()\n this.log('license successfully activated', LogLevel.INFO)\n if (response.data.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${response.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n } else {\n const errorMsg = `license activation failed: ${\n response.data.message ?? 'unknown reason'\n }`\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (response.data.errorId) {\n e.errorId = response.data.errorId\n }\n\n this.log(errorMsg, LogLevel.WARN)\n throw e\n }\n }\n\n async renew() {\n return this._renew({ cause: 'request' })\n }\n\n async _renew({\n detachFloatingEntitlements = false,\n cause = 'unknown',\n }: {\n detachFloatingEntitlements?: Boolean\n cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown'\n } = {}) {\n if (!this.hasCert()) {\n throw new Error('renewal failed because current cert is not initialized')\n }\n\n if (this.licenseCert.isEphemeral) {\n return\n }\n\n if (this.isTerminated()) {\n throw new Error('renewal failed because current cert was terminated')\n }\n\n if (this.config.offlineMode) {\n throw new Error('renewal failed because SDK is in offline mode')\n }\n\n if (this.config.tenantId !== this.licenseCert.tenantId) {\n throw new Error('renewal failed because tenant ID does not match')\n }\n\n // error out if device fingerprint does not match but allow renewal on explicit request\n // as the consumer might have been changed to more permissive settings on the server\n if (\n cause !== 'request' &&\n this.licenseCert.deviceLock &&\n this.deviceFingerprint !== this.licenseCert.deviceFingerprint\n ) {\n throw new Error(\n 'renewal failed because device fingerprint does not match'\n )\n }\n\n const [usageMetrics, passthroughData] = await Promise.all([\n this.config.collectUsageMetrics ? this.config.collectUsageMetrics() : [],\n this.config.collectPassthroughData\n ? this.config.collectPassthroughData()\n : {},\n ])\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<ResponseDataFormat>(\n `${this.config.server!}/renew`,\n {\n consumerId: this.licenseCert.consumerId,\n tenantId: this.config.tenantId,\n deviceFingerprint: this.deviceFingerprint,\n productIdentifier: this.config.productIdentifier,\n renewalToken: this.licenseCert.renewalToken,\n detachFloatingEntitlements,\n cause,\n usageMetrics,\n passthroughData,\n },\n { timeoutInMs: 10000, productIdentifier: this.config.productIdentifier }\n )\n } catch (error) {\n this.log(\n 'license renewal failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n const responseData = response.data\n\n if (response.status == 200) {\n if (\n !responseData.hasOwnProperty('licenseKey') ||\n !responseData.hasOwnProperty('x509')\n ) {\n this.log(\n 'license renewal failed: unexpected server response',\n LogLevel.WARN\n )\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: responseData.licenseKey,\n x509: responseData.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n\n this.log('license successfully renewed', LogLevel.INFO)\n\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n if (detachFloatingEntitlements) {\n this.log(\n `${responseData.detachedEntitlementsCount} floating entitlements were returned to the pool`,\n LogLevel.INFO\n )\n } else {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n }\n\n await this.initCert()\n } else {\n const errorMsg = `license renewal failed: ${\n responseData.message ?? 'unknown reason'\n }`\n\n this.log(errorMsg, LogLevel.WARN)\n\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (responseData.errorId) {\n e.errorId = responseData.errorId\n\n if (\n ['NOT_FOUND', 'CONSUMER_TERMINATED'].includes(responseData.errorId)\n ) {\n this.log(\n 'license was terminated by the server. Deleting local cert.',\n LogLevel.WARN\n )\n await this.config.saveCertStr('')\n await this.initCert()\n } else if (responseData.errorId === 'FINGERPRINT_MISMATCH') {\n // pause auto-renewal as subsequent requests will also fail\n this.disableAutoRenewals()\n }\n }\n\n throw e\n }\n }\n\n private hasCert(): this is { licenseCert: TLicenseCertObj } {\n return !!this.licenseCert\n }\n\n isTerminated(): boolean {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n const now = new Date()\n\n return this.licenseCert.terminatesAt < now\n }\n\n getExpiryDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.expiresAt\n }\n\n getTerminationDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.terminatesAt\n }\n\n isValid(useLogger = true): boolean {\n const logError = (msg: string) => {\n if (useLogger) {\n const debugMetadata = this.hasCert()\n ? `: (autorenewalsEnabled: ${this.config.autoRenewEnabled}, expiredAt: ${this.licenseCert?.expiresAt}, issuedAt: ${this.licenseCert?.issuedAt})`\n : ''\n\n this.log(`${msg}${debugMetadata}`, LogLevel.ERROR)\n }\n }\n\n if (!this.hasCert()) {\n logError('cert is invalid because it is undefined')\n return false\n }\n\n const cert = this.licenseCert as TLicenseCertObj\n const now = new Date()\n\n if (cert.expiresAt < now) {\n logError('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n logError('cert is invalid because it was terminated')\n return false\n }\n\n //allow clocks to be out of sync by no more than 300,000 ms / = 5 minutes\n if (cert.createdAt.getTime() - 300000 > now.getTime()) {\n logError('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n logError('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n logError('cert is invalid because tenant ID does not match')\n return false\n }\n\n return true\n }\n\n hasFeatureEnabled(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) ? true : false\n }\n\n hasFeatureDefined(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) !== undefined\n ? true\n : false\n }\n\n hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean {\n const quota = this.getFeatureValue(quotaFeatureName)\n\n if (quota === undefined) {\n return false\n }\n\n if (typeof quota !== 'number') {\n throw new Error(\n `${quotaFeatureName} cannot be used as quota as it is not numeric`\n )\n }\n\n // -1 means unlimited quota!\n if (quota === -1) {\n return true\n }\n\n return Math.ceil(currentConsumption) < Math.ceil(quota)\n }\n\n getFeatureValue(\n feature: string,\n requireValidCert: boolean = true\n ): undefined | boolean | number | string {\n if (!this.hasCert()) {\n return undefined\n }\n\n if (requireValidCert && !this.isValid()) {\n return undefined\n }\n\n const currentFeatures = this.getFeatures()\n\n if (!currentFeatures.hasOwnProperty(feature)) {\n return undefined\n }\n\n return currentFeatures[feature]\n }\n\n private updateCurrentFeatures() {\n if (!this.hasCert()) {\n return\n }\n\n const now = new Date()\n\n if (\n this.licenseCert.expiresAt < now ||\n this.licenseCert.terminatesAt < now\n ) {\n this.currentFeatures = {} as TFeatures\n }\n\n this.currentFeatures = this.licenseCert.entitlements\n .filter(\n (entitlement) =>\n entitlement.validFrom <= now && entitlement.validTo > now\n )\n .sort(\n (entitlement1, entitlement2) =>\n entitlement1.validFrom.getTime() - entitlement2.validFrom.getTime()\n )\n .reduce((currentFeatures, entitlement) => {\n return {\n ...currentFeatures,\n ...entitlement.features,\n ...entitlement.featureOverrides,\n }\n }, {} as TFeatures)\n }\n\n getFeatures() {\n if (!this.hasCert()) {\n return {}\n }\n\n return this.currentFeatures ?? {}\n }\n\n getCurrentEntitlements() {\n if (!this.hasCert()) {\n return []\n }\n\n const now = new Date()\n\n return this.licenseCert.entitlements.filter(\n (entitlement) => entitlement.validFrom <= now && entitlement.validTo > now\n )\n }\n\n getManagementJwt() {\n if (!this.licenseCert) {\n return ''\n }\n\n return this.licenseCert.managementJwt\n }\n\n async getCertStr(): Promise<TLicenseBlock> {\n return this.config.loadCertStr()\n }\n\n getConsumerId() {\n return this.licenseCert?.consumerId\n }\n\n isRenewalDue(): boolean {\n if (!this.licenseCert || this.licenseCert.isEphemeral) {\n return false\n }\n\n const now = Date.now()\n const mins15inMs = 1000 * 60 * 15\n const mins20inMs = 1000 * 60 * 20\n const expiry = this.licenseCert.expiresAt.getTime()\n const issuedAt = this.licenseCert.issuedAt.getTime()\n const termination = this.licenseCert.terminatesAt.getTime()\n\n //consumerRenewalDue is TRUE when current time is close enough to consumer expiry and not after consumer termination\n const consumerRenewalDue =\n now > expiry - this.config.autoRenewOffset! * 1000 && now < termination\n\n //entitlementRenewalDue is TRUE when one currently valid entitlement will expire in the next 15 minutes\n //and the Cert was issued more than 20 minutes ago\n const entitlementRenewalDue =\n this.getCurrentEntitlements().find(\n (entitlement) =>\n now >= entitlement.validTo.getTime() - mins15inMs &&\n now <= entitlement.validTo.getTime()\n ) !== undefined && issuedAt < now - mins20inMs\n\n return consumerRenewalDue || entitlementRenewalDue\n }\n\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const remainingSeconds = seconds % 60\n\n return `${hours}h ${minutes}m ${remainingSeconds}s`\n }\n\n toString() {\n const isValid = this.isValid(false)\n const isRenewalDue = this.isRenewalDue()\n const hasDetachedEntitlements =\n (this.licenseCert?.detachedEntitlementsCount ?? 0) > 0\n\n // Helper function to format values with warnings\n const formatWithWarning = (value: any, condition: any) =>\n `${value}${condition ? ' (!)' : ''}`\n\n // Helper function to display value or default\n const formatValue = (value: any, defaultValue = '<n/a>') =>\n value ?? defaultValue\n\n // Build sections of the output\n const consumerConfig = [\n '## CONSUMER CONFIG ##',\n `tenantId: ${formatValue(this.config.tenantId)}`,\n `productIdentifier: ${formatValue(this.config.productIdentifier)}`,\n `deviceFingerprint: ${formatValue(this.deviceFingerprint)}`,\n `autoRenewalEnabled: ${formatWithWarning(\n this.config.autoRenewEnabled ? 'true' : 'false',\n !this.config.autoRenewEnabled\n )}`,\n `autoRenewalOffset: ${\n this.config.autoRenewOffset\n } (= ${this.formatDuration(this.config.autoRenewOffset ?? 0)})`,\n ].join('\\n')\n\n const licenseCert = [\n '## LICENSE CERT ##',\n `version: ${formatValue(this.licenseCert?.version)}`,\n `tenantId: ${formatWithWarning(\n formatValue(this.licenseCert?.tenantId),\n this.licenseCert?.tenantId !== this.config.tenantId\n )}`,\n `consumerId: ${formatValue(this.licenseCert?.consumerId)}`,\n `deviceFingerprint: ${formatWithWarning(\n formatValue(this.licenseCert?.deviceFingerprint),\n this.licenseCert?.deviceFingerprint !== this.deviceFingerprint\n )}`,\n `createdAt: ${formatValue(this.licenseCert?.createdAt)}`,\n `issuedAt: ${formatValue(this.licenseCert?.issuedAt)}`,\n `expiresAt: ${formatValue(this.licenseCert?.expiresAt)}`,\n `terminatesAt: ${formatValue(this.licenseCert?.terminatesAt)}`,\n `isEphemeral: ${formatValue(this.licenseCert?.isEphemeral)}`,\n `isValid: ${formatWithWarning(isValid, !isValid)}`,\n `isRenewalDue: ${formatWithWarning(isRenewalDue, isRenewalDue)}`,\n `detachedEntitlementsCount: ${formatWithWarning(\n formatValue(this.licenseCert?.detachedEntitlementsCount),\n hasDetachedEntitlements\n )}`,\n `entitlements: ${this.licenseCert?.entitlements?.length ?? 0}`,\n ].join('\\n')\n\n // Format entitlements\n const entitlements =\n this.licenseCert?.entitlements\n ?.map((entitlement, index) =>\n [\n '## ENTITLEMENT ' + (index + 1) + ' ##',\n `id: ${entitlement.id}`,\n `productId: ${entitlement.productId}`,\n `validFrom: ${entitlement.validFrom}`,\n `validTo: ${entitlement.validTo}`,\n `features: ${JSON.stringify(entitlement.features)}`,\n `featureOverrides: ${JSON.stringify(entitlement.featureOverrides)}`,\n ].join('\\n')\n )\n .join('\\n--\\n') || ''\n\n // Combine all sections with proper separators\n return [\n consumerConfig,\n '--',\n licenseCert,\n entitlements ? '--\\n' + entitlements : '',\n ].join('\\n')\n }\n\n private triggerOnFeatureChangeCallback() {\n if (this.config.onFeatureChange) {\n this.config.onFeatureChange(this.currentFeatures ?? {})\n }\n }\n\n private setTimerForNextEntitlementChange() {\n if (!this.hasCert()) {\n return\n }\n\n const now = Date.now()\n const offsets = new Set<number>()\n\n offsets.add(this.licenseCert.expiresAt.getTime() - now)\n offsets.add(this.licenseCert.terminatesAt.getTime() - now)\n\n const upcomingEventOffsets = [\n ...this.licenseCert.entitlements.reduce((offsets, entitlement) => {\n offsets.add(entitlement.validFrom.getTime() - now)\n offsets.add(entitlement.validTo.getTime() - now)\n return offsets\n }, offsets),\n ]\n .filter((offset) => offset >= 0 && offset <= AUTORENEWAL_INTERVAL) // keep if offset is within the next 15 minutes\n .sort((a, b) => a - b)\n\n //console.dir(upcomingEventOffsets.map((offset) => offset / 1000 / 60))\n\n if (upcomingEventOffsets.length === 0) {\n return\n }\n\n const timeTillNextEventInMs = upcomingEventOffsets[0]\n\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = this.setupSingleTimer(() => {\n this.updateCurrentFeatures()\n this.triggerOnFeatureChangeCallback()\n this.setTimerForNextEntitlementChange()\n }, timeTillNextEventInMs + 1000)\n }\n\n private async renewalCron({ force }: { force: boolean }) {\n if (force || this.isRenewalDue()) {\n this.log('attempting license renewal', LogLevel.INFO)\n try {\n await this._renew({ cause: force ? 'startup' : 'auto' })\n } catch (e) {}\n }\n }\n\n private async initCert() {\n if (this.isShuttingDown) {\n return\n }\n\n try {\n const containerStr = await this.getCertStr()\n if (!containerStr) {\n this.licenseCert = undefined\n return\n }\n if (containerStr.length < 50) {\n throw new Error('cert string is undefined or too short')\n }\n const { x509, licenseKey } =\n this.parseLicenseCertContainerStr(containerStr)\n this.x509Cert = new X509Certificate(x509)\n const hasApprovedIssuer = this.x509Cert.checkIssued(this.getIssuerCert())\n if (!hasApprovedIssuer) {\n throw new Error('cert was not issued by an approved issuer')\n }\n const publicKey = this.x509Cert.publicKey.export({\n format: 'pem',\n type: 'pkcs1',\n })\n this.key = new NodeRSA(publicKey)\n this.licenseCert = this.parseLicenseKeyStr(licenseKey)\n this.updateCurrentFeatures()\n this.setTimerForNextEntitlementChange()\n } catch (e) {\n this.log(\n `cert could not be initialized. ${e instanceof Error ? e.message : ''}`,\n LogLevel.ERROR\n )\n }\n }\n\n private stringifyCertContainer(container: TLicenseContainer): string {\n const containerStr = JSON.stringify(container)\n return Buffer.from(containerStr).toString('base64')\n }\n\n private parseLicenseCertContainerStr(\n stringifiedContainer: string\n ): TLicenseContainer {\n const containerStr = Buffer.from(stringifiedContainer, 'base64').toString(\n 'ascii'\n )\n const container = JSON.parse(containerStr)\n if (\n !container.hasOwnProperty('licenseKey') ||\n !container.hasOwnProperty('x509')\n ) {\n throw new Error('license cert container could not be parsed')\n }\n\n return container as TLicenseContainer\n }\n\n private parseLicenseKeyStr(certStr: string): TLicenseCertObj {\n const certPayload = this.validateLicenseKey(certStr)\n\n const cert = { ...certPayload } as TLicenseCertObj\n\n // turn timestamp strings into Date objects\n cert.createdAt = new Date(certPayload.createdAt)\n cert.issuedAt = new Date(certPayload.issuedAt)\n cert.expiresAt = new Date(certPayload.expiresAt)\n cert.terminatesAt = new Date(certPayload.terminatesAt)\n\n // make sure detachedEntitlementsCount is a number (certs issues before this field was introduced will have it missing)\n cert.detachedEntitlementsCount = certPayload.detachedEntitlementsCount ?? 0\n\n cert.entitlements = cert.entitlements.map((entitlement) => {\n entitlement.validFrom = new Date(entitlement.validFrom)\n entitlement.validTo = new Date(entitlement.validTo)\n return entitlement\n })\n\n return cert\n }\n\n private validateLicenseKey(licenseKey: string) {\n //remove all line breaks\n licenseKey = licenseKey.replace(/(\\r\\n|\\n|\\r)/gm, '')\n\n //extract parts\n const match = licenseKey.match(\n /^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\\|\\|)(?<encryptedData>.+)\\|\\|(?<signature>.+)-----END LICENSE KEY-----$/\n )\n\n if (!match) {\n throw new Error('license key could not be parsed')\n }\n\n const encryptedSymmetricKey = match.groups!.encryptedSymmetricKey\n const payload = match.groups!.encryptedData\n const signature = match.groups!.signature\n\n let symmetricKey, decryptedData\n\n //decrypt the random symmetric key\n try {\n symmetricKey = this.key!.decryptPublic(encryptedSymmetricKey, 'utf8')\n } catch (e) {\n throw new Error('Invalid data: Could not extract symmetric key')\n }\n\n //decrypt the payload\n try {\n decryptedData = CryptoJS.AES.decrypt(payload, symmetricKey).toString(\n CryptoJS.enc.Utf8\n )\n } catch (e) {\n throw new Error('Invalid Data: Could not decrypt data with key found')\n }\n\n //verify the signature.\n if (\n this.key!.verify(Buffer.from(decryptedData), signature, 'utf8', 'base64')\n ) {\n //return the decrypted data.\n return JSON.parse(decryptedData)\n } else {\n throw new Error('License Key signature invalid')\n }\n }\n\n public getIssuerCert() {\n return this.x509IssuerCert\n }\n\n /**\n * Detaches any floating entitlements and clears the local license cert.\n */\n public async clear() {\n try {\n await this.detachFloatingEntitlements()\n } catch (err) {\n this.log(\n `failed to detach floating entitlements (${err}). Continuing with clearing license certificate`,\n LogLevel.WARN\n )\n } finally {\n await this.config.saveCertStr('')\n await this.initCert()\n }\n }\n\n public async shutdown() {\n this.isShuttingDown = true\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.clearSingleTimer(this.entitlementChangeTimer)\n\n if (this.config.detachFloatingOnShutdown) {\n await this.detachFloatingEntitlements()\n }\n }\n\n private async detachFloatingEntitlements() {\n if (!this.hasCert()) {\n return\n }\n\n const hasFloatableEntitlements = this.licenseCert.entitlements.some(\n (entitlement) => entitlement.isFloatable ?? false\n )\n\n if (hasFloatableEntitlements) {\n await this._renew({\n detachFloatingEntitlements: true,\n cause: 'shutdown',\n })\n }\n }\n\n /** Enable periodical renewal of the license. */\n public enableAutoRenewals() {\n if (this.config.autoRenewEnabled === true) return\n\n this.config.autoRenewEnabled = true\n this.log('License auto-renewals enabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n\n /** Disable periodical renewal of the license. */\n public disableAutoRenewals() {\n if (this.config.autoRenewEnabled === false) return\n\n this.config.autoRenewEnabled = false\n this.log('License auto-renewals disabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n }\n}\n","import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.1' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.1'\n"],"mappings":"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","names":["LicenseManager_exports","__export","AUTORENEWAL_INTERVAL","LicenseManager","__toCommonJS","import_crypto_js","import_node_machine_id","import_node_rsa","import_node_assert","import_node_crypto","import_undici","import_node_url","SDK_VERSION","getProxyAgent","envVar","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","proxyAgent","response","SDK_VERSION","err","error","AUTORENEWAL_INTERVAL","LicenseManager","config","msg","logLevel","AUTORENEWAL_INTERVAL","callback","interval","timer","date","durationInMs","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","passthroughData","responseData","now","useLogger","logError","debugMetadata","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","seconds","hours","minutes","remainingSeconds","isValid","isRenewalDue","hasDetachedEntitlements","formatWithWarning","value","condition","formatValue","defaultValue","consumerConfig","licenseCert","entitlements","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS","err"]}
|
package/dist/LicenseManager.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import w from"crypto-js";import{machineId as F}from"node-machine-id";import A from"node-rsa";import{ok as D}from"node:assert";import{X509Certificate as C}from"node:crypto";import{fetch as y,ProxyAgent as T}from"undici";import{URL as E}from"node:url";var p="2.20.1";function u(c){let e=process.env[c]||process.env[c.toUpperCase()];return e?new T(e):!1}var g=u("http_proxy_license_server")||u("http_proxy"),f=u("https_proxy_license_server")||u("https_proxy"),I={...g?{"http:":g}:{},...f?{"https:":f}:{}},R=((process.env.no_proxy||process.env.NO_PROXY)??"").split(",").map(c=>c.trim()).filter(c=>c.length>0),b=c=>{let{host:e,protocol:t}=c;return!(t==="http:"&&!g||t==="https:"&&!f||R.some(i=>e.endsWith(i)))};async function m(c,e,t={}){let i=new E(c),r;b(i)&&(r=I[i.protocol]);try{let n=await y(c,{method:"POST",body:JSON.stringify(e),headers:{"Content-Type":"application/json","User-Agent":`License-SDK/${p} (Node.js ${process.version}; ${process.platform}) ${t.productIdentifier??""}`},signal:AbortSignal.timeout(t.timeoutInMs??3e4),...r?{dispatcher:r}:{}});return{status:n.status,data:await n.json()}}catch(n){let s=new Error("Connection Error: "+n.message);throw s.cause=n,s}}var d=15*60*1e3;var v=class{constructor(e){this.isShuttingDown=!1;this.config=e,this.config.logger?this.logger=this.config.logger:this.logger={error(){console.log("ERROR:",...arguments)},warn(){console.log("WARN:",...arguments)},info(){console.log("INFO:",...arguments)},debug(){console.log("DEBUG:",...arguments)}},this.x509IssuerCert=new C(`-----BEGIN CERTIFICATE-----
|
|
2
2
|
MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE
|
|
3
3
|
RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp
|
|
4
4
|
Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL
|
|
@@ -26,34 +26,12 @@ uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP
|
|
|
26
26
|
A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD
|
|
27
27
|
4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT
|
|
28
28
|
/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ
|
|
29
|
-
-----END CERTIFICATE-----`),this.config.autoRenewEnabled=this.config.autoRenewEnabled??!0,this.config.renewOnInit=this.config.renewOnInit??!1,this.config.offlineMode=this.config.offlineMode??!1,this.config.autoRenewOffset=this.config.autoRenewOffset??60*60*72,this.config.detachFloatingOnShutdown=this.config.detachFloatingOnShutdown??!0,this.config.server=this.config.server??"https://license.n8n.io/v1"}get isInitialized(){return!!this.initializationPromise}log(e,t){this.logger[t](`[license SDK] ${e}`)}async initialize(){return this.initializationPromise?this.initializationPromise:(this.initializationPromise=this._doInitialization(),await this.initializationPromise)}async _doInitialization(){
|
|
30
|
-
tenantId: ${this.config.tenantId
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
autoRenewalEnabled: ${this.config.autoRenewEnabled?"true":"false (!)"}
|
|
34
|
-
autoRenewalOffset: ${this.config.autoRenewOffset} (= ${this.formatDuration(this.config.autoRenewOffset??0)})
|
|
29
|
+
-----END CERTIFICATE-----`),this.config.autoRenewEnabled=this.config.autoRenewEnabled??!0,this.config.renewOnInit=this.config.renewOnInit??!1,this.config.offlineMode=this.config.offlineMode??!1,this.config.autoRenewOffset=this.config.autoRenewOffset??60*60*72,this.config.detachFloatingOnShutdown=this.config.detachFloatingOnShutdown??!0,this.config.server=this.config.server??"https://license.n8n.io/v1"}get isInitialized(){return!!this.initializationPromise}log(e,t){this.logger[t](`[license SDK] ${e}`)}async initialize(){return this.initializationPromise?this.initializationPromise:(this.initializationPromise=this._doInitialization(),await this.initializationPromise)}async _doInitialization(){D(!this.initializationPromise,"Initialization already in progress"),this.deviceFingerprint=await this.computeDeviceFingerprint(),this.log(`initializing for deviceFingerprint ${this.deviceFingerprint}`,"debug"),await this.initCert(),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.upcomingEntitlementChangesCheckTimer=this.setupRepeatingTimer(()=>this.setTimerForNextEntitlementChange(),d),this.config.renewOnInit&&this.config.autoRenewEnabled&&this.hasCert()&&(this.licenseCert.detachedEntitlementsCount>0||this.isRenewalDue())?await this.renewalCron({force:!0}):this.log("Skipping renewal on init because renewal is not due yet or cert is not initialized","info"),this.config.autoRenewEnabled&&(this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),d))}setupSingleTimer(e,t){return setTimeout(e,t)}clearSingleTimer(e){e&&clearTimeout(e)}setupRepeatingTimer(e,t){return setInterval(e,t)}clearRepeatingTimer(e){e&&clearInterval(e)}isOlderThan(e,t){return Date.now()-e.getTime()>t}async reload(){await this.reset(),await this.initialize()}async reset(){this.initializationPromise&&await this.initializationPromise,this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0,this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.upcomingEntitlementChangesCheckTimer=void 0,this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=void 0,this.licenseCert=void 0,this.deviceFingerprint=void 0,this.initializationPromise=void 0}async computeDeviceFingerprint(){return this.config.deviceFingerprint&&typeof this.config.deviceFingerprint=="function"?await this.config.deviceFingerprint():await F()}async activate(e){if(!this.isInitialized)throw new Error("activation failed because SDK was not yet initialized");if(this.isShuttingDown)throw new Error("activation failed because SDK is shutting down");if(this.config.offlineMode)throw new Error("activation failed because SDK is in offline mode");let t={reservationId:e,tenantId:this.config.tenantId,productIdentifier:this.config.productIdentifier,deviceFingerprint:this.deviceFingerprint};this.hasCert()&&(t.consumerId=this.licenseCert.consumerId,t.renewalToken=this.licenseCert.renewalToken);let i;try{i=await m(`${this.config.server}/activate`,t,{timeoutInMs:1e4,productIdentifier:this.config.productIdentifier})}catch(r){throw this.log("license activation failed: "+r.message,"warn"),new Error(r.message)}if(i.status==200){if(!i.data.hasOwnProperty("licenseKey")||!i.data.hasOwnProperty("x509"))throw this.log("unexpected server response","warn"),new Error("unexpected server response");let r=this.stringifyCertContainer({licenseKey:i.data.licenseKey,x509:i.data.x509});await this.config.saveCertStr(r),await this.initCert(),this.log("license successfully activated","info"),(i.data.detachedEntitlementsCount??!1)&&this.log(`skipped importing ${i.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,"info")}else{let r=`license activation failed: ${i.data.message??"unknown reason"}`,n=new Error(r);throw i.data.errorId&&(n.errorId=i.data.errorId),this.log(r,"warn"),n}}async renew(){return this._renew({cause:"request"})}async _renew({detachFloatingEntitlements:e=!1,cause:t="unknown"}={}){if(!this.hasCert())throw new Error("renewal failed because current cert is not initialized");if(this.licenseCert.isEphemeral)return;if(this.isTerminated())throw new Error("renewal failed because current cert was terminated");if(this.config.offlineMode)throw new Error("renewal failed because SDK is in offline mode");if(this.config.tenantId!==this.licenseCert.tenantId)throw new Error("renewal failed because tenant ID does not match");if(t!=="request"&&this.licenseCert.deviceLock&&this.deviceFingerprint!==this.licenseCert.deviceFingerprint)throw new Error("renewal failed because device fingerprint does not match");let[i,r]=await Promise.all([this.config.collectUsageMetrics?this.config.collectUsageMetrics():[],this.config.collectPassthroughData?this.config.collectPassthroughData():{}]),n;try{n=await m(`${this.config.server}/renew`,{consumerId:this.licenseCert.consumerId,tenantId:this.config.tenantId,deviceFingerprint:this.deviceFingerprint,productIdentifier:this.config.productIdentifier,renewalToken:this.licenseCert.renewalToken,detachFloatingEntitlements:e,cause:t,usageMetrics:i,passthroughData:r},{timeoutInMs:1e4,productIdentifier:this.config.productIdentifier})}catch(a){throw this.log("license renewal failed: "+a.message,"warn"),new Error(a.message)}let s=n.data;if(n.status==200){if(!s.hasOwnProperty("licenseKey")||!s.hasOwnProperty("x509"))throw this.log("license renewal failed: unexpected server response","warn"),new Error("unexpected server response");let a=this.stringifyCertContainer({licenseKey:s.licenseKey,x509:s.x509});await this.config.saveCertStr(a),this.log("license successfully renewed","info"),(s.detachedEntitlementsCount??!1)&&(e?this.log(`${s.detachedEntitlementsCount} floating entitlements were returned to the pool`,"info"):this.log(`skipped importing ${s.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,"info")),await this.initCert()}else{let a=`license renewal failed: ${s.message??"unknown reason"}`;this.log(a,"warn");let l=new Error(a);throw s.errorId&&(l.errorId=s.errorId,["NOT_FOUND","CONSUMER_TERMINATED"].includes(s.errorId)?(this.log("license was terminated by the server. Deleting local cert.","warn"),await this.config.saveCertStr(""),await this.initCert()):s.errorId==="FINGERPRINT_MISMATCH"&&this.disableAutoRenewals()),l}}hasCert(){return!!this.licenseCert}isTerminated(){if(!this.hasCert())throw new Error("Cert is not initialized");let e=new Date;return this.licenseCert.terminatesAt<e}getExpiryDate(){if(!this.hasCert())throw new Error("Cert is not initialized");return this.licenseCert.expiresAt}getTerminationDate(){if(!this.hasCert())throw new Error("Cert is not initialized");return this.licenseCert.terminatesAt}isValid(e=!0){let t=n=>{if(e){let s=this.hasCert()?`: (autorenewalsEnabled: ${this.config.autoRenewEnabled}, expiredAt: ${this.licenseCert?.expiresAt}, issuedAt: ${this.licenseCert?.issuedAt})`:"";this.log(`${n}${s}`,"error")}};if(!this.hasCert())return t("cert is invalid because it is undefined"),!1;let i=this.licenseCert,r=new Date;return i.expiresAt<r?(t("cert is invalid because it has expired"),!1):i.terminatesAt<r?(t("cert is invalid because it was terminated"),!1):i.createdAt.getTime()-3e5>r.getTime()?(t("cert is invalid because system clock is out of sync"),!1):i.deviceLock&&this.deviceFingerprint!==i.deviceFingerprint?(t("cert is invalid because device fingerprint does not match"),!1):this.config.tenantId!==i.tenantId?(t("cert is invalid because tenant ID does not match"),!1):!0}hasFeatureEnabled(e,t=!0){return!!this.getFeatureValue(e,t)}hasFeatureDefined(e,t=!0){return this.getFeatureValue(e,t)!==void 0}hasQuotaLeft(e,t){let i=this.getFeatureValue(e);if(i===void 0)return!1;if(typeof i!="number")throw new Error(`${e} cannot be used as quota as it is not numeric`);return i===-1?!0:Math.ceil(t)<Math.ceil(i)}getFeatureValue(e,t=!0){if(!this.hasCert()||t&&!this.isValid())return;let i=this.getFeatures();if(i.hasOwnProperty(e))return i[e]}updateCurrentFeatures(){if(!this.hasCert())return;let e=new Date;(this.licenseCert.expiresAt<e||this.licenseCert.terminatesAt<e)&&(this.currentFeatures={}),this.currentFeatures=this.licenseCert.entitlements.filter(t=>t.validFrom<=e&&t.validTo>e).sort((t,i)=>t.validFrom.getTime()-i.validFrom.getTime()).reduce((t,i)=>({...t,...i.features,...i.featureOverrides}),{})}getFeatures(){return this.hasCert()?this.currentFeatures??{}:{}}getCurrentEntitlements(){if(!this.hasCert())return[];let e=new Date;return this.licenseCert.entitlements.filter(t=>t.validFrom<=e&&t.validTo>e)}getManagementJwt(){return this.licenseCert?this.licenseCert.managementJwt:""}async getCertStr(){return this.config.loadCertStr()}getConsumerId(){return this.licenseCert?.consumerId}isRenewalDue(){if(!this.licenseCert||this.licenseCert.isEphemeral)return!1;let e=Date.now(),t=1e3*60*15,i=1e3*60*20,r=this.licenseCert.expiresAt.getTime(),n=this.licenseCert.issuedAt.getTime(),s=this.licenseCert.terminatesAt.getTime(),a=e>r-this.config.autoRenewOffset*1e3&&e<s,l=this.getCurrentEntitlements().find(o=>e>=o.validTo.getTime()-t&&e<=o.validTo.getTime())!==void 0&&n<e-i;return a||l}formatDuration(e){let t=Math.floor(e/3600),i=Math.floor(e%3600/60),r=e%60;return`${t}h ${i}m ${r}s`}toString(){let e=this.isValid(!1),t=this.isRenewalDue(),i=(this.licenseCert?.detachedEntitlementsCount??0)>0,r=(o,h)=>`${o}${h?" (!)":""}`,n=(o,h="<n/a>")=>o??h,s=["## CONSUMER CONFIG ##",`tenantId: ${n(this.config.tenantId)}`,`productIdentifier: ${n(this.config.productIdentifier)}`,`deviceFingerprint: ${n(this.deviceFingerprint)}`,`autoRenewalEnabled: ${r(this.config.autoRenewEnabled?"true":"false",!this.config.autoRenewEnabled)}`,`autoRenewalOffset: ${this.config.autoRenewOffset} (= ${this.formatDuration(this.config.autoRenewOffset??0)})`].join(`
|
|
30
|
+
`),a=["## LICENSE CERT ##",`version: ${n(this.licenseCert?.version)}`,`tenantId: ${r(n(this.licenseCert?.tenantId),this.licenseCert?.tenantId!==this.config.tenantId)}`,`consumerId: ${n(this.licenseCert?.consumerId)}`,`deviceFingerprint: ${r(n(this.licenseCert?.deviceFingerprint),this.licenseCert?.deviceFingerprint!==this.deviceFingerprint)}`,`createdAt: ${n(this.licenseCert?.createdAt)}`,`issuedAt: ${n(this.licenseCert?.issuedAt)}`,`expiresAt: ${n(this.licenseCert?.expiresAt)}`,`terminatesAt: ${n(this.licenseCert?.terminatesAt)}`,`isEphemeral: ${n(this.licenseCert?.isEphemeral)}`,`isValid: ${r(e,!e)}`,`isRenewalDue: ${r(t,t)}`,`detachedEntitlementsCount: ${r(n(this.licenseCert?.detachedEntitlementsCount),i)}`,`entitlements: ${this.licenseCert?.entitlements?.length??0}`].join(`
|
|
31
|
+
`),l=this.licenseCert?.entitlements?.map((o,h)=>["## ENTITLEMENT "+(h+1)+" ##",`id: ${o.id}`,`productId: ${o.productId}`,`validFrom: ${o.validFrom}`,`validTo: ${o.validTo}`,`features: ${JSON.stringify(o.features)}`,`featureOverrides: ${JSON.stringify(o.featureOverrides)}`].join(`
|
|
32
|
+
`)).join(`
|
|
35
33
|
--
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
consumerId: ${this.licenseCert?.consumerId??"<n/a>"}
|
|
40
|
-
deviceFingerprint: ${this.licenseCert?.deviceFingerprint??"<n/a>"} ${this.licenseCert?.deviceFingerprint!==this.deviceFingerprint?"(!)":""}
|
|
41
|
-
createdAt: ${this.licenseCert?.createdAt??"<n/a>"}
|
|
42
|
-
issuedAt: ${this.licenseCert?.issuedAt??"<n/a>"}
|
|
43
|
-
expiresAt: ${this.licenseCert?.expiresAt??"<n/a>"}
|
|
44
|
-
terminatesAt: ${this.licenseCert?.terminatesAt??"<n/a>"}
|
|
45
|
-
isEphemeral: ${this.licenseCert?.isEphemeral??"<n/a>"}
|
|
46
|
-
isValid: ${this.isValid(!1)}
|
|
47
|
-
isRenewalDue: ${this.isRenewalDue()}
|
|
48
|
-
detachedEntitlementsCount: ${this.licenseCert?.detachedEntitlementsCount??"<n/a>"}
|
|
49
|
-
entitlements: ${this.licenseCert?.entitlements.length??0}
|
|
50
|
-
`+this.licenseCert?.entitlements.map((e,t)=>`--
|
|
51
|
-
## ENTITLEMENT ${t+1} ##
|
|
52
|
-
id: ${e.id}
|
|
53
|
-
productId: ${e.productId}
|
|
54
|
-
validFrom: ${e.validFrom}
|
|
55
|
-
validTo: ${e.validTo}
|
|
56
|
-
features: ${JSON.stringify(e.features)}
|
|
57
|
-
featureOverrides: ${JSON.stringify(e.featureOverrides)}
|
|
58
|
-
`).join("")}triggerOnFeatureChangeCallback(){this.config.onFeatureChange&&this.config.onFeatureChange(this.currentFeatures??{})}setTimerForNextEntitlementChange(){if(!this.hasCert())return;let e=Date.now(),t=new Set;t.add(this.licenseCert.expiresAt.getTime()-e),t.add(this.licenseCert.terminatesAt.getTime()-e);let i=[...this.licenseCert.entitlements.reduce((r,s)=>(r.add(s.validFrom.getTime()-e),r.add(s.validTo.getTime()-e),r),t)].filter(r=>r>=0&&r<=h).sort((r,s)=>r-s);if(i.length===0)return;let n=i[0];this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=this.setupSingleTimer(()=>{this.updateCurrentFeatures(),this.triggerOnFeatureChangeCallback(),this.setTimerForNextEntitlementChange()},n+1e3)}async renewalCron({force:e}){if(e||this.isRenewalDue()){this.log("attempting license renewal","debug");try{await this._renew({cause:e?"startup":"auto"})}catch{}}}async initCert(){if(!this.isShuttingDown)try{let e=await this.getCertStr();if(!e){this.licenseCert=void 0;return}if(e.length<50)throw new Error("cert string is undefined or too short");let{x509:t,licenseKey:i}=this.parseLicenseCertContainerStr(e);if(this.x509Cert=new w(t),!this.x509Cert.checkIssued(this.getIssuerCert()))throw new Error("cert was not issued by an approved issuer");let r=this.x509Cert.publicKey.export({format:"pem",type:"pkcs1"});this.key=new F(r),this.licenseCert=this.parseLicenseKeyStr(i),this.updateCurrentFeatures(),this.setTimerForNextEntitlementChange()}catch(e){this.log(`cert could not be initialized. ${e instanceof Error?e.message:""}`,"error")}}stringifyCertContainer(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}parseLicenseCertContainerStr(e){let t=Buffer.from(e,"base64").toString("ascii"),i=JSON.parse(t);if(!i.hasOwnProperty("licenseKey")||!i.hasOwnProperty("x509"))throw new Error("license cert container could not be parsed");return i}parseLicenseKeyStr(e){let t=this.validateLicenseKey(e),i={...t};return i.createdAt=new Date(t.createdAt),i.issuedAt=new Date(t.issuedAt),i.expiresAt=new Date(t.expiresAt),i.terminatesAt=new Date(t.terminatesAt),i.detachedEntitlementsCount=t.detachedEntitlementsCount??0,i.entitlements=i.entitlements.map(n=>(n.validFrom=new Date(n.validFrom),n.validTo=new Date(n.validTo),n)),i}validateLicenseKey(e){e=e.replace(/(\r\n|\n|\r)/gm,"");let t=e.match(/^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\|\|)(?<encryptedData>.+)\|\|(?<signature>.+)-----END LICENSE KEY-----$/);if(!t)throw new Error("license key could not be parsed");let i=t.groups.encryptedSymmetricKey,n=t.groups.encryptedData,r=t.groups.signature,s,a;try{s=this.key.decryptPublic(i,"utf8")}catch{throw new Error("Invalid data: Could not extract symmetric key")}try{a=p.AES.decrypt(n,s).toString(p.enc.Utf8)}catch{throw new Error("Invalid Data: Could not decrypt data with key found")}if(this.key.verify(Buffer.from(a),r,"utf8","base64"))return JSON.parse(a);throw new Error("License Key signature invalid")}getIssuerCert(){return this.x509IssuerCert}async clear(){try{await this.detachFloatingEntitlements()}catch(e){this.log(`failed to detach floating entitlements (${e}). Continuing with clearing license certificate`,"warn")}finally{await this.config.saveCertStr(""),await this.initCert()}}async shutdown(){this.isShuttingDown=!0,this.clearRepeatingTimer(this.renewalTimer),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.clearSingleTimer(this.entitlementChangeTimer),this.config.detachFloatingOnShutdown&&await this.detachFloatingEntitlements()}async detachFloatingEntitlements(){if(!this.hasCert())return;this.licenseCert.entitlements.some(t=>t.isFloatable??!1)&&await this._renew({detachFloatingEntitlements:!0,cause:"shutdown"})}enableAutoRenewals(){this.config.autoRenewEnabled!==!0&&(this.config.autoRenewEnabled=!0,this.log("License auto-renewals enabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),h))}disableAutoRenewals(){this.config.autoRenewEnabled!==!1&&(this.config.autoRenewEnabled=!1,this.log("License auto-renewals disabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0)}};export{h as AUTORENEWAL_INTERVAL,C as LicenseManager};
|
|
34
|
+
`)||"";return[s,"--",a,l?`--
|
|
35
|
+
`+l:""].join(`
|
|
36
|
+
`)}triggerOnFeatureChangeCallback(){this.config.onFeatureChange&&this.config.onFeatureChange(this.currentFeatures??{})}setTimerForNextEntitlementChange(){if(!this.hasCert())return;let e=Date.now(),t=new Set;t.add(this.licenseCert.expiresAt.getTime()-e),t.add(this.licenseCert.terminatesAt.getTime()-e);let i=[...this.licenseCert.entitlements.reduce((n,s)=>(n.add(s.validFrom.getTime()-e),n.add(s.validTo.getTime()-e),n),t)].filter(n=>n>=0&&n<=d).sort((n,s)=>n-s);if(i.length===0)return;let r=i[0];this.clearSingleTimer(this.entitlementChangeTimer),this.entitlementChangeTimer=this.setupSingleTimer(()=>{this.updateCurrentFeatures(),this.triggerOnFeatureChangeCallback(),this.setTimerForNextEntitlementChange()},r+1e3)}async renewalCron({force:e}){if(e||this.isRenewalDue()){this.log("attempting license renewal","info");try{await this._renew({cause:e?"startup":"auto"})}catch{}}}async initCert(){if(!this.isShuttingDown)try{let e=await this.getCertStr();if(!e){this.licenseCert=void 0;return}if(e.length<50)throw new Error("cert string is undefined or too short");let{x509:t,licenseKey:i}=this.parseLicenseCertContainerStr(e);if(this.x509Cert=new C(t),!this.x509Cert.checkIssued(this.getIssuerCert()))throw new Error("cert was not issued by an approved issuer");let n=this.x509Cert.publicKey.export({format:"pem",type:"pkcs1"});this.key=new A(n),this.licenseCert=this.parseLicenseKeyStr(i),this.updateCurrentFeatures(),this.setTimerForNextEntitlementChange()}catch(e){this.log(`cert could not be initialized. ${e instanceof Error?e.message:""}`,"error")}}stringifyCertContainer(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}parseLicenseCertContainerStr(e){let t=Buffer.from(e,"base64").toString("ascii"),i=JSON.parse(t);if(!i.hasOwnProperty("licenseKey")||!i.hasOwnProperty("x509"))throw new Error("license cert container could not be parsed");return i}parseLicenseKeyStr(e){let t=this.validateLicenseKey(e),i={...t};return i.createdAt=new Date(t.createdAt),i.issuedAt=new Date(t.issuedAt),i.expiresAt=new Date(t.expiresAt),i.terminatesAt=new Date(t.terminatesAt),i.detachedEntitlementsCount=t.detachedEntitlementsCount??0,i.entitlements=i.entitlements.map(r=>(r.validFrom=new Date(r.validFrom),r.validTo=new Date(r.validTo),r)),i}validateLicenseKey(e){e=e.replace(/(\r\n|\n|\r)/gm,"");let t=e.match(/^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\|\|)(?<encryptedData>.+)\|\|(?<signature>.+)-----END LICENSE KEY-----$/);if(!t)throw new Error("license key could not be parsed");let i=t.groups.encryptedSymmetricKey,r=t.groups.encryptedData,n=t.groups.signature,s,a;try{s=this.key.decryptPublic(i,"utf8")}catch{throw new Error("Invalid data: Could not extract symmetric key")}try{a=w.AES.decrypt(r,s).toString(w.enc.Utf8)}catch{throw new Error("Invalid Data: Could not decrypt data with key found")}if(this.key.verify(Buffer.from(a),n,"utf8","base64"))return JSON.parse(a);throw new Error("License Key signature invalid")}getIssuerCert(){return this.x509IssuerCert}async clear(){try{await this.detachFloatingEntitlements()}catch(e){this.log(`failed to detach floating entitlements (${e}). Continuing with clearing license certificate`,"warn")}finally{await this.config.saveCertStr(""),await this.initCert()}}async shutdown(){this.isShuttingDown=!0,this.clearRepeatingTimer(this.renewalTimer),this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer),this.clearSingleTimer(this.entitlementChangeTimer),this.config.detachFloatingOnShutdown&&await this.detachFloatingEntitlements()}async detachFloatingEntitlements(){if(!this.hasCert())return;this.licenseCert.entitlements.some(t=>t.isFloatable??!1)&&await this._renew({detachFloatingEntitlements:!0,cause:"shutdown"})}enableAutoRenewals(){this.config.autoRenewEnabled!==!0&&(this.config.autoRenewEnabled=!0,this.log("License auto-renewals enabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=this.setupRepeatingTimer(()=>this.renewalCron({force:!1}),d))}disableAutoRenewals(){this.config.autoRenewEnabled!==!1&&(this.config.autoRenewEnabled=!1,this.log("License auto-renewals disabled","info"),this.clearRepeatingTimer(this.renewalTimer),this.renewalTimer=void 0)}};export{d as AUTORENEWAL_INTERVAL,v as LicenseManager};
|
|
59
37
|
//# sourceMappingURL=LicenseManager.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { ok } from 'node:assert'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\n/** How often to consider periodic license renewal (in ms) */\nexport const AUTORENEWAL_INTERVAL = 15 * 60 * 1000 // 15 minutes\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n\n /**\n * Whether to renew the license periodically.\n *\n * @default true\n */\n autoRenewEnabled?: boolean\n /**\n * Whether to return any floatable entitlements to the pool on SDK shutdown.\n *\n * @default true\n */\n detachFloatingOnShutdown?: boolean\n offlineMode?: boolean\n renewOnInit?: boolean\n autoRenewOffset?: number\n loadCertStr: () => Promise<TLicenseBlock>\n saveCertStr: (cert: TLicenseBlock) => Promise<void>\n collectUsageMetrics?: () => Promise<Array<TUsageMetric>>\n collectPassthroughData?: () => Promise<TPassthroughData>\n deviceFingerprint?: () => string | Promise<string>\n onFeatureChange?: (features: TFeatures) => any\n logger?: TLogger\n}\n\nexport type TLicenseBlock = string\n\nexport type TLicenseContainer = {\n licenseKey: string\n x509: string\n}\n\nexport type TFeatures = { [key: string]: boolean | number | string }\n\nexport type TUsageMetric = { name: string; value: number }\n\nexport type TPassthroughData = Record<string, unknown>\n\nexport type TMetadata = {\n [key: string]: boolean | number | string | Array<any> | {}\n}\n\nexport type TEntitlement = {\n id: string\n productId: string\n productMetadata: TMetadata\n features: TFeatures\n featureOverrides: TFeatures\n validFrom: Date\n validTo: Date\n isFloatable: boolean\n}\n\nexport type TLicenseCertObj = {\n consumerId: string\n consumerRef?: string\n version: number\n tenantId: number\n renewalToken: string\n deviceLock: boolean\n deviceFingerprint: string\n createdAt: Date\n issuedAt: Date\n expiresAt: Date\n terminatesAt: Date\n entitlements: TEntitlement[]\n /**\n * Indicates the number of floating entitlements that are not attached to the consumer\n * because they are in use elsewhere at the time of renewal.\n */\n detachedEntitlementsCount: number\n managementJwt: string\n /**\n * Specifies whether the license is ephemeral and therefore does not have corresponding entries in the license server DB.\n */\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\n\ntype SingleTimer = NodeJS.Timeout\ntype RepeatingTimer = NodeJS.Timeout\n\nconst enum LogLevel {\n ERROR = 'error',\n WARN = 'warn',\n INFO = 'info',\n DEBUG = 'debug',\n}\n\nexport class LicenseManager {\n public config: TLicenseManagerConfig\n\n private initializationPromise?: Promise<void>\n private key?: NodeRSA\n private logger: TLogger\n protected licenseCert?: TLicenseCertObj\n private x509Cert?: X509Certificate\n private x509IssuerCert: X509Certificate\n private deviceFingerprint?: string\n private renewalTimer?: RepeatingTimer\n private upcomingEntitlementChangesCheckTimer?: RepeatingTimer\n private entitlementChangeTimer?: SingleTimer\n private currentFeatures?: TFeatures\n private isShuttingDown = false\n\n get isInitialized() {\n return !!this.initializationPromise\n }\n\n constructor(config: TLicenseManagerConfig) {\n this.config = config\n\n if (this.config.logger) {\n this.logger = this.config.logger\n } else {\n this.logger = {\n error() {\n console.log('ERROR:', ...arguments)\n },\n warn() {\n console.log('WARN:', ...arguments)\n },\n info() {\n console.log('INFO:', ...arguments)\n },\n debug() {\n console.log('DEBUG:', ...arguments)\n },\n }\n }\n\n this.x509IssuerCert = new X509Certificate(\n '-----BEGIN CERTIFICATE-----\\n' +\n 'MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE\\n' +\n 'RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp\\n' +\n 'Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL\\n' +\n 'MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw\\n' +\n 'FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\\n' +\n 'AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q\\n' +\n 'IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+\\n' +\n 'btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU\\n' +\n 'zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED\\n' +\n '+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS\\n' +\n 'dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po\\n' +\n 'Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S\\n' +\n '28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM\\n' +\n 'K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs\\n' +\n 'sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL\\n' +\n 'JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ\\n' +\n 'KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8\\n' +\n 'ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3\\n' +\n 'Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl\\n' +\n '/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP\\n' +\n 'Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK\\n' +\n 'LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc\\n' +\n 'Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw\\n' +\n 'uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP\\n' +\n 'A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD\\n' +\n '4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT\\n' +\n '/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ\\n' +\n '-----END CERTIFICATE-----'\n )\n\n //set defaults for not set config properties:\n this.config.autoRenewEnabled = this.config.autoRenewEnabled ?? true\n this.config.renewOnInit = this.config.renewOnInit ?? false\n this.config.offlineMode = this.config.offlineMode ?? false\n this.config.autoRenewOffset = this.config.autoRenewOffset ?? 60 * 60 * 72 // default: 72 hours\n this.config.detachFloatingOnShutdown =\n this.config.detachFloatingOnShutdown ?? true\n this.config.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license SDK] ${msg}`)\n }\n\n async initialize() {\n if (this.initializationPromise) {\n return this.initializationPromise\n }\n\n this.initializationPromise = this._doInitialization()\n\n return await this.initializationPromise\n }\n\n /** Initializes the license manager */\n private async _doInitialization() {\n ok(!this.initializationPromise, 'Initialization already in progress')\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n\n await this.initCert() // doesn't throw!\n\n // Clear and set up periodic timer for entitlement changes\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = this.setupRepeatingTimer(\n () => this.setTimerForNextEntitlementChange(),\n AUTORENEWAL_INTERVAL\n )\n\n // Renew license on init if necessary\n // If detachedEntitlementsCount > 0, renewing is important in order to attempt re-attaching floating entitlements!\n if (\n this.config.renewOnInit &&\n this.config.autoRenewEnabled &&\n this.hasCert() &&\n (this.licenseCert.detachedEntitlementsCount > 0 || this.isRenewalDue())\n ) {\n await this.renewalCron({ force: true })\n } else {\n this.log(\n 'Skipping renewal on init because renewal is not due yet or cert is not initialized',\n LogLevel.DEBUG\n )\n }\n\n // Set up periodic renewal if enabled\n if (this.config.autoRenewEnabled) {\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n }\n\n private setupSingleTimer(\n callback: () => void,\n interval: number\n ): SingleTimer {\n return setTimeout(callback, interval)\n }\n\n clearSingleTimer(timer: SingleTimer | undefined) {\n if (timer) {\n clearTimeout(timer)\n }\n }\n\n setupRepeatingTimer(callback: () => void, interval: number): RepeatingTimer {\n return setInterval(callback, interval)\n }\n\n clearRepeatingTimer(timer: RepeatingTimer | undefined) {\n if (timer) {\n clearInterval(timer)\n }\n }\n\n private isOlderThan(date: Date, durationInMs: number) {\n return Date.now() - date.getTime() > durationInMs\n }\n\n async reload() {\n await this.reset()\n await this.initialize()\n }\n\n async reset() {\n // Make sure initialization is not ongoing before resetting\n if (this.initializationPromise) {\n await this.initializationPromise\n }\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = undefined\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = undefined\n\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.initializationPromise = undefined\n }\n\n async computeDeviceFingerprint() {\n if (\n this.config.deviceFingerprint &&\n typeof this.config.deviceFingerprint === 'function'\n ) {\n return await this.config.deviceFingerprint()\n }\n return await machineId()\n }\n\n async activate(reservationId: string) {\n if (!this.isInitialized) {\n throw new Error('activation failed because SDK was not yet initialized')\n }\n\n if (this.isShuttingDown) {\n throw new Error('activation failed because SDK is shutting down')\n }\n\n if (this.config.offlineMode) {\n throw new Error('activation failed because SDK is in offline mode')\n }\n\n const postData: {\n reservationId: string\n tenantId: number\n productIdentifier: string\n deviceFingerprint: string\n consumerId?: string\n renewalToken?: string\n } = {\n reservationId,\n tenantId: this.config.tenantId,\n productIdentifier: this.config.productIdentifier,\n deviceFingerprint: this.deviceFingerprint!,\n }\n\n if (this.hasCert()) {\n postData.consumerId = this.licenseCert.consumerId\n postData.renewalToken = this.licenseCert.renewalToken\n }\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<{\n licenseKey?: string\n x509?: string\n message?: string\n errorId?: string\n }>(`${this.config.server!}/activate`, postData, {\n timeoutInMs: 10000,\n productIdentifier: this.config.productIdentifier,\n })\n } catch (error) {\n this.log(\n 'license activation failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n if (response.status == 200) {\n if (\n !response.data.hasOwnProperty('licenseKey') ||\n !response.data.hasOwnProperty('x509')\n ) {\n this.log('unexpected server response', LogLevel.WARN)\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: response.data.licenseKey,\n x509: response.data.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n await this.initCert()\n this.log('license successfully activated', LogLevel.INFO)\n if (response.data.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${response.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n } else {\n const errorMsg = `license activation failed: ${\n response.data.message ?? 'unknown reason'\n }`\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (response.data.errorId) {\n e.errorId = response.data.errorId\n }\n\n this.log(errorMsg, LogLevel.WARN)\n throw e\n }\n }\n\n async renew() {\n return this._renew({ cause: 'request' })\n }\n\n async _renew({\n detachFloatingEntitlements = false,\n cause = 'unknown',\n }: {\n detachFloatingEntitlements?: Boolean\n cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown'\n } = {}) {\n if (!this.hasCert()) {\n throw new Error('renewal failed because current cert is not initialized')\n }\n\n if (this.licenseCert.isEphemeral) {\n return\n }\n\n if (this.isTerminated()) {\n throw new Error('renewal failed because current cert was terminated')\n }\n\n if (this.config.offlineMode) {\n throw new Error('renewal failed because SDK is in offline mode')\n }\n\n if (this.config.tenantId !== this.licenseCert.tenantId) {\n throw new Error('renewal failed because tenant ID does not match')\n }\n\n // error out if device fingerprint does not match but allow renewal on explicit request\n // as the consumer might have been changed to more permissive settings on the server\n if (\n cause !== 'request' &&\n this.licenseCert.deviceLock &&\n this.deviceFingerprint !== this.licenseCert.deviceFingerprint\n ) {\n throw new Error(\n 'renewal failed because device fingerprint does not match'\n )\n }\n\n const [usageMetrics, passthroughData] = await Promise.all([\n this.config.collectUsageMetrics ? this.config.collectUsageMetrics() : [],\n this.config.collectPassthroughData\n ? this.config.collectPassthroughData()\n : {},\n ])\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<ResponseDataFormat>(\n `${this.config.server!}/renew`,\n {\n consumerId: this.licenseCert.consumerId,\n tenantId: this.config.tenantId,\n deviceFingerprint: this.deviceFingerprint,\n productIdentifier: this.config.productIdentifier,\n renewalToken: this.licenseCert.renewalToken,\n detachFloatingEntitlements,\n cause,\n usageMetrics,\n passthroughData,\n },\n { timeoutInMs: 10000, productIdentifier: this.config.productIdentifier }\n )\n } catch (error) {\n this.log(\n 'license renewal failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n const responseData = response.data\n\n if (response.status == 200) {\n if (\n !responseData.hasOwnProperty('licenseKey') ||\n !responseData.hasOwnProperty('x509')\n ) {\n this.log(\n 'license renewal failed: unexpected server response',\n LogLevel.WARN\n )\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: responseData.licenseKey,\n x509: responseData.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n\n this.log('license successfully renewed', LogLevel.DEBUG)\n\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n if (detachFloatingEntitlements) {\n this.log(\n `${responseData.detachedEntitlementsCount} floating entitlements were returned to the pool`,\n LogLevel.INFO\n )\n } else {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n }\n\n await this.initCert()\n } else {\n const errorMsg = `license renewal failed: ${\n responseData.message ?? 'unknown reason'\n }`\n\n this.log(errorMsg, LogLevel.WARN)\n\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (responseData.errorId) {\n e.errorId = responseData.errorId\n\n if (\n ['NOT_FOUND', 'CONSUMER_TERMINATED'].includes(responseData.errorId)\n ) {\n this.log(\n 'license was terminated by the server. Deleting local cert.',\n LogLevel.WARN\n )\n await this.config.saveCertStr('')\n await this.initCert()\n } else if (responseData.errorId === 'FINGERPRINT_MISMATCH') {\n // pause auto-renewal as subsequent requests will also fail\n this.disableAutoRenewals()\n }\n }\n\n throw e\n }\n }\n\n private hasCert(): this is { licenseCert: TLicenseCertObj } {\n return !!this.licenseCert\n }\n\n isTerminated(): boolean {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n const now = new Date()\n\n return this.licenseCert.terminatesAt < now\n }\n\n getExpiryDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.expiresAt\n }\n\n getTerminationDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.terminatesAt\n }\n\n isValid(useLogger = true): boolean {\n const error = (msg: string) => {\n if (useLogger) {\n this.log(msg, LogLevel.ERROR)\n }\n }\n\n if (!this.hasCert()) {\n error('cert is invalid because it is undefined')\n return false\n }\n\n const cert = this.licenseCert as TLicenseCertObj\n const now = new Date()\n\n if (cert.expiresAt < now) {\n error('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n error('cert is invalid because it was terminated')\n return false\n }\n\n //allow clocks to be out of sync by no more than 300,000 ms / = 5 minutes\n if (cert.createdAt.getTime() - 300000 > now.getTime()) {\n error('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n error('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n error('cert is invalid because tenant ID does not match')\n return false\n }\n\n return true\n }\n\n hasFeatureEnabled(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) ? true : false\n }\n\n hasFeatureDefined(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) !== undefined\n ? true\n : false\n }\n\n hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean {\n const quota = this.getFeatureValue(quotaFeatureName)\n\n if (quota === undefined) {\n return false\n }\n\n if (typeof quota !== 'number') {\n throw new Error(\n `${quotaFeatureName} cannot be used as quota as it is not numeric`\n )\n }\n\n // -1 means unlimited quota!\n if (quota === -1) {\n return true\n }\n\n return Math.ceil(currentConsumption) < Math.ceil(quota)\n }\n\n getFeatureValue(\n feature: string,\n requireValidCert: boolean = true\n ): undefined | boolean | number | string {\n if (!this.hasCert()) {\n return undefined\n }\n\n if (requireValidCert && !this.isValid()) {\n return undefined\n }\n\n const currentFeatures = this.getFeatures()\n\n if (!currentFeatures.hasOwnProperty(feature)) {\n return undefined\n }\n\n return currentFeatures[feature]\n }\n\n private updateCurrentFeatures() {\n if (!this.hasCert()) {\n return\n }\n\n const now = new Date()\n\n if (\n this.licenseCert.expiresAt < now ||\n this.licenseCert.terminatesAt < now\n ) {\n this.currentFeatures = {} as TFeatures\n }\n\n this.currentFeatures = this.licenseCert.entitlements\n .filter(\n (entitlement) =>\n entitlement.validFrom <= now && entitlement.validTo > now\n )\n .sort(\n (entitlement1, entitlement2) =>\n entitlement1.validFrom.getTime() - entitlement2.validFrom.getTime()\n )\n .reduce((currentFeatures, entitlement) => {\n return {\n ...currentFeatures,\n ...entitlement.features,\n ...entitlement.featureOverrides,\n }\n }, {} as TFeatures)\n }\n\n getFeatures() {\n if (!this.hasCert()) {\n return {}\n }\n\n return this.currentFeatures ?? {}\n }\n\n getCurrentEntitlements() {\n if (!this.hasCert()) {\n return []\n }\n\n const now = new Date()\n\n return this.licenseCert.entitlements.filter(\n (entitlement) => entitlement.validFrom <= now && entitlement.validTo > now\n )\n }\n\n getManagementJwt() {\n if (!this.licenseCert) {\n return ''\n }\n\n return this.licenseCert.managementJwt\n }\n\n async getCertStr(): Promise<TLicenseBlock> {\n return this.config.loadCertStr()\n }\n\n getConsumerId() {\n return this.licenseCert?.consumerId\n }\n\n isRenewalDue(): boolean {\n if (!this.licenseCert || this.licenseCert.isEphemeral) {\n return false\n }\n\n const now = Date.now()\n const mins15inMs = 1000 * 60 * 15\n const mins20inMs = 1000 * 60 * 20\n const expiry = this.licenseCert.expiresAt.getTime()\n const issuedAt = this.licenseCert.issuedAt.getTime()\n const termination = this.licenseCert.terminatesAt.getTime()\n\n //consumerRenewalDue is TRUE when current time is close enough to consumer expiry and not after consumer termination\n const consumerRenewalDue =\n now > expiry - this.config.autoRenewOffset! * 1000 && now < termination\n\n //entitlementRenewalDue is TRUE when one currently valid entitlement will expire in the next 15 minutes\n //and the Cert was issued more than 20 minutes ago\n const entitlementRenewalDue =\n this.getCurrentEntitlements().find(\n (entitlement) =>\n now >= entitlement.validTo.getTime() - mins15inMs &&\n now <= entitlement.validTo.getTime()\n ) !== undefined && issuedAt < now - mins20inMs\n\n return consumerRenewalDue || entitlementRenewalDue\n }\n\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const remainingSeconds = seconds % 60\n\n return `${hours}h ${minutes}m ${remainingSeconds}s`\n }\n\n toString() {\n return (\n `## CONSUMER CONFIG ##\\n` +\n `tenantId: ${this.config.tenantId ?? '<n/a>'}\\n` +\n `productIdentifier: ${this.config.productIdentifier ?? '<n/a>'}\\n` +\n `deviceFingerprint: ${this.deviceFingerprint ?? '<n/a>'}\\n` +\n `autoRenewalEnabled: ${\n this.config.autoRenewEnabled ? 'true' : 'false (!)'\n }\\n` +\n `autoRenewalOffset: ${\n this.config.autoRenewOffset\n } (= ${this.formatDuration(this.config.autoRenewOffset ?? 0)})\\n` +\n '--\\n' +\n `## LICENSE CERT ##\\n` +\n `version: ${this.licenseCert?.version ?? '<n/a>'}\\n` +\n `tenantId: ${this.licenseCert?.tenantId ?? '<n/a>'} ${\n this.licenseCert?.tenantId !== this.config.tenantId ? '(!)' : ''\n }\\n` +\n `consumerId: ${this.licenseCert?.consumerId ?? '<n/a>'}\\n` +\n `deviceFingerprint: ${this.licenseCert?.deviceFingerprint ?? '<n/a>'} ${\n this.licenseCert?.deviceFingerprint !== this.deviceFingerprint\n ? '(!)'\n : ''\n }\\n` +\n `createdAt: ${this.licenseCert?.createdAt ?? '<n/a>'}\\n` +\n `issuedAt: ${this.licenseCert?.issuedAt ?? '<n/a>'}\\n` +\n `expiresAt: ${this.licenseCert?.expiresAt ?? '<n/a>'}\\n` +\n `terminatesAt: ${this.licenseCert?.terminatesAt ?? '<n/a>'}\\n` +\n `isEphemeral: ${this.licenseCert?.isEphemeral ?? '<n/a>'}\\n` +\n `isValid: ${this.isValid(false)}\\n` +\n `isRenewalDue: ${this.isRenewalDue()}\\n` +\n `detachedEntitlementsCount: ${\n this.licenseCert?.detachedEntitlementsCount ?? '<n/a>'\n }\\n` +\n `entitlements: ${this.licenseCert?.entitlements.length ?? 0}\\n` +\n this.licenseCert?.entitlements\n .map((entitlement, index) => {\n return (\n '--\\n' +\n `## ENTITLEMENT ${index + 1} ##\\n` +\n `id: ${entitlement.id}\\n` +\n `productId: ${entitlement.productId}\\n` +\n `validFrom: ${entitlement.validFrom}\\n` +\n `validTo: ${entitlement.validTo}\\n` +\n `features: ${JSON.stringify(entitlement.features)}\\n` +\n `featureOverrides: ${JSON.stringify(\n entitlement.featureOverrides\n )}\\n`\n )\n })\n .join('')\n )\n }\n\n private triggerOnFeatureChangeCallback() {\n if (this.config.onFeatureChange) {\n this.config.onFeatureChange(this.currentFeatures ?? {})\n }\n }\n\n private setTimerForNextEntitlementChange() {\n if (!this.hasCert()) {\n return\n }\n\n const now = Date.now()\n const offsets = new Set<number>()\n\n offsets.add(this.licenseCert.expiresAt.getTime() - now)\n offsets.add(this.licenseCert.terminatesAt.getTime() - now)\n\n const upcomingEventOffsets = [\n ...this.licenseCert.entitlements.reduce((offsets, entitlement) => {\n offsets.add(entitlement.validFrom.getTime() - now)\n offsets.add(entitlement.validTo.getTime() - now)\n return offsets\n }, offsets),\n ]\n .filter((offset) => offset >= 0 && offset <= AUTORENEWAL_INTERVAL) // keep if offset is within the next 15 minutes\n .sort((a, b) => a - b)\n\n //console.dir(upcomingEventOffsets.map((offset) => offset / 1000 / 60))\n\n if (upcomingEventOffsets.length === 0) {\n return\n }\n\n const timeTillNextEventInMs = upcomingEventOffsets[0]\n\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = this.setupSingleTimer(() => {\n this.updateCurrentFeatures()\n this.triggerOnFeatureChangeCallback()\n this.setTimerForNextEntitlementChange()\n }, timeTillNextEventInMs + 1000)\n }\n\n private async renewalCron({ force }: { force: boolean }) {\n if (force || this.isRenewalDue()) {\n this.log('attempting license renewal', LogLevel.DEBUG)\n try {\n await this._renew({ cause: force ? 'startup' : 'auto' })\n } catch (e) {}\n }\n }\n\n private async initCert() {\n if (this.isShuttingDown) {\n return\n }\n\n try {\n const containerStr = await this.getCertStr()\n if (!containerStr) {\n this.licenseCert = undefined\n return\n }\n if (containerStr.length < 50) {\n throw new Error('cert string is undefined or too short')\n }\n const { x509, licenseKey } =\n this.parseLicenseCertContainerStr(containerStr)\n this.x509Cert = new X509Certificate(x509)\n const hasApprovedIssuer = this.x509Cert.checkIssued(this.getIssuerCert())\n if (!hasApprovedIssuer) {\n throw new Error('cert was not issued by an approved issuer')\n }\n const publicKey = this.x509Cert.publicKey.export({\n format: 'pem',\n type: 'pkcs1',\n })\n this.key = new NodeRSA(publicKey)\n this.licenseCert = this.parseLicenseKeyStr(licenseKey)\n this.updateCurrentFeatures()\n this.setTimerForNextEntitlementChange()\n } catch (e) {\n this.log(\n `cert could not be initialized. ${e instanceof Error ? e.message : ''}`,\n LogLevel.ERROR\n )\n }\n }\n\n private stringifyCertContainer(container: TLicenseContainer): string {\n const containerStr = JSON.stringify(container)\n return Buffer.from(containerStr).toString('base64')\n }\n\n private parseLicenseCertContainerStr(\n stringifiedContainer: string\n ): TLicenseContainer {\n const containerStr = Buffer.from(stringifiedContainer, 'base64').toString(\n 'ascii'\n )\n const container = JSON.parse(containerStr)\n if (\n !container.hasOwnProperty('licenseKey') ||\n !container.hasOwnProperty('x509')\n ) {\n throw new Error('license cert container could not be parsed')\n }\n\n return container as TLicenseContainer\n }\n\n private parseLicenseKeyStr(certStr: string): TLicenseCertObj {\n const certPayload = this.validateLicenseKey(certStr)\n\n const cert = { ...certPayload } as TLicenseCertObj\n\n // turn timestamp strings into Date objects\n cert.createdAt = new Date(certPayload.createdAt)\n cert.issuedAt = new Date(certPayload.issuedAt)\n cert.expiresAt = new Date(certPayload.expiresAt)\n cert.terminatesAt = new Date(certPayload.terminatesAt)\n\n // make sure detachedEntitlementsCount is a number (certs issues before this field was introduced will have it missing)\n cert.detachedEntitlementsCount = certPayload.detachedEntitlementsCount ?? 0\n\n cert.entitlements = cert.entitlements.map((entitlement) => {\n entitlement.validFrom = new Date(entitlement.validFrom)\n entitlement.validTo = new Date(entitlement.validTo)\n return entitlement\n })\n\n return cert\n }\n\n private validateLicenseKey(licenseKey: string) {\n //remove all line breaks\n licenseKey = licenseKey.replace(/(\\r\\n|\\n|\\r)/gm, '')\n\n //extract parts\n const match = licenseKey.match(\n /^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\\|\\|)(?<encryptedData>.+)\\|\\|(?<signature>.+)-----END LICENSE KEY-----$/\n )\n\n if (!match) {\n throw new Error('license key could not be parsed')\n }\n\n const encryptedSymmetricKey = match.groups!.encryptedSymmetricKey\n const payload = match.groups!.encryptedData\n const signature = match.groups!.signature\n\n let symmetricKey, decryptedData\n\n //decrypt the random symmetric key\n try {\n symmetricKey = this.key!.decryptPublic(encryptedSymmetricKey, 'utf8')\n } catch (e) {\n throw new Error('Invalid data: Could not extract symmetric key')\n }\n\n //decrypt the payload\n try {\n decryptedData = CryptoJS.AES.decrypt(payload, symmetricKey).toString(\n CryptoJS.enc.Utf8\n )\n } catch (e) {\n throw new Error('Invalid Data: Could not decrypt data with key found')\n }\n\n //verify the signature.\n if (\n this.key!.verify(Buffer.from(decryptedData), signature, 'utf8', 'base64')\n ) {\n //return the decrypted data.\n return JSON.parse(decryptedData)\n } else {\n throw new Error('License Key signature invalid')\n }\n }\n\n public getIssuerCert() {\n return this.x509IssuerCert\n }\n\n /**\n * Detaches any floating entitlements and clears the local license cert.\n */\n public async clear() {\n try {\n await this.detachFloatingEntitlements()\n } catch (err) {\n this.log(\n `failed to detach floating entitlements (${err}). Continuing with clearing license certificate`,\n LogLevel.WARN\n )\n } finally {\n await this.config.saveCertStr('')\n await this.initCert()\n }\n }\n\n public async shutdown() {\n this.isShuttingDown = true\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.clearSingleTimer(this.entitlementChangeTimer)\n\n if (this.config.detachFloatingOnShutdown) {\n await this.detachFloatingEntitlements()\n }\n }\n\n private async detachFloatingEntitlements() {\n if (!this.hasCert()) {\n return\n }\n\n const hasFloatableEntitlements = this.licenseCert.entitlements.some(\n (entitlement) => entitlement.isFloatable ?? false\n )\n\n if (hasFloatableEntitlements) {\n await this._renew({\n detachFloatingEntitlements: true,\n cause: 'shutdown',\n })\n }\n }\n\n /** Enable periodical renewal of the license. */\n public enableAutoRenewals() {\n if (this.config.autoRenewEnabled === true) return\n\n this.config.autoRenewEnabled = true\n this.log('License auto-renewals enabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n\n /** Disable periodical renewal of the license. */\n public disableAutoRenewals() {\n if (this.config.autoRenewEnabled === false) return\n\n this.config.autoRenewEnabled = false\n this.log('License auto-renewals disabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n }\n}\n","import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.0' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.0'\n"],"mappings":"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","names":["CryptoJS","machineId","NodeRSA","ok","X509Certificate","fetch","ProxyAgent","URL","SDK_VERSION","getProxyAgent","envVar","proxyURI","ProxyAgent","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","URL","proxyAgent","response","fetch","SDK_VERSION","err","error","AUTORENEWAL_INTERVAL","LicenseManager","config","X509Certificate","msg","logLevel","ok","AUTORENEWAL_INTERVAL","callback","interval","timer","date","durationInMs","machineId","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","passthroughData","responseData","now","useLogger","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","seconds","hours","minutes","remainingSeconds","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS","err"]}
|
|
1
|
+
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { ok } from 'node:assert'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\n/** How often to consider periodic license renewal (in ms) */\nexport const AUTORENEWAL_INTERVAL = 15 * 60 * 1000 // 15 minutes\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n\n /**\n * Whether to renew the license periodically.\n *\n * @default true\n */\n autoRenewEnabled?: boolean\n /**\n * Whether to return any floatable entitlements to the pool on SDK shutdown.\n *\n * @default true\n */\n detachFloatingOnShutdown?: boolean\n offlineMode?: boolean\n renewOnInit?: boolean\n autoRenewOffset?: number\n loadCertStr: () => Promise<TLicenseBlock>\n saveCertStr: (cert: TLicenseBlock) => Promise<void>\n collectUsageMetrics?: () => Promise<Array<TUsageMetric>>\n collectPassthroughData?: () => Promise<TPassthroughData>\n deviceFingerprint?: () => string | Promise<string>\n onFeatureChange?: (features: TFeatures) => any\n logger?: TLogger\n}\n\nexport type TLicenseBlock = string\n\nexport type TLicenseContainer = {\n licenseKey: string\n x509: string\n}\n\nexport type TFeatures = { [key: string]: boolean | number | string }\n\nexport type TUsageMetric = { name: string; value: number }\n\nexport type TPassthroughData = Record<string, unknown>\n\nexport type TMetadata = {\n [key: string]: boolean | number | string | Array<any> | {}\n}\n\nexport type TEntitlement = {\n id: string\n productId: string\n productMetadata: TMetadata\n features: TFeatures\n featureOverrides: TFeatures\n validFrom: Date\n validTo: Date\n isFloatable: boolean\n}\n\nexport type TLicenseCertObj = {\n consumerId: string\n consumerRef?: string\n version: number\n tenantId: number\n renewalToken: string\n deviceLock: boolean\n deviceFingerprint: string\n createdAt: Date\n issuedAt: Date\n expiresAt: Date\n terminatesAt: Date\n entitlements: TEntitlement[]\n /**\n * Indicates the number of floating entitlements that are not attached to the consumer\n * because they are in use elsewhere at the time of renewal.\n */\n detachedEntitlementsCount: number\n managementJwt: string\n /**\n * Specifies whether the license is ephemeral and therefore does not have corresponding entries in the license server DB.\n */\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\n\ntype SingleTimer = NodeJS.Timeout\ntype RepeatingTimer = NodeJS.Timeout\n\nconst enum LogLevel {\n ERROR = 'error',\n WARN = 'warn',\n INFO = 'info',\n DEBUG = 'debug',\n}\n\nexport class LicenseManager {\n public config: TLicenseManagerConfig\n\n private initializationPromise?: Promise<void>\n private key?: NodeRSA\n private logger: TLogger\n protected licenseCert?: TLicenseCertObj\n private x509Cert?: X509Certificate\n private x509IssuerCert: X509Certificate\n private deviceFingerprint?: string\n private renewalTimer?: RepeatingTimer\n private upcomingEntitlementChangesCheckTimer?: RepeatingTimer\n private entitlementChangeTimer?: SingleTimer\n private currentFeatures?: TFeatures\n private isShuttingDown = false\n\n get isInitialized() {\n return !!this.initializationPromise\n }\n\n constructor(config: TLicenseManagerConfig) {\n this.config = config\n\n if (this.config.logger) {\n this.logger = this.config.logger\n } else {\n this.logger = {\n error() {\n console.log('ERROR:', ...arguments)\n },\n warn() {\n console.log('WARN:', ...arguments)\n },\n info() {\n console.log('INFO:', ...arguments)\n },\n debug() {\n console.log('DEBUG:', ...arguments)\n },\n }\n }\n\n this.x509IssuerCert = new X509Certificate(\n '-----BEGIN CERTIFICATE-----\\n' +\n 'MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE\\n' +\n 'RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp\\n' +\n 'Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL\\n' +\n 'MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw\\n' +\n 'FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\\n' +\n 'AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q\\n' +\n 'IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+\\n' +\n 'btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU\\n' +\n 'zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED\\n' +\n '+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS\\n' +\n 'dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po\\n' +\n 'Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S\\n' +\n '28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM\\n' +\n 'K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs\\n' +\n 'sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL\\n' +\n 'JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ\\n' +\n 'KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8\\n' +\n 'ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3\\n' +\n 'Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl\\n' +\n '/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP\\n' +\n 'Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK\\n' +\n 'LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc\\n' +\n 'Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw\\n' +\n 'uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP\\n' +\n 'A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD\\n' +\n '4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT\\n' +\n '/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ\\n' +\n '-----END CERTIFICATE-----'\n )\n\n //set defaults for not set config properties:\n this.config.autoRenewEnabled = this.config.autoRenewEnabled ?? true\n this.config.renewOnInit = this.config.renewOnInit ?? false\n this.config.offlineMode = this.config.offlineMode ?? false\n this.config.autoRenewOffset = this.config.autoRenewOffset ?? 60 * 60 * 72 // default: 72 hours\n this.config.detachFloatingOnShutdown =\n this.config.detachFloatingOnShutdown ?? true\n this.config.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license SDK] ${msg}`)\n }\n\n async initialize() {\n if (this.initializationPromise) {\n return this.initializationPromise\n }\n\n this.initializationPromise = this._doInitialization()\n\n return await this.initializationPromise\n }\n\n /** Initializes the license manager */\n private async _doInitialization() {\n ok(!this.initializationPromise, 'Initialization already in progress')\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n\n await this.initCert() // doesn't throw!\n\n // Clear and set up periodic timer for entitlement changes\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = this.setupRepeatingTimer(\n () => this.setTimerForNextEntitlementChange(),\n AUTORENEWAL_INTERVAL\n )\n\n // Renew license on init if necessary\n // If detachedEntitlementsCount > 0, renewing is important in order to attempt re-attaching floating entitlements!\n if (\n this.config.renewOnInit &&\n this.config.autoRenewEnabled &&\n this.hasCert() &&\n (this.licenseCert.detachedEntitlementsCount > 0 || this.isRenewalDue())\n ) {\n await this.renewalCron({ force: true })\n } else {\n this.log(\n 'Skipping renewal on init because renewal is not due yet or cert is not initialized',\n LogLevel.INFO\n )\n }\n\n // Set up periodic renewal if enabled\n if (this.config.autoRenewEnabled) {\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n }\n\n private setupSingleTimer(\n callback: () => void,\n interval: number\n ): SingleTimer {\n return setTimeout(callback, interval)\n }\n\n clearSingleTimer(timer: SingleTimer | undefined) {\n if (timer) {\n clearTimeout(timer)\n }\n }\n\n setupRepeatingTimer(callback: () => void, interval: number): RepeatingTimer {\n return setInterval(callback, interval)\n }\n\n clearRepeatingTimer(timer: RepeatingTimer | undefined) {\n if (timer) {\n clearInterval(timer)\n }\n }\n\n private isOlderThan(date: Date, durationInMs: number) {\n return Date.now() - date.getTime() > durationInMs\n }\n\n async reload() {\n await this.reset()\n await this.initialize()\n }\n\n async reset() {\n // Make sure initialization is not ongoing before resetting\n if (this.initializationPromise) {\n await this.initializationPromise\n }\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.upcomingEntitlementChangesCheckTimer = undefined\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = undefined\n\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.initializationPromise = undefined\n }\n\n async computeDeviceFingerprint() {\n if (\n this.config.deviceFingerprint &&\n typeof this.config.deviceFingerprint === 'function'\n ) {\n return await this.config.deviceFingerprint()\n }\n return await machineId()\n }\n\n async activate(reservationId: string) {\n if (!this.isInitialized) {\n throw new Error('activation failed because SDK was not yet initialized')\n }\n\n if (this.isShuttingDown) {\n throw new Error('activation failed because SDK is shutting down')\n }\n\n if (this.config.offlineMode) {\n throw new Error('activation failed because SDK is in offline mode')\n }\n\n const postData: {\n reservationId: string\n tenantId: number\n productIdentifier: string\n deviceFingerprint: string\n consumerId?: string\n renewalToken?: string\n } = {\n reservationId,\n tenantId: this.config.tenantId,\n productIdentifier: this.config.productIdentifier,\n deviceFingerprint: this.deviceFingerprint!,\n }\n\n if (this.hasCert()) {\n postData.consumerId = this.licenseCert.consumerId\n postData.renewalToken = this.licenseCert.renewalToken\n }\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<{\n licenseKey?: string\n x509?: string\n message?: string\n errorId?: string\n }>(`${this.config.server!}/activate`, postData, {\n timeoutInMs: 10000,\n productIdentifier: this.config.productIdentifier,\n })\n } catch (error) {\n this.log(\n 'license activation failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n if (response.status == 200) {\n if (\n !response.data.hasOwnProperty('licenseKey') ||\n !response.data.hasOwnProperty('x509')\n ) {\n this.log('unexpected server response', LogLevel.WARN)\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: response.data.licenseKey,\n x509: response.data.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n await this.initCert()\n this.log('license successfully activated', LogLevel.INFO)\n if (response.data.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${response.data.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n } else {\n const errorMsg = `license activation failed: ${\n response.data.message ?? 'unknown reason'\n }`\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (response.data.errorId) {\n e.errorId = response.data.errorId\n }\n\n this.log(errorMsg, LogLevel.WARN)\n throw e\n }\n }\n\n async renew() {\n return this._renew({ cause: 'request' })\n }\n\n async _renew({\n detachFloatingEntitlements = false,\n cause = 'unknown',\n }: {\n detachFloatingEntitlements?: Boolean\n cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown'\n } = {}) {\n if (!this.hasCert()) {\n throw new Error('renewal failed because current cert is not initialized')\n }\n\n if (this.licenseCert.isEphemeral) {\n return\n }\n\n if (this.isTerminated()) {\n throw new Error('renewal failed because current cert was terminated')\n }\n\n if (this.config.offlineMode) {\n throw new Error('renewal failed because SDK is in offline mode')\n }\n\n if (this.config.tenantId !== this.licenseCert.tenantId) {\n throw new Error('renewal failed because tenant ID does not match')\n }\n\n // error out if device fingerprint does not match but allow renewal on explicit request\n // as the consumer might have been changed to more permissive settings on the server\n if (\n cause !== 'request' &&\n this.licenseCert.deviceLock &&\n this.deviceFingerprint !== this.licenseCert.deviceFingerprint\n ) {\n throw new Error(\n 'renewal failed because device fingerprint does not match'\n )\n }\n\n const [usageMetrics, passthroughData] = await Promise.all([\n this.config.collectUsageMetrics ? this.config.collectUsageMetrics() : [],\n this.config.collectPassthroughData\n ? this.config.collectPassthroughData()\n : {},\n ])\n\n type ResponseDataFormat = {\n licenseKey?: string\n x509?: string\n detachedEntitlementsCount?: number\n message?: string\n errorId?: string\n }\n\n type PostRequestResponse = Awaited<\n ReturnType<typeof postRequest<ResponseDataFormat>>\n >\n\n let response: PostRequestResponse\n\n try {\n response = await postRequest<ResponseDataFormat>(\n `${this.config.server!}/renew`,\n {\n consumerId: this.licenseCert.consumerId,\n tenantId: this.config.tenantId,\n deviceFingerprint: this.deviceFingerprint,\n productIdentifier: this.config.productIdentifier,\n renewalToken: this.licenseCert.renewalToken,\n detachFloatingEntitlements,\n cause,\n usageMetrics,\n passthroughData,\n },\n { timeoutInMs: 10000, productIdentifier: this.config.productIdentifier }\n )\n } catch (error) {\n this.log(\n 'license renewal failed: ' + (error as Error).message,\n LogLevel.WARN\n )\n throw new Error((error as Error).message)\n }\n\n const responseData = response.data\n\n if (response.status == 200) {\n if (\n !responseData.hasOwnProperty('licenseKey') ||\n !responseData.hasOwnProperty('x509')\n ) {\n this.log(\n 'license renewal failed: unexpected server response',\n LogLevel.WARN\n )\n throw new Error('unexpected server response')\n }\n const containerStr = this.stringifyCertContainer({\n licenseKey: responseData.licenseKey,\n x509: responseData.x509,\n } as TLicenseContainer)\n await this.config.saveCertStr(containerStr)\n\n this.log('license successfully renewed', LogLevel.INFO)\n\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n if (detachFloatingEntitlements) {\n this.log(\n `${responseData.detachedEntitlementsCount} floating entitlements were returned to the pool`,\n LogLevel.INFO\n )\n } else {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\n )\n }\n }\n\n await this.initCert()\n } else {\n const errorMsg = `license renewal failed: ${\n responseData.message ?? 'unknown reason'\n }`\n\n this.log(errorMsg, LogLevel.WARN)\n\n const e = new Error(errorMsg) as Error & { errorId?: string }\n\n if (responseData.errorId) {\n e.errorId = responseData.errorId\n\n if (\n ['NOT_FOUND', 'CONSUMER_TERMINATED'].includes(responseData.errorId)\n ) {\n this.log(\n 'license was terminated by the server. Deleting local cert.',\n LogLevel.WARN\n )\n await this.config.saveCertStr('')\n await this.initCert()\n } else if (responseData.errorId === 'FINGERPRINT_MISMATCH') {\n // pause auto-renewal as subsequent requests will also fail\n this.disableAutoRenewals()\n }\n }\n\n throw e\n }\n }\n\n private hasCert(): this is { licenseCert: TLicenseCertObj } {\n return !!this.licenseCert\n }\n\n isTerminated(): boolean {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n const now = new Date()\n\n return this.licenseCert.terminatesAt < now\n }\n\n getExpiryDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.expiresAt\n }\n\n getTerminationDate(): Date {\n if (!this.hasCert()) {\n throw new Error('Cert is not initialized')\n }\n\n return this.licenseCert.terminatesAt\n }\n\n isValid(useLogger = true): boolean {\n const logError = (msg: string) => {\n if (useLogger) {\n const debugMetadata = this.hasCert()\n ? `: (autorenewalsEnabled: ${this.config.autoRenewEnabled}, expiredAt: ${this.licenseCert?.expiresAt}, issuedAt: ${this.licenseCert?.issuedAt})`\n : ''\n\n this.log(`${msg}${debugMetadata}`, LogLevel.ERROR)\n }\n }\n\n if (!this.hasCert()) {\n logError('cert is invalid because it is undefined')\n return false\n }\n\n const cert = this.licenseCert as TLicenseCertObj\n const now = new Date()\n\n if (cert.expiresAt < now) {\n logError('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n logError('cert is invalid because it was terminated')\n return false\n }\n\n //allow clocks to be out of sync by no more than 300,000 ms / = 5 minutes\n if (cert.createdAt.getTime() - 300000 > now.getTime()) {\n logError('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n logError('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n logError('cert is invalid because tenant ID does not match')\n return false\n }\n\n return true\n }\n\n hasFeatureEnabled(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) ? true : false\n }\n\n hasFeatureDefined(\n feature: string,\n requireValidCert: boolean = true\n ): boolean {\n return this.getFeatureValue(feature, requireValidCert) !== undefined\n ? true\n : false\n }\n\n hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean {\n const quota = this.getFeatureValue(quotaFeatureName)\n\n if (quota === undefined) {\n return false\n }\n\n if (typeof quota !== 'number') {\n throw new Error(\n `${quotaFeatureName} cannot be used as quota as it is not numeric`\n )\n }\n\n // -1 means unlimited quota!\n if (quota === -1) {\n return true\n }\n\n return Math.ceil(currentConsumption) < Math.ceil(quota)\n }\n\n getFeatureValue(\n feature: string,\n requireValidCert: boolean = true\n ): undefined | boolean | number | string {\n if (!this.hasCert()) {\n return undefined\n }\n\n if (requireValidCert && !this.isValid()) {\n return undefined\n }\n\n const currentFeatures = this.getFeatures()\n\n if (!currentFeatures.hasOwnProperty(feature)) {\n return undefined\n }\n\n return currentFeatures[feature]\n }\n\n private updateCurrentFeatures() {\n if (!this.hasCert()) {\n return\n }\n\n const now = new Date()\n\n if (\n this.licenseCert.expiresAt < now ||\n this.licenseCert.terminatesAt < now\n ) {\n this.currentFeatures = {} as TFeatures\n }\n\n this.currentFeatures = this.licenseCert.entitlements\n .filter(\n (entitlement) =>\n entitlement.validFrom <= now && entitlement.validTo > now\n )\n .sort(\n (entitlement1, entitlement2) =>\n entitlement1.validFrom.getTime() - entitlement2.validFrom.getTime()\n )\n .reduce((currentFeatures, entitlement) => {\n return {\n ...currentFeatures,\n ...entitlement.features,\n ...entitlement.featureOverrides,\n }\n }, {} as TFeatures)\n }\n\n getFeatures() {\n if (!this.hasCert()) {\n return {}\n }\n\n return this.currentFeatures ?? {}\n }\n\n getCurrentEntitlements() {\n if (!this.hasCert()) {\n return []\n }\n\n const now = new Date()\n\n return this.licenseCert.entitlements.filter(\n (entitlement) => entitlement.validFrom <= now && entitlement.validTo > now\n )\n }\n\n getManagementJwt() {\n if (!this.licenseCert) {\n return ''\n }\n\n return this.licenseCert.managementJwt\n }\n\n async getCertStr(): Promise<TLicenseBlock> {\n return this.config.loadCertStr()\n }\n\n getConsumerId() {\n return this.licenseCert?.consumerId\n }\n\n isRenewalDue(): boolean {\n if (!this.licenseCert || this.licenseCert.isEphemeral) {\n return false\n }\n\n const now = Date.now()\n const mins15inMs = 1000 * 60 * 15\n const mins20inMs = 1000 * 60 * 20\n const expiry = this.licenseCert.expiresAt.getTime()\n const issuedAt = this.licenseCert.issuedAt.getTime()\n const termination = this.licenseCert.terminatesAt.getTime()\n\n //consumerRenewalDue is TRUE when current time is close enough to consumer expiry and not after consumer termination\n const consumerRenewalDue =\n now > expiry - this.config.autoRenewOffset! * 1000 && now < termination\n\n //entitlementRenewalDue is TRUE when one currently valid entitlement will expire in the next 15 minutes\n //and the Cert was issued more than 20 minutes ago\n const entitlementRenewalDue =\n this.getCurrentEntitlements().find(\n (entitlement) =>\n now >= entitlement.validTo.getTime() - mins15inMs &&\n now <= entitlement.validTo.getTime()\n ) !== undefined && issuedAt < now - mins20inMs\n\n return consumerRenewalDue || entitlementRenewalDue\n }\n\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const remainingSeconds = seconds % 60\n\n return `${hours}h ${minutes}m ${remainingSeconds}s`\n }\n\n toString() {\n const isValid = this.isValid(false)\n const isRenewalDue = this.isRenewalDue()\n const hasDetachedEntitlements =\n (this.licenseCert?.detachedEntitlementsCount ?? 0) > 0\n\n // Helper function to format values with warnings\n const formatWithWarning = (value: any, condition: any) =>\n `${value}${condition ? ' (!)' : ''}`\n\n // Helper function to display value or default\n const formatValue = (value: any, defaultValue = '<n/a>') =>\n value ?? defaultValue\n\n // Build sections of the output\n const consumerConfig = [\n '## CONSUMER CONFIG ##',\n `tenantId: ${formatValue(this.config.tenantId)}`,\n `productIdentifier: ${formatValue(this.config.productIdentifier)}`,\n `deviceFingerprint: ${formatValue(this.deviceFingerprint)}`,\n `autoRenewalEnabled: ${formatWithWarning(\n this.config.autoRenewEnabled ? 'true' : 'false',\n !this.config.autoRenewEnabled\n )}`,\n `autoRenewalOffset: ${\n this.config.autoRenewOffset\n } (= ${this.formatDuration(this.config.autoRenewOffset ?? 0)})`,\n ].join('\\n')\n\n const licenseCert = [\n '## LICENSE CERT ##',\n `version: ${formatValue(this.licenseCert?.version)}`,\n `tenantId: ${formatWithWarning(\n formatValue(this.licenseCert?.tenantId),\n this.licenseCert?.tenantId !== this.config.tenantId\n )}`,\n `consumerId: ${formatValue(this.licenseCert?.consumerId)}`,\n `deviceFingerprint: ${formatWithWarning(\n formatValue(this.licenseCert?.deviceFingerprint),\n this.licenseCert?.deviceFingerprint !== this.deviceFingerprint\n )}`,\n `createdAt: ${formatValue(this.licenseCert?.createdAt)}`,\n `issuedAt: ${formatValue(this.licenseCert?.issuedAt)}`,\n `expiresAt: ${formatValue(this.licenseCert?.expiresAt)}`,\n `terminatesAt: ${formatValue(this.licenseCert?.terminatesAt)}`,\n `isEphemeral: ${formatValue(this.licenseCert?.isEphemeral)}`,\n `isValid: ${formatWithWarning(isValid, !isValid)}`,\n `isRenewalDue: ${formatWithWarning(isRenewalDue, isRenewalDue)}`,\n `detachedEntitlementsCount: ${formatWithWarning(\n formatValue(this.licenseCert?.detachedEntitlementsCount),\n hasDetachedEntitlements\n )}`,\n `entitlements: ${this.licenseCert?.entitlements?.length ?? 0}`,\n ].join('\\n')\n\n // Format entitlements\n const entitlements =\n this.licenseCert?.entitlements\n ?.map((entitlement, index) =>\n [\n '## ENTITLEMENT ' + (index + 1) + ' ##',\n `id: ${entitlement.id}`,\n `productId: ${entitlement.productId}`,\n `validFrom: ${entitlement.validFrom}`,\n `validTo: ${entitlement.validTo}`,\n `features: ${JSON.stringify(entitlement.features)}`,\n `featureOverrides: ${JSON.stringify(entitlement.featureOverrides)}`,\n ].join('\\n')\n )\n .join('\\n--\\n') || ''\n\n // Combine all sections with proper separators\n return [\n consumerConfig,\n '--',\n licenseCert,\n entitlements ? '--\\n' + entitlements : '',\n ].join('\\n')\n }\n\n private triggerOnFeatureChangeCallback() {\n if (this.config.onFeatureChange) {\n this.config.onFeatureChange(this.currentFeatures ?? {})\n }\n }\n\n private setTimerForNextEntitlementChange() {\n if (!this.hasCert()) {\n return\n }\n\n const now = Date.now()\n const offsets = new Set<number>()\n\n offsets.add(this.licenseCert.expiresAt.getTime() - now)\n offsets.add(this.licenseCert.terminatesAt.getTime() - now)\n\n const upcomingEventOffsets = [\n ...this.licenseCert.entitlements.reduce((offsets, entitlement) => {\n offsets.add(entitlement.validFrom.getTime() - now)\n offsets.add(entitlement.validTo.getTime() - now)\n return offsets\n }, offsets),\n ]\n .filter((offset) => offset >= 0 && offset <= AUTORENEWAL_INTERVAL) // keep if offset is within the next 15 minutes\n .sort((a, b) => a - b)\n\n //console.dir(upcomingEventOffsets.map((offset) => offset / 1000 / 60))\n\n if (upcomingEventOffsets.length === 0) {\n return\n }\n\n const timeTillNextEventInMs = upcomingEventOffsets[0]\n\n this.clearSingleTimer(this.entitlementChangeTimer)\n this.entitlementChangeTimer = this.setupSingleTimer(() => {\n this.updateCurrentFeatures()\n this.triggerOnFeatureChangeCallback()\n this.setTimerForNextEntitlementChange()\n }, timeTillNextEventInMs + 1000)\n }\n\n private async renewalCron({ force }: { force: boolean }) {\n if (force || this.isRenewalDue()) {\n this.log('attempting license renewal', LogLevel.INFO)\n try {\n await this._renew({ cause: force ? 'startup' : 'auto' })\n } catch (e) {}\n }\n }\n\n private async initCert() {\n if (this.isShuttingDown) {\n return\n }\n\n try {\n const containerStr = await this.getCertStr()\n if (!containerStr) {\n this.licenseCert = undefined\n return\n }\n if (containerStr.length < 50) {\n throw new Error('cert string is undefined or too short')\n }\n const { x509, licenseKey } =\n this.parseLicenseCertContainerStr(containerStr)\n this.x509Cert = new X509Certificate(x509)\n const hasApprovedIssuer = this.x509Cert.checkIssued(this.getIssuerCert())\n if (!hasApprovedIssuer) {\n throw new Error('cert was not issued by an approved issuer')\n }\n const publicKey = this.x509Cert.publicKey.export({\n format: 'pem',\n type: 'pkcs1',\n })\n this.key = new NodeRSA(publicKey)\n this.licenseCert = this.parseLicenseKeyStr(licenseKey)\n this.updateCurrentFeatures()\n this.setTimerForNextEntitlementChange()\n } catch (e) {\n this.log(\n `cert could not be initialized. ${e instanceof Error ? e.message : ''}`,\n LogLevel.ERROR\n )\n }\n }\n\n private stringifyCertContainer(container: TLicenseContainer): string {\n const containerStr = JSON.stringify(container)\n return Buffer.from(containerStr).toString('base64')\n }\n\n private parseLicenseCertContainerStr(\n stringifiedContainer: string\n ): TLicenseContainer {\n const containerStr = Buffer.from(stringifiedContainer, 'base64').toString(\n 'ascii'\n )\n const container = JSON.parse(containerStr)\n if (\n !container.hasOwnProperty('licenseKey') ||\n !container.hasOwnProperty('x509')\n ) {\n throw new Error('license cert container could not be parsed')\n }\n\n return container as TLicenseContainer\n }\n\n private parseLicenseKeyStr(certStr: string): TLicenseCertObj {\n const certPayload = this.validateLicenseKey(certStr)\n\n const cert = { ...certPayload } as TLicenseCertObj\n\n // turn timestamp strings into Date objects\n cert.createdAt = new Date(certPayload.createdAt)\n cert.issuedAt = new Date(certPayload.issuedAt)\n cert.expiresAt = new Date(certPayload.expiresAt)\n cert.terminatesAt = new Date(certPayload.terminatesAt)\n\n // make sure detachedEntitlementsCount is a number (certs issues before this field was introduced will have it missing)\n cert.detachedEntitlementsCount = certPayload.detachedEntitlementsCount ?? 0\n\n cert.entitlements = cert.entitlements.map((entitlement) => {\n entitlement.validFrom = new Date(entitlement.validFrom)\n entitlement.validTo = new Date(entitlement.validTo)\n return entitlement\n })\n\n return cert\n }\n\n private validateLicenseKey(licenseKey: string) {\n //remove all line breaks\n licenseKey = licenseKey.replace(/(\\r\\n|\\n|\\r)/gm, '')\n\n //extract parts\n const match = licenseKey.match(\n /^-----BEGIN LICENSE KEY-----(?<encryptedSymmetricKey>.+\\|\\|)(?<encryptedData>.+)\\|\\|(?<signature>.+)-----END LICENSE KEY-----$/\n )\n\n if (!match) {\n throw new Error('license key could not be parsed')\n }\n\n const encryptedSymmetricKey = match.groups!.encryptedSymmetricKey\n const payload = match.groups!.encryptedData\n const signature = match.groups!.signature\n\n let symmetricKey, decryptedData\n\n //decrypt the random symmetric key\n try {\n symmetricKey = this.key!.decryptPublic(encryptedSymmetricKey, 'utf8')\n } catch (e) {\n throw new Error('Invalid data: Could not extract symmetric key')\n }\n\n //decrypt the payload\n try {\n decryptedData = CryptoJS.AES.decrypt(payload, symmetricKey).toString(\n CryptoJS.enc.Utf8\n )\n } catch (e) {\n throw new Error('Invalid Data: Could not decrypt data with key found')\n }\n\n //verify the signature.\n if (\n this.key!.verify(Buffer.from(decryptedData), signature, 'utf8', 'base64')\n ) {\n //return the decrypted data.\n return JSON.parse(decryptedData)\n } else {\n throw new Error('License Key signature invalid')\n }\n }\n\n public getIssuerCert() {\n return this.x509IssuerCert\n }\n\n /**\n * Detaches any floating entitlements and clears the local license cert.\n */\n public async clear() {\n try {\n await this.detachFloatingEntitlements()\n } catch (err) {\n this.log(\n `failed to detach floating entitlements (${err}). Continuing with clearing license certificate`,\n LogLevel.WARN\n )\n } finally {\n await this.config.saveCertStr('')\n await this.initCert()\n }\n }\n\n public async shutdown() {\n this.isShuttingDown = true\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.clearRepeatingTimer(this.upcomingEntitlementChangesCheckTimer)\n this.clearSingleTimer(this.entitlementChangeTimer)\n\n if (this.config.detachFloatingOnShutdown) {\n await this.detachFloatingEntitlements()\n }\n }\n\n private async detachFloatingEntitlements() {\n if (!this.hasCert()) {\n return\n }\n\n const hasFloatableEntitlements = this.licenseCert.entitlements.some(\n (entitlement) => entitlement.isFloatable ?? false\n )\n\n if (hasFloatableEntitlements) {\n await this._renew({\n detachFloatingEntitlements: true,\n cause: 'shutdown',\n })\n }\n }\n\n /** Enable periodical renewal of the license. */\n public enableAutoRenewals() {\n if (this.config.autoRenewEnabled === true) return\n\n this.config.autoRenewEnabled = true\n this.log('License auto-renewals enabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = this.setupRepeatingTimer(\n () => this.renewalCron({ force: false }),\n AUTORENEWAL_INTERVAL\n )\n }\n\n /** Disable periodical renewal of the license. */\n public disableAutoRenewals() {\n if (this.config.autoRenewEnabled === false) return\n\n this.config.autoRenewEnabled = false\n this.log('License auto-renewals disabled', LogLevel.INFO)\n\n this.clearRepeatingTimer(this.renewalTimer)\n this.renewalTimer = undefined\n }\n}\n","import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.1' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.1'\n"],"mappings":"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","names":["CryptoJS","machineId","NodeRSA","ok","X509Certificate","fetch","ProxyAgent","URL","SDK_VERSION","getProxyAgent","envVar","proxyURI","ProxyAgent","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","URL","proxyAgent","response","fetch","SDK_VERSION","err","error","AUTORENEWAL_INTERVAL","LicenseManager","config","X509Certificate","msg","logLevel","ok","AUTORENEWAL_INTERVAL","callback","interval","timer","date","durationInMs","machineId","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","passthroughData","responseData","now","useLogger","logError","debugMetadata","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","seconds","hours","minutes","remainingSeconds","isValid","isRenewalDue","hasDetachedEntitlements","formatWithWarning","value","condition","formatValue","defaultValue","consumerConfig","licenseCert","entitlements","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS","err"]}
|
|
@@ -86,7 +86,7 @@ export declare class LicenseManager {
|
|
|
86
86
|
disableAutoRenewals(): void;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
export declare function licenseManagerFactory(config?: {}): LicenseManager;
|
|
89
|
+
export declare function licenseManagerFactory(config?: {}, mockLogger?: TLogger): LicenseManager;
|
|
90
90
|
|
|
91
91
|
declare const enum LogLevel {
|
|
92
92
|
ERROR = "error",
|
|
@@ -127,7 +127,7 @@ export declare function postRequest<T>(url: string, data: Record<string, unknown
|
|
|
127
127
|
|
|
128
128
|
declare type RepeatingTimer = NodeJS.Timeout;
|
|
129
129
|
|
|
130
|
-
export declare const SDK_VERSION = "2.20.
|
|
130
|
+
export declare const SDK_VERSION = "2.20.1";
|
|
131
131
|
|
|
132
132
|
declare type SingleTimer = NodeJS.Timeout;
|
|
133
133
|
|
|
@@ -86,7 +86,7 @@ export declare class LicenseManager {
|
|
|
86
86
|
disableAutoRenewals(): void;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
export declare function licenseManagerFactory(config?: {}): LicenseManager;
|
|
89
|
+
export declare function licenseManagerFactory(config?: {}, mockLogger?: TLogger): LicenseManager;
|
|
90
90
|
|
|
91
91
|
declare const enum LogLevel {
|
|
92
92
|
ERROR = "error",
|
|
@@ -127,7 +127,7 @@ export declare function postRequest<T>(url: string, data: Record<string, unknown
|
|
|
127
127
|
|
|
128
128
|
declare type RepeatingTimer = NodeJS.Timeout;
|
|
129
129
|
|
|
130
|
-
export declare const SDK_VERSION = "2.20.
|
|
130
|
+
export declare const SDK_VERSION = "2.20.1";
|
|
131
131
|
|
|
132
132
|
declare type SingleTimer = NodeJS.Timeout;
|
|
133
133
|
|
package/dist/httpRequest.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(t,e)=>{for(var r in e)c(t,r,{get:e[r],enumerable:!0})},_=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of g(e))!d.call(t,o)&&o!==r&&c(t,o,{get:()=>e[o],enumerable:!(s=x(e,o))||s.enumerable});return t};var P=t=>_(c({},"__esModule",{value:!0}),t);var I={};m(I,{default:()=>A,postRequest:()=>l});module.exports=P(I);var i=require("undici"),f=require("url");var y="2.20.
|
|
1
|
+
"use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(t,e)=>{for(var r in e)c(t,r,{get:e[r],enumerable:!0})},_=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of g(e))!d.call(t,o)&&o!==r&&c(t,o,{get:()=>e[o],enumerable:!(s=x(e,o))||s.enumerable});return t};var P=t=>_(c({},"__esModule",{value:!0}),t);var I={};m(I,{default:()=>A,postRequest:()=>l});module.exports=P(I);var i=require("undici"),f=require("url");var y="2.20.1";function p(t){let e=process.env[t]||process.env[t.toUpperCase()];return e?new i.ProxyAgent(e):!1}var a=p("http_proxy_license_server")||p("http_proxy"),u=p("https_proxy_license_server")||p("https_proxy"),R={...a?{"http:":a}:{},...u?{"https:":u}:{}},S=((process.env.no_proxy||process.env.NO_PROXY)??"").split(",").map(t=>t.trim()).filter(t=>t.length>0),w=t=>{let{host:e,protocol:r}=t;return!(r==="http:"&&!a||r==="https:"&&!u||S.some(s=>e.endsWith(s)))};async function l(t,e,r={}){let s=new f.URL(t),o;w(s)&&(o=R[s.protocol]);try{let n=await(0,i.fetch)(t,{method:"POST",body:JSON.stringify(e),headers:{"Content-Type":"application/json","User-Agent":`License-SDK/${y} (Node.js ${process.version}; ${process.platform}) ${r.productIdentifier??""}`},signal:AbortSignal.timeout(r.timeoutInMs??3e4),...o?{dispatcher:o}:{}});return{status:n.status,data:await n.json()}}catch(n){let h=new Error("Connection Error: "+n.message);throw h.cause=n,h}}var A={postRequest:l};0&&(module.exports={postRequest});
|
|
2
2
|
//# sourceMappingURL=httpRequest.js.map
|
package/dist/httpRequest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.
|
|
1
|
+
{"version":3,"sources":["../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.1' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.1'\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAAkC,kBAElCC,EAAoB,eCDb,IAAMC,EAAc,SDI3B,SAASC,EAAcC,EAAgB,CACrC,IAAMC,EAAW,QAAQ,IAAID,CAAM,GAAK,QAAQ,IAAIA,EAAO,YAAY,CAAC,EACxE,OAAOC,EAAW,IAAI,aAAWA,CAAQ,EAAI,EAC/C,CAEA,IAAMC,EACJH,EAAc,2BAA2B,GAAKA,EAAc,YAAY,EAEpEI,EACJJ,EAAc,4BAA4B,GAAKA,EAAc,aAAa,EAEtEK,EAAc,CAClB,GAAIF,EAAY,CAAE,QAASA,CAAU,EAAI,CAAC,EAC1C,GAAIC,EAAa,CAAE,SAAUA,CAAW,EAAI,CAAC,CAC/C,EAEME,IACH,QAAQ,IAAI,UAAe,QAAQ,IAAI,WACxC,IAEC,MAAM,GAAG,EACT,IAAKC,GAASA,EAAK,KAAK,CAAC,EACzB,OAAQA,GAASA,EAAK,OAAS,CAAC,EAE7BC,EAAkBC,GAAa,CACnC,GAAM,CAAE,KAAAC,EAAM,SAAAC,CAAS,EAAIF,EAU3B,MARI,EAAAE,IAAa,SAAW,CAACR,GAIzBQ,IAAa,UAAY,CAACP,GAI1BE,EAAa,KAAMC,GAASG,EAAK,SAASH,CAAI,CAAC,EAKrD,EAEA,eAAsBK,EACpBH,EACAI,EACAC,EAGI,CAAC,EACL,CACA,IAAMC,EAAY,IAAI,MAAIN,CAAG,EAEzBO,EAEAR,EAAeO,CAAS,IAC1BC,EAAaX,EAAYU,EAAU,QAA8B,GAGnE,GAAI,CACF,IAAME,EAAW,QAAM,SAAMR,EAAK,CAChC,OAAQ,OACR,KAAM,KAAK,UAAUI,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,aAAc,eAAeK,CAAW,aACtC,QAAQ,OACV,KAAK,QAAQ,QAAQ,KAAKJ,EAAQ,mBAAqB,EAAE,EAC3D,EACA,OAAQ,YAAY,QAAQA,EAAQ,aAAe,GAAM,EACzD,GAAIE,EAAa,CAAE,WAAYA,CAAW,EAAI,CAAC,CACjD,CAAC,EAED,MAAO,CACL,OAAQC,EAAS,OACjB,KAAO,MAAMA,EAAS,KAAK,CAC7B,CACF,OAASE,EAAK,CACZ,IAAMC,EAAQ,IAAI,MAAM,qBAAwBD,EAAY,OAAO,EAClE,MAACC,EAAc,MAAQD,EAClBC,CACR,CACF,CAEA,IAAOC,EAAQ,CACb,YAAAT,CACF","names":["httpRequest_exports","__export","httpRequest_default","postRequest","__toCommonJS","import_undici","import_node_url","SDK_VERSION","getProxyAgent","envVar","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","proxyAgent","response","SDK_VERSION","err","error","httpRequest_default"]}
|
package/dist/httpRequest.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{fetch as h,ProxyAgent as y}from"undici";import{URL as f}from"node:url";var u="2.20.
|
|
1
|
+
import{fetch as h,ProxyAgent as y}from"undici";import{URL as f}from"node:url";var u="2.20.1";function n(t){let e=process.env[t]||process.env[t.toUpperCase()];return e?new y(e):!1}var i=n("http_proxy_license_server")||n("http_proxy"),c=n("https_proxy_license_server")||n("https_proxy"),l={...i?{"http:":i}:{},...c?{"https:":c}:{}},x=((process.env.no_proxy||process.env.NO_PROXY)??"").split(",").map(t=>t.trim()).filter(t=>t.length>0),g=t=>{let{host:e,protocol:r}=t;return!(r==="http:"&&!i||r==="https:"&&!c||x.some(s=>e.endsWith(s)))};async function d(t,e,r={}){let s=new f(t),p;g(s)&&(p=l[s.protocol]);try{let o=await h(t,{method:"POST",body:JSON.stringify(e),headers:{"Content-Type":"application/json","User-Agent":`License-SDK/${u} (Node.js ${process.version}; ${process.platform}) ${r.productIdentifier??""}`},signal:AbortSignal.timeout(r.timeoutInMs??3e4),...p?{dispatcher:p}:{}});return{status:o.status,data:await o.json()}}catch(o){let a=new Error("Connection Error: "+o.message);throw a.cause=o,a}}var S={postRequest:d};export{S as default,d as postRequest};
|
|
2
2
|
//# sourceMappingURL=httpRequest.mjs.map
|
package/dist/httpRequest.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.
|
|
1
|
+
{"version":3,"sources":["../src/httpRequest.ts","../src/version.ts"],"sourcesContent":["import { fetch, ProxyAgent } from 'undici'\n\nimport { URL } from 'node:url'\nimport { SDK_VERSION } from './version'\n\nfunction getProxyAgent(envVar: string) {\n const proxyURI = process.env[envVar] || process.env[envVar.toUpperCase()]\n return proxyURI ? new ProxyAgent(proxyURI) : false\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\n\nconst httpsProxy =\n getProxyAgent('https_proxy_license_server') || getProxyAgent('https_proxy')\n\nconst proxyAgents = {\n ...(httpProxy ? { 'http:': httpProxy } : {}),\n ...(httpsProxy ? { 'https:': httpsProxy } : {}),\n}\n\nconst noProxyRules = (\n (process.env['no_proxy'] || process.env['NO_PROXY']) ??\n ''\n)\n .split(',')\n .map((rule) => rule.trim())\n .filter((rule) => rule.length > 0)\n\nconst shouldUseProxy = (url: URL) => {\n const { host, protocol } = url\n\n if (protocol === 'http:' && !httpProxy) {\n return false\n }\n\n if (protocol === 'https:' && !httpsProxy) {\n return false\n }\n\n if (noProxyRules.some((rule) => host.endsWith(rule))) {\n return false\n }\n\n return true\n}\n\nexport async function postRequest<T>(\n url: string,\n data: Record<string, unknown>,\n options: {\n timeoutInMs?: number\n productIdentifier?: string\n } = {}\n) {\n const targetUrl = new URL(url)\n\n let proxyAgent: ProxyAgent | undefined\n\n if (shouldUseProxy(targetUrl)) {\n proxyAgent = proxyAgents[targetUrl.protocol as 'http:' | 'https:']\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `License-SDK/${SDK_VERSION} (Node.js ${\n process.version\n }; ${process.platform}) ${options.productIdentifier ?? ''}`,\n },\n signal: AbortSignal.timeout(options.timeoutInMs ?? 30_000),\n ...(proxyAgent ? { dispatcher: proxyAgent } : {}),\n })\n\n return {\n status: response.status,\n data: (await response.json()) as T,\n }\n } catch (err) {\n const error = new Error('Connection Error: ' + (err as any).message)\n ;(error as any).cause = err\n throw error\n }\n}\n\nexport default {\n postRequest,\n}\n","// '2.20.1' is replaced before publishing to npm at .github/workflows/publish_sdk.yml\nexport const SDK_VERSION = '2.20.1'\n"],"mappings":"AAAA,OAAS,SAAAA,EAAO,cAAAC,MAAkB,SAElC,OAAS,OAAAC,MAAW,WCDb,IAAMC,EAAc,SDI3B,SAASC,EAAcC,EAAgB,CACrC,IAAMC,EAAW,QAAQ,IAAID,CAAM,GAAK,QAAQ,IAAIA,EAAO,YAAY,CAAC,EACxE,OAAOC,EAAW,IAAIC,EAAWD,CAAQ,EAAI,EAC/C,CAEA,IAAME,EACJJ,EAAc,2BAA2B,GAAKA,EAAc,YAAY,EAEpEK,EACJL,EAAc,4BAA4B,GAAKA,EAAc,aAAa,EAEtEM,EAAc,CAClB,GAAIF,EAAY,CAAE,QAASA,CAAU,EAAI,CAAC,EAC1C,GAAIC,EAAa,CAAE,SAAUA,CAAW,EAAI,CAAC,CAC/C,EAEME,IACH,QAAQ,IAAI,UAAe,QAAQ,IAAI,WACxC,IAEC,MAAM,GAAG,EACT,IAAKC,GAASA,EAAK,KAAK,CAAC,EACzB,OAAQA,GAASA,EAAK,OAAS,CAAC,EAE7BC,EAAkBC,GAAa,CACnC,GAAM,CAAE,KAAAC,EAAM,SAAAC,CAAS,EAAIF,EAU3B,MARI,EAAAE,IAAa,SAAW,CAACR,GAIzBQ,IAAa,UAAY,CAACP,GAI1BE,EAAa,KAAMC,GAASG,EAAK,SAASH,CAAI,CAAC,EAKrD,EAEA,eAAsBK,EACpBH,EACAI,EACAC,EAGI,CAAC,EACL,CACA,IAAMC,EAAY,IAAIC,EAAIP,CAAG,EAEzBQ,EAEAT,EAAeO,CAAS,IAC1BE,EAAaZ,EAAYU,EAAU,QAA8B,GAGnE,GAAI,CACF,IAAMG,EAAW,MAAMC,EAAMV,EAAK,CAChC,OAAQ,OACR,KAAM,KAAK,UAAUI,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,aAAc,eAAeO,CAAW,aACtC,QAAQ,OACV,KAAK,QAAQ,QAAQ,KAAKN,EAAQ,mBAAqB,EAAE,EAC3D,EACA,OAAQ,YAAY,QAAQA,EAAQ,aAAe,GAAM,EACzD,GAAIG,EAAa,CAAE,WAAYA,CAAW,EAAI,CAAC,CACjD,CAAC,EAED,MAAO,CACL,OAAQC,EAAS,OACjB,KAAO,MAAMA,EAAS,KAAK,CAC7B,CACF,OAASG,EAAK,CACZ,IAAMC,EAAQ,IAAI,MAAM,qBAAwBD,EAAY,OAAO,EAClE,MAACC,EAAc,MAAQD,EAClBC,CACR,CACF,CAEA,IAAOC,EAAQ,CACb,YAAAX,CACF","names":["fetch","ProxyAgent","URL","SDK_VERSION","getProxyAgent","envVar","proxyURI","ProxyAgent","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","shouldUseProxy","url","host","protocol","postRequest","data","options","targetUrl","URL","proxyAgent","response","fetch","SDK_VERSION","err","error","httpRequest_default"]}
|