import w from"crypto-js";import{machineId as F}from"node-machine-id";import A from"node-rsa";import{ok as S}from"node:assert";import{X509Certificate as C}from"node:crypto";import{fetch as T,ProxyAgent as v}from"undici";import{URL as E}from"node:url";var m="2.22.0";function u(c){let e=process.env[c]||process.env[c.toUpperCase()];return e?new v(e):!1}var d=u("http_proxy_license_server")||u("http_proxy"),f=u("https_proxy_license_server")||u("https_proxy"),I={...d?{"http:":d}:{},...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:"&&!d||t==="https:"&&!f||R.some(i=>e.endsWith(i)))};async function p(c,e,t={}){let i=new E(c),r;b(i)&&(r=I[i.protocol]);try{let n=await T(c,{method:"POST",body:JSON.stringify(e),headers:{"Content-Type":"application/json","User-Agent":`License-SDK/${m} (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 g=15*60*1e3;var y=class{constructor(e){this.expirySoonCallbackFired=!1;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-----
MIIFDDCCAvQCCQCWGBewlWbp0DANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJE
RTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAMMDmxp
Y2Vuc2UubjhuLmlvMB4XDTIyMDYyNDA0MDkzM1oXDTQ5MTEwOTA0MDkzM1owSDEL
MAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMRcw
FQYDVQQDDA5saWNlbnNlLm44bi5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
AgoCggIBANK6Uj5CSyPaa2rf/bwH/AqzzINeWg4n94pECv4p8tsjy0+ZscodNn7Q
IvYW/6IUpax8fZvHCSqu0L7fsgLkw0+HDLlsln+ryI/3h1ElVZm67BfqOvhSfPj+
btxcP8EtS+6hbf74sqPEBFD0wikKhIPGdtBolp7rLXfTGs+5eMqSA5q4W1V+HUUU
zgaCdchzlHGTdIICNpbRozGeFTIIx1MPzMie+4zIs6i680efx2KJVZWsa2WuCSED
+b0gSRTgoKQ3B7JjxJKfzHdOdM6JxhkCjrJIkJCrZL7wFypn+wMHsVFrsw/80WkS
dwBj/RqCPzKcRwnxs0WNLhkyT/XCMS/1pNzPymdFADu2tEZjhFsa5ziIhdoQz8po
Efheyg3mOZDWyu6oyHCLH9lUlsNjV9zZ6RICgvHZvHPmPqOLPomy4Qymq2osuH+S
28rwEy0W3DCEfuS3dZHrSQfohGC9EAyyFAIPSGhTJSYJl0oNBZjpRM+jAm9ER7PM
K70/7g6z8uIgKa8/SD/Pezd/aWzxH/tOokAF5X5o5TzSOwVzqOJzY06EZC7CJnhs
sigAJTy1trZJBcZuWnKY5FqrK3QzjsQ9sWM0tRocfNOYmD21mubNo+RmMMo3kvYL
JoBfap/cuP6kx3OiRzBJ4luTEa6nRIYy+EjcPaN3+9L5iEZ9/NABAgMBAAEwDQYJ
KoZIhvcNAQELBQADggIBAIUpJ0Rh6C92cJqy6iehS8c77r1prj62gr6Acdy5QGh8
ax30ANDbPtkezVIIBk+0JjLkMxr3mwqCRsPgMshPcxhZwEafmZrWPPGRVsOfukB3
Gp10cIv1YmZ7AFY4i/izj5184+A+GjxrJBULQG1JfX4c7KW06Kaps85AaX/Tp0fl
/hZ6oUe48aSSTuAW38hWZ5jCpBqfFyQ15ablJZt0fB8NkXEdFUcUEt/OHJfqF5fP
Nt5PWC1AuBxzSbzjwabOy/M4r8m5CzCeXSIjqbcsAq52myMoxvNrjKRtucQ7CjqK
LR6WdhMf+NLvyTI+evXMoXpDzlevkCpz17uDiDt9XrmvLSf3Ff8mdTRwzVmOmHfc
Ruz5v7WBR4cpBR/sC+WxOw9heLMHgYhPyRUM4voo55EcJGusXr/iavblBAnI0GUw
uMNs3MjEmfbaBV1K0GKG5UToF9UmUxxVmTcRUZrAQX+yBkRezDTpOQuRnB58BDQP
A62lcgZlikzJw3lHue33qAudyUrUmjfHGll7GFQNeLO42jPMeM4NJiNIrBZ7j0uD
4slHdDi/44PHcKchvde/5k7ZJMi6OC1Vu+bOnKvzhnWQIOkHFQ55m13oslV2ozZT
/oqhn/8/LeV0ooZuYnBeRkRTveniUeho2OFe5xZvWSSfuBrbHt9+zBg+5MWPUTIJ
-----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.expirySoonOffsetMins=this.config.expirySoonOffsetMins??0,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(){S(!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(),g),this.checkAndTriggerExpirySoonCallback(),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}),g))}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.clearSingleTimer(this.expirySoonTimer),this.expirySoonTimer=void 0,this.expirySoonCallbackFired=!1,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 p(`${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 p(`${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"),this.config.onLicenseRenewed?.(),(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(`
`),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(`
`),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(`
`)).join(`
--
`)||"";return[s,"--",a,l?`--
`+l:""].join(`
`)}triggerOnFeatureChangeCallback(){this.config.onFeatureChange&&this.config.onFeatureChange(this.currentFeatures??{})}setTimerForNextEntitlementChange(){if(!this.hasCert())return;let e=Date.now(),t=new Set;if(t.add(this.licenseCert.expiresAt.getTime()-e),t.add(this.licenseCert.terminatesAt.getTime()-e),this.config.onExpirySoon&&this.config.expirySoonOffsetMins){let n=this.licenseCert.expiresAt.getTime()-this.config.expirySoonOffsetMins*60*1e3;t.add(n-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<=g).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.checkAndTriggerExpirySoonCallback(),this.setTimerForNextEntitlementChange()},r+1e3)}checkAndTriggerExpirySoonCallback(){if(!this.hasCert()||!this.config.onExpirySoon||!this.config.expirySoonOffsetMins||this.expirySoonCallbackFired)return;let e=this.licenseCert.expiresAt.getTime()-Date.now(),t=this.config.expirySoonOffsetMins*60*1e3;if(e>0&&e<=t)try{this.config.onExpirySoon(),this.expirySoonCallbackFired=!0}catch(i){this.log(`Failed to run onExpirySoon callback: ${i}`,"error")}}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(),this.expirySoonCallbackFired=!1}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.clearSingleTimer(this.expirySoonTimer),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}),g))}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{g as AUTORENEWAL_INTERVAL,y as LicenseManager};
//# sourceMappingURL=LicenseManager.mjs.map