@n8n_io/license-sdk 2.10.0 → 2.11.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.d.mts +10 -0
- package/dist/LicenseManager.d.ts +10 -125
- package/dist/LicenseManager.js +21 -21
- package/dist/LicenseManager.js.map +1 -1
- package/dist/LicenseManager.mjs +21 -21
- package/dist/LicenseManager.mjs.map +1 -1
- package/dist/_tsup-dts-rollup.d.mts +178 -0
- package/dist/_tsup-dts-rollup.d.ts +178 -0
- package/dist/httpRequest.d.mts +2 -0
- package/dist/httpRequest.d.ts +2 -11
- package/dist/httpRequest.js.map +1 -1
- package/dist/httpRequest.mjs.map +1 -1
- package/package.json +19 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n autoRenewEnabled?: 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 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 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 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 managementJwt: string\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\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 isInitializationCompleted = false\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 renewalIntervalPointer?: NodeJS.Timeout\n private checkUpcomingEntitlementChangesCron?: NodeJS.Timeout\n private entitlementChangeTimeoutPointer?: NodeJS.Timeout\n private currentFeatures?: TFeatures\n private isShuttingDown = false\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.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license] ${msg}`)\n }\n\n private isInitialized() {\n return this.isInitializationCompleted\n }\n\n async initialize() {\n if (this.isInitialized()) {\n return\n }\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n await this.initCert()\n\n //set up periodic timer to assess check upcoming entitlement / feature changes\n this.checkUpcomingEntitlementChangesCron = setInterval(\n () => this.setTimerForNextEntitlementChange(),\n 1000 * 60 * 15 //15 minutes\n )\n\n if (this.config.autoRenewEnabled) {\n //invoke renewal immediately once, unless disabled:\n if (this.config.renewOnInit) {\n await this.renewalCron({ force: true })\n }\n\n //and periodically:\n this.renewalIntervalPointer = setInterval(\n () => this.renewalCron({ force: false }),\n 1000 * 60 * 15 //15 minutes\n )\n }\n\n this.isInitializationCompleted = true\n }\n\n async reload() {\n this.reset()\n await this.initialize()\n }\n\n reset() {\n if (this.config.autoRenewEnabled) {\n clearInterval(this.renewalIntervalPointer)\n }\n if (this.checkUpcomingEntitlementChangesCron) {\n clearInterval(this.checkUpcomingEntitlementChangesCron)\n }\n if (this.entitlementChangeTimeoutPointer) {\n clearTimeout(this.entitlementChangeTimeoutPointer)\n }\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.isInitializationCompleted = false\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, { timeoutInMs: 10000 })\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 const usageMetrics = this.config.collectUsageMetrics\n ? await this.config.collectUsageMetrics()\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 },\n { timeoutInMs: 10000 }\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 this.log('license successfully renewed', LogLevel.DEBUG)\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\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 }\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 debug = (msg: string) => {\n if (useLogger) {\n this.log(msg, LogLevel.DEBUG)\n }\n }\n\n if (!this.hasCert()) {\n debug('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 debug('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n debug('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 debug('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n debug('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n debug('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 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 = new Date().getTime()\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 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 '--\\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 `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 = new Date().getTime()\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 <= 15 * 60 * 1000) // 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 clearTimeout(this.entitlementChangeTimeoutPointer)\n this.entitlementChangeTimeoutPointer = setTimeout(() => {\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.config.loadCertStr()\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.triggerOnFeatureChangeCallback()\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 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 public async shutdown() {\n this.isShuttingDown = true\n\n if (this.config.autoRenewEnabled) {\n clearInterval(this.renewalIntervalPointer)\n }\n if (this.checkUpcomingEntitlementChangesCron) {\n clearInterval(this.checkUpcomingEntitlementChangesCron)\n }\n if (this.entitlementChangeTimeoutPointer) {\n clearTimeout(this.entitlementChangeTimeoutPointer)\n }\n\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({ detachFloatingEntitlements: true, cause: 'shutdown' })\n }\n }\n}\n","import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"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","names":["CryptoJS","machineId","NodeRSA","X509Certificate","fetch","getGlobalDispatcher","setGlobalDispatcher","Dispatcher","ProxyAgent","URL","getProxyAgent","variableName","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","defaultDispatcher","options","handler","host","protocol","proxyAgent","postRequest","url","data","controller","timeout","response","responseJson","err","LicenseManager","config","X509Certificate","msg","logLevel","machineId","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","responseData","now","useLogger","debug","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","_a","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS"]}
|
|
1
|
+
{"version":3,"sources":["../src/LicenseManager.ts","../src/httpRequest.ts"],"sourcesContent":["import CryptoJS from 'crypto-js'\nimport { machineId } from 'node-machine-id'\nimport NodeRSA from 'node-rsa'\nimport { X509Certificate } from 'node:crypto'\nimport { postRequest } from './httpRequest'\n\nexport type TLicenseManagerConfig = {\n server?: string\n tenantId: number\n productIdentifier: string\n autoRenewEnabled?: 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 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 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 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 managementJwt: string\n isEphemeral: boolean\n}\n\nexport type TLogger = {\n error: Function\n warn: Function\n info: Function\n debug: Function\n}\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 isInitializationCompleted = false\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 renewalIntervalPointer?: NodeJS.Timeout\n private checkUpcomingEntitlementChangesCron?: NodeJS.Timeout\n private entitlementChangeTimeoutPointer?: NodeJS.Timeout\n private currentFeatures?: TFeatures\n private isShuttingDown = false\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.server = this.config.server ?? 'https://license.n8n.io/v1'\n }\n\n log(msg: string, logLevel: LogLevel) {\n this.logger[logLevel](`[license] ${msg}`)\n }\n\n private isInitialized() {\n return this.isInitializationCompleted\n }\n\n async initialize() {\n if (this.isInitialized()) {\n return\n }\n\n this.deviceFingerprint = await this.computeDeviceFingerprint()\n this.log(\n `initializing for deviceFingerprint ${this.deviceFingerprint}`,\n LogLevel.DEBUG\n )\n await this.initCert()\n\n //set up periodic timer to assess check upcoming entitlement / feature changes\n this.checkUpcomingEntitlementChangesCron = setInterval(\n () => this.setTimerForNextEntitlementChange(),\n 1000 * 60 * 15 //15 minutes\n )\n\n if (this.config.autoRenewEnabled) {\n //invoke renewal immediately once, unless disabled:\n if (this.config.renewOnInit) {\n await this.renewalCron({ force: true })\n }\n\n //and periodically:\n this.renewalIntervalPointer = setInterval(\n () => this.renewalCron({ force: false }),\n 1000 * 60 * 15 //15 minutes\n )\n }\n\n this.isInitializationCompleted = true\n }\n\n async reload() {\n this.reset()\n await this.initialize()\n }\n\n reset() {\n if (this.config.autoRenewEnabled) {\n clearInterval(this.renewalIntervalPointer)\n }\n if (this.checkUpcomingEntitlementChangesCron) {\n clearInterval(this.checkUpcomingEntitlementChangesCron)\n }\n if (this.entitlementChangeTimeoutPointer) {\n clearTimeout(this.entitlementChangeTimeoutPointer)\n }\n this.licenseCert = undefined\n this.deviceFingerprint = undefined\n this.isInitializationCompleted = false\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, { timeoutInMs: 10000 })\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 const usageMetrics = this.config.collectUsageMetrics\n ? await this.config.collectUsageMetrics()\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 },\n { timeoutInMs: 10000 }\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 this.log('license successfully renewed', LogLevel.DEBUG)\n if (responseData.detachedEntitlementsCount ?? 0 > 0) {\n this.log(\n `skipped importing ${responseData.detachedEntitlementsCount} floating entitlements which are currently in use elsewhere`,\n LogLevel.INFO\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 }\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 debug = (msg: string) => {\n if (useLogger) {\n this.log(msg, LogLevel.DEBUG)\n }\n }\n\n if (!this.hasCert()) {\n debug('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 debug('cert is invalid because it has expired')\n return false\n }\n\n if (cert.terminatesAt < now) {\n debug('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 debug('cert is invalid because system clock is out of sync')\n return false\n }\n\n if (cert.deviceLock && this.deviceFingerprint !== cert.deviceFingerprint) {\n debug('cert is invalid because device fingerprint does not match')\n return false\n }\n\n if (this.config.tenantId !== cert.tenantId) {\n debug('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 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 = new Date().getTime()\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 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 '--\\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 `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 = new Date().getTime()\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 <= 15 * 60 * 1000) // 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 clearTimeout(this.entitlementChangeTimeoutPointer)\n this.entitlementChangeTimeoutPointer = setTimeout(() => {\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.config.loadCertStr()\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.triggerOnFeatureChangeCallback()\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 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 public async shutdown() {\n this.isShuttingDown = true\n\n if (this.config.autoRenewEnabled) {\n clearInterval(this.renewalIntervalPointer)\n }\n if (this.checkUpcomingEntitlementChangesCron) {\n clearInterval(this.checkUpcomingEntitlementChangesCron)\n }\n if (this.entitlementChangeTimeoutPointer) {\n clearTimeout(this.entitlementChangeTimeoutPointer)\n }\n\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({ detachFloatingEntitlements: true, cause: 'shutdown' })\n }\n }\n}\n","import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"AAAA,OAAOA,MAAc,YACrB,OAAS,aAAAC,MAAiB,kBAC1B,OAAOC,MAAa,WACpB,OAAS,mBAAAC,MAAuB,SCHhC,OACE,SAAAC,EACA,uBAAAC,EACA,uBAAAC,EACA,cAAAC,EACA,cAAAC,MACK,SAEP,OAAS,OAAAC,MAAW,MAEpB,SAASC,EAAcC,EAAsB,CAC3C,IAAMC,EAAW,QAAQ,IAAID,CAAY,EACzC,OAAOC,EAAW,IAAIJ,EAAWI,CAAQ,EAAI,IAC/C,CAEA,IAAMC,EACJH,EAAc,2BAA2B,GAAKA,EAAc,YAAY,EACpEI,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,GAAgB,QAAQ,IAAI,UAAe,IAC9C,MAAM,GAAG,EACT,IAAKC,GAASA,EAAK,KAAK,CAAC,EAEtBC,EAAoBb,EAAoB,EAE9CC,EACE,IAAK,cAAcC,CAAW,CAC5B,SAASY,EAAcC,EAAc,CACnC,GAAID,EAAQ,OAAQ,CAClB,GAAM,CAAE,KAAAE,EAAM,SAAAC,CAAS,EACrB,OAAOH,EAAQ,QAAW,SACtB,IAAIV,EAAIU,EAAQ,MAAM,EACtBA,EAAQ,OACd,GACE,CAACH,EAAa,KAAMC,GAClBA,EAAK,WAAW,GAAG,EAAII,EAAK,SAASJ,CAAI,EAAII,IAASJ,CACxD,EACA,CACA,IAAMM,EAAaR,EAAYO,CAA8B,EACzDC,GACFA,EAAW,SAASJ,EAASC,CAAO,CAExC,CACF,CACA,OAAOF,EAAkB,SAASC,EAASC,CAAO,CACpD,CACF,CACF,EAEA,eAAsBI,EACpBC,EACAC,EACAP,EAEI,CAAC,EACL,CACA,IAAMQ,EAAa,IAAI,gBAEjBC,EAAU,WAAW,IAAM,CAC/BD,EAAW,MAAM,CACnB,EAAGR,EAAQ,aAAe,GAAK,EAE/B,GAAI,CACF,IAAMU,EAAW,MAAMzB,EAAMqB,EAAK,CAChC,OAAQ,OACR,KAAM,KAAK,UAAUC,CAAI,EACzB,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,OAAQC,EAAW,MACrB,CAAC,EAEKG,EAAe,MAAMD,EAAS,KAAK,EAEzC,MAAO,CACL,OAAQA,EAAS,OACjB,KAAMC,CACR,CACF,OAASC,EAAK,CACZ,MAAM,IAAI,MAAM,mBAAoB,CAAE,MAAOA,CAAI,CAAC,CACpD,QAAE,CACA,aAAaH,CAAO,CACtB,CACF,CDTO,IAAMI,EAAN,KAAqB,CAgB1B,YAAYC,EAA+B,CAb3C,KAAQ,0BAA4B,GAWpC,KAAQ,eAAiB,GAGvB,KAAK,OAASA,EAEV,KAAK,OAAO,OACd,KAAK,OAAS,KAAK,OAAO,OAE1B,KAAK,OAAS,CACZ,OAAQ,CACN,QAAQ,IAAI,SAAU,GAAG,SAAS,CACpC,EACA,MAAO,CACL,QAAQ,IAAI,QAAS,GAAG,SAAS,CACnC,EACA,MAAO,CACL,QAAQ,IAAI,QAAS,GAAG,SAAS,CACnC,EACA,OAAQ,CACN,QAAQ,IAAI,SAAU,GAAG,SAAS,CACpC,CACF,EAGF,KAAK,eAAiB,IAAIC,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BA6BF,EAGA,KAAK,OAAO,iBAAmB,KAAK,OAAO,kBAAoB,GAC/D,KAAK,OAAO,YAAc,KAAK,OAAO,aAAe,GACrD,KAAK,OAAO,YAAc,KAAK,OAAO,aAAe,GACrD,KAAK,OAAO,gBAAkB,KAAK,OAAO,iBAAmB,GAAK,GAAK,GACvE,KAAK,OAAO,OAAS,KAAK,OAAO,QAAU,2BAC7C,CAEA,IAAIC,EAAaC,EAAoB,CACnC,KAAK,OAAOA,CAAQ,EAAE,aAAaD,CAAG,EAAE,CAC1C,CAEQ,eAAgB,CACtB,OAAO,KAAK,yBACd,CAEA,MAAM,YAAa,CACb,KAAK,cAAc,IAIvB,KAAK,kBAAoB,MAAM,KAAK,yBAAyB,EAC7D,KAAK,IACH,sCAAsC,KAAK,iBAAiB,GAC5D,OACF,EACA,MAAM,KAAK,SAAS,EAGpB,KAAK,oCAAsC,YACzC,IAAM,KAAK,iCAAiC,EAC5C,IAAO,GAAK,EACd,EAEI,KAAK,OAAO,mBAEV,KAAK,OAAO,aACd,MAAM,KAAK,YAAY,CAAE,MAAO,EAAK,CAAC,EAIxC,KAAK,uBAAyB,YAC5B,IAAM,KAAK,YAAY,CAAE,MAAO,EAAM,CAAC,EACvC,IAAO,GAAK,EACd,GAGF,KAAK,0BAA4B,GACnC,CAEA,MAAM,QAAS,CACb,KAAK,MAAM,EACX,MAAM,KAAK,WAAW,CACxB,CAEA,OAAQ,CACF,KAAK,OAAO,kBACd,cAAc,KAAK,sBAAsB,EAEvC,KAAK,qCACP,cAAc,KAAK,mCAAmC,EAEpD,KAAK,iCACP,aAAa,KAAK,+BAA+B,EAEnD,KAAK,YAAc,OACnB,KAAK,kBAAoB,OACzB,KAAK,0BAA4B,EACnC,CAEA,MAAM,0BAA2B,CAC/B,OACE,KAAK,OAAO,mBACZ,OAAO,KAAK,OAAO,mBAAsB,WAElC,MAAM,KAAK,OAAO,kBAAkB,EAEtC,MAAME,EAAU,CACzB,CAEA,MAAM,SAASC,EAAuB,CACpC,GAAI,CAAC,KAAK,cAAc,EACtB,MAAM,IAAI,MAAM,uDAAuD,EAGzE,GAAI,KAAK,eACP,MAAM,IAAI,MAAM,gDAAgD,EAGlE,GAAI,KAAK,OAAO,YACd,MAAM,IAAI,MAAM,kDAAkD,EAGpE,IAAMC,EAOF,CACF,cAAAD,EACA,SAAU,KAAK,OAAO,SACtB,kBAAmB,KAAK,OAAO,kBAC/B,kBAAmB,KAAK,iBAC1B,EAEI,KAAK,QAAQ,IACfC,EAAS,WAAa,KAAK,YAAY,WACvCA,EAAS,aAAe,KAAK,YAAY,cAe3C,IAAIC,EAEJ,GAAI,CACFA,EAAW,MAAMC,EAKd,GAAG,KAAK,OAAO,MAAO,YAAaF,EAAU,CAAE,YAAa,GAAM,CAAC,CACxE,OAASG,EAAO,CACd,WAAK,IACH,8BAAiCA,EAAgB,QACjD,MACF,EACM,IAAI,MAAOA,EAAgB,OAAO,CAC1C,CAEA,GAAIF,EAAS,QAAU,IAAK,CAC1B,GACE,CAACA,EAAS,KAAK,eAAe,YAAY,GAC1C,CAACA,EAAS,KAAK,eAAe,MAAM,EAEpC,WAAK,IAAI,6BAA8B,MAAa,EAC9C,IAAI,MAAM,4BAA4B,EAE9C,IAAMG,EAAe,KAAK,uBAAuB,CAC/C,WAAYH,EAAS,KAAK,WAC1B,KAAMA,EAAS,KAAK,IACtB,CAAsB,EACtB,MAAM,KAAK,OAAO,YAAYG,CAAY,EAC1C,MAAM,KAAK,SAAS,EACpB,KAAK,IAAI,iCAAkC,MAAa,GACpDH,EAAS,KAAK,2BAA6B,EAAI,IACjD,KAAK,IACH,qBAAqBA,EAAS,KAAK,yBAAyB,8DAC5D,MACF,CAEJ,KAAO,CACL,IAAMI,EAAW,8BACfJ,EAAS,KAAK,SAAW,gBAC3B,GACMK,EAAI,IAAI,MAAMD,CAAQ,EAE5B,MAAIJ,EAAS,KAAK,UAChBK,EAAE,QAAUL,EAAS,KAAK,SAG5B,KAAK,IAAII,EAAU,MAAa,EAC1BC,CACR,CACF,CAEA,MAAM,OAAQ,CACZ,OAAO,KAAK,OAAO,CAAE,MAAO,SAAU,CAAC,CACzC,CAEA,MAAM,OAAO,CACX,2BAAAC,EAA6B,GAC7B,MAAAC,EAAQ,SACV,EAGI,CAAC,EAAG,CACN,GAAI,CAAC,KAAK,QAAQ,EAChB,MAAM,IAAI,MAAM,wDAAwD,EAG1E,GAAI,KAAK,YAAY,YACnB,OAGF,GAAI,KAAK,aAAa,EACpB,MAAM,IAAI,MAAM,oDAAoD,EAGtE,GAAI,KAAK,OAAO,YACd,MAAM,IAAI,MAAM,+CAA+C,EAGjE,IAAMC,EAAe,KAAK,OAAO,oBAC7B,MAAM,KAAK,OAAO,oBAAoB,EACtC,CAAC,EAcDR,EAEJ,GAAI,CACFA,EAAW,MAAMC,EACf,GAAG,KAAK,OAAO,MAAO,SACtB,CACE,WAAY,KAAK,YAAY,WAC7B,SAAU,KAAK,OAAO,SACtB,kBAAmB,KAAK,kBACxB,kBAAmB,KAAK,OAAO,kBAC/B,aAAc,KAAK,YAAY,aAC/B,2BAAAK,EACA,MAAAC,EACA,aAAAC,CACF,EACA,CAAE,YAAa,GAAM,CACvB,CACF,OAASN,EAAO,CACd,WAAK,IACH,2BAA8BA,EAAgB,QAC9C,MACF,EACM,IAAI,MAAOA,EAAgB,OAAO,CAC1C,CAEA,IAAMO,EAAeT,EAAS,KAE9B,GAAIA,EAAS,QAAU,IAAK,CAC1B,GACE,CAACS,EAAa,eAAe,YAAY,GACzC,CAACA,EAAa,eAAe,MAAM,EAEnC,WAAK,IACH,qDACA,MACF,EACM,IAAI,MAAM,4BAA4B,EAE9C,IAAMN,EAAe,KAAK,uBAAuB,CAC/C,WAAYM,EAAa,WACzB,KAAMA,EAAa,IACrB,CAAsB,EACtB,MAAM,KAAK,OAAO,YAAYN,CAAY,EAC1C,KAAK,IAAI,+BAAgC,OAAc,GACnDM,EAAa,2BAA6B,EAAI,IAChD,KAAK,IACH,qBAAqBA,EAAa,yBAAyB,8DAC3D,MACF,EAEF,MAAM,KAAK,SAAS,CACtB,KAAO,CACL,IAAML,EAAW,2BACfK,EAAa,SAAW,gBAC1B,GAEA,KAAK,IAAIL,EAAU,MAAa,EAEhC,IAAMC,EAAI,IAAI,MAAMD,CAAQ,EAE5B,MAAIK,EAAa,UACfJ,EAAE,QAAUI,EAAa,QAGvB,CAAC,YAAa,qBAAqB,EAAE,SAASA,EAAa,OAAO,IAElE,KAAK,IACH,6DACA,MACF,EACA,MAAM,KAAK,OAAO,YAAY,EAAE,EAChC,MAAM,KAAK,SAAS,IAIlBJ,CACR,CACF,CAEQ,SAAoD,CAC1D,MAAO,CAAC,CAAC,KAAK,WAChB,CAEA,cAAwB,CACtB,GAAI,CAAC,KAAK,QAAQ,EAChB,MAAM,IAAI,MAAM,yBAAyB,EAG3C,IAAMK,EAAM,IAAI,KAEhB,OAAO,KAAK,YAAY,aAAeA,CACzC,CAEA,eAAsB,CACpB,GAAI,CAAC,KAAK,QAAQ,EAChB,MAAM,IAAI,MAAM,yBAAyB,EAG3C,OAAO,KAAK,YAAY,SAC1B,CAEA,oBAA2B,CACzB,GAAI,CAAC,KAAK,QAAQ,EAChB,MAAM,IAAI,MAAM,yBAAyB,EAG3C,OAAO,KAAK,YAAY,YAC1B,CAEA,QAAQC,EAAY,GAAe,CACjC,IAAMC,EAASjB,GAAgB,CACzBgB,GACF,KAAK,IAAIhB,EAAK,OAAc,CAEhC,EAEA,GAAI,CAAC,KAAK,QAAQ,EAChB,OAAAiB,EAAM,yCAAyC,EACxC,GAGT,IAAMC,EAAO,KAAK,YACZH,EAAM,IAAI,KAEhB,OAAIG,EAAK,UAAYH,GACnBE,EAAM,wCAAwC,EACvC,IAGLC,EAAK,aAAeH,GACtBE,EAAM,2CAA2C,EAC1C,IAILC,EAAK,UAAU,QAAQ,EAAI,IAASH,EAAI,QAAQ,GAClDE,EAAM,qDAAqD,EACpD,IAGLC,EAAK,YAAc,KAAK,oBAAsBA,EAAK,mBACrDD,EAAM,2DAA2D,EAC1D,IAGL,KAAK,OAAO,WAAaC,EAAK,UAChCD,EAAM,kDAAkD,EACjD,IAGF,EACT,CAEA,kBACEE,EACAC,EAA4B,GACnB,CACT,MAAO,OAAK,gBAAgBD,EAASC,CAAgB,CACvD,CAEA,kBACED,EACAC,EAA4B,GACnB,CACT,OAAO,KAAK,gBAAgBD,EAASC,CAAgB,IAAM,MAG7D,CAEA,aAAaC,EAA0BC,EAAqC,CAC1E,IAAMC,EAAQ,KAAK,gBAAgBF,CAAgB,EAEnD,GAAIE,IAAU,OACZ,MAAO,GAGT,GAAI,OAAOA,GAAU,SACnB,MAAM,IAAI,MACR,GAAGF,CAAgB,+CACrB,EAIF,OAAIE,IAAU,GACL,GAGF,KAAK,KAAKD,CAAkB,EAAI,KAAK,KAAKC,CAAK,CACxD,CAEA,gBACEJ,EACAC,EAA4B,GACW,CAKvC,GAJI,CAAC,KAAK,QAAQ,GAIdA,GAAoB,CAAC,KAAK,QAAQ,EACpC,OAGF,IAAMI,EAAkB,KAAK,YAAY,EAEzC,GAAKA,EAAgB,eAAeL,CAAO,EAI3C,OAAOK,EAAgBL,CAAO,CAChC,CAEQ,uBAAwB,CAC9B,GAAI,CAAC,KAAK,QAAQ,EAChB,OAGF,IAAMJ,EAAM,IAAI,MAGd,KAAK,YAAY,UAAYA,GAC7B,KAAK,YAAY,aAAeA,KAEhC,KAAK,gBAAkB,CAAC,GAG1B,KAAK,gBAAkB,KAAK,YAAY,aACrC,OACEU,GACCA,EAAY,WAAaV,GAAOU,EAAY,QAAUV,CAC1D,EACC,KACC,CAACW,EAAcC,IACbD,EAAa,UAAU,QAAQ,EAAIC,EAAa,UAAU,QAAQ,CACtE,EACC,OAAO,CAACH,EAAiBC,KACjB,CACL,GAAGD,EACH,GAAGC,EAAY,SACf,GAAGA,EAAY,gBACjB,GACC,CAAC,CAAc,CACtB,CAEA,aAAc,CACZ,OAAK,KAAK,QAAQ,EAIX,KAAK,iBAAmB,CAAC,EAHvB,CAAC,CAIZ,CAEA,wBAAyB,CACvB,GAAI,CAAC,KAAK,QAAQ,EAChB,MAAO,CAAC,EAGV,IAAMV,EAAM,IAAI,KAEhB,OAAO,KAAK,YAAY,aAAa,OAClCU,GAAgBA,EAAY,WAAaV,GAAOU,EAAY,QAAUV,CACzE,CACF,CAEA,kBAAmB,CACjB,OAAK,KAAK,YAIH,KAAK,YAAY,cAHf,EAIX,CAEA,eAAgB,CACd,OAAO,KAAK,aAAa,UAC3B,CAEA,cAAwB,CACtB,GAAI,CAAC,KAAK,aAAe,KAAK,YAAY,YACxC,MAAO,GAGT,IAAMA,EAAM,IAAI,KAAK,EAAE,QAAQ,EACzBa,EAAa,IAAO,GAAK,GACzBC,EAAa,IAAO,GAAK,GACzBC,EAAS,KAAK,YAAY,UAAU,QAAQ,EAC5CC,EAAW,KAAK,YAAY,SAAS,QAAQ,EAC7CC,EAAc,KAAK,YAAY,aAAa,QAAQ,EAGpDC,EACJlB,EAAMe,EAAS,KAAK,OAAO,gBAAmB,KAAQf,EAAMiB,EAIxDE,EACJ,KAAK,uBAAuB,EAAE,KAC3BT,GACCV,GAAOU,EAAY,QAAQ,QAAQ,EAAIG,GACvCb,GAAOU,EAAY,QAAQ,QAAQ,CACvC,IAAM,QAAaM,EAAWhB,EAAMc,EAEtC,OAAOI,GAAsBC,CAC/B,CAEA,UAAW,CACT,MACE;AAAA,YACa,KAAK,OAAO,UAAY,OAAO;AAAA,qBACtB,KAAK,OAAO,mBAAqB,OAAO;AAAA,qBACxC,KAAK,mBAAqB,OAAO;AAAA;AAAA;AAAA,WAG3C,KAAK,aAAa,SAAW,OAAO;AAAA,YACnC,KAAK,aAAa,UAAY,OAAO,IAChD,KAAK,aAAa,WAAa,KAAK,OAAO,SAAW,MAAQ,EAChE;AAAA,cACe,KAAK,aAAa,YAAc,OAAO;AAAA,qBAChC,KAAK,aAAa,mBAAqB,OAAO,IAClE,KAAK,aAAa,oBAAsB,KAAK,kBACzC,MACA,EACN;AAAA,aACc,KAAK,aAAa,WAAa,OAAO;AAAA,YACvC,KAAK,aAAa,UAAY,OAAO;AAAA,aACpC,KAAK,aAAa,WAAa,OAAO;AAAA,gBACnC,KAAK,aAAa,cAAgB,OAAO;AAAA,eAC1C,KAAK,aAAa,aAAe,OAAO;AAAA,WAC5C,KAAK,QAAQ,EAAK,CAAC;AAAA,gBACd,KAAK,aAAa,CAAC;AAAA,gBACnB,KAAK,aAAa,aAAa,QAAU,CAAC;AAAA,EAC3D,KAAK,aAAa,aACf,IAAI,CAACT,EAAaU,IAEf;AAAA,iBACkBA,EAAQ,CAAC;AAAA,MACpBV,EAAY,EAAE;AAAA,aACPA,EAAY,SAAS;AAAA,aACrBA,EAAY,SAAS;AAAA,WACvBA,EAAY,OAAO;AAAA,YAClB,KAAK,UAAUA,EAAY,QAAQ,CAAC;AAAA,oBAC5B,KAAK,UACxBA,EAAY,gBACd,CAAC;AAAA,CAEJ,EACA,KAAK,EAAE,CAEd,CAEQ,gCAAiC,CACnC,KAAK,OAAO,iBACd,KAAK,OAAO,gBAAgB,KAAK,iBAAmB,CAAC,CAAC,CAE1D,CAEQ,kCAAmC,CACzC,GAAI,CAAC,KAAK,QAAQ,EAChB,OAGF,IAAMV,EAAM,IAAI,KAAK,EAAE,QAAQ,EACzBqB,EAAU,IAAI,IAEpBA,EAAQ,IAAI,KAAK,YAAY,UAAU,QAAQ,EAAIrB,CAAG,EACtDqB,EAAQ,IAAI,KAAK,YAAY,aAAa,QAAQ,EAAIrB,CAAG,EAEzD,IAAMsB,EAAuB,CAC3B,GAAG,KAAK,YAAY,aAAa,OAAO,CAACD,EAASX,KAChDW,EAAQ,IAAIX,EAAY,UAAU,QAAQ,EAAIV,CAAG,EACjDqB,EAAQ,IAAIX,EAAY,QAAQ,QAAQ,EAAIV,CAAG,EACxCqB,GACNA,CAAO,CACZ,EACG,OAAQE,GAAWA,GAAU,GAAKA,GAAU,GAAK,GAAK,GAAI,EAC1D,KAAK,CAACC,EAAGC,IAAMD,EAAIC,CAAC,EAIvB,GAAIH,EAAqB,SAAW,EAClC,OAGF,IAAMI,EAAwBJ,EAAqB,CAAC,EAEpD,aAAa,KAAK,+BAA+B,EACjD,KAAK,gCAAkC,WAAW,IAAM,CACtD,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,iCAAiC,CACxC,EAAGI,EAAwB,GAAI,CACjC,CAEA,MAAc,YAAY,CAAE,MAAAC,CAAM,EAAuB,CACvD,GAAIA,GAAS,KAAK,aAAa,EAAG,CAChC,KAAK,IAAI,6BAA8B,OAAc,EACrD,GAAI,CACF,MAAM,KAAK,OAAO,CAAE,MAAOA,EAAQ,UAAY,MAAO,CAAC,CACzD,MAAY,CAAC,CACf,CACF,CAEA,MAAc,UAAW,CACvB,GAAI,MAAK,eAIT,GAAI,CACF,IAAMlC,EAAe,MAAM,KAAK,OAAO,YAAY,EACnD,GAAI,CAACA,EAAc,CACjB,KAAK,YAAc,OACnB,MACF,CACA,GAAIA,EAAa,OAAS,GACxB,MAAM,IAAI,MAAM,uCAAuC,EAEzD,GAAM,CAAE,KAAAmC,EAAM,WAAAC,CAAW,EACvB,KAAK,6BAA6BpC,CAAY,EAGhD,GAFA,KAAK,SAAW,IAAIT,EAAgB4C,CAAI,EAEpC,CADsB,KAAK,SAAS,YAAY,KAAK,cAAc,CAAC,EAEtE,MAAM,IAAI,MAAM,2CAA2C,EAE7D,IAAME,EAAY,KAAK,SAAS,UAAU,OAAO,CAC/C,OAAQ,MACR,KAAM,OACR,CAAC,EACD,KAAK,IAAM,IAAIC,EAAQD,CAAS,EAChC,KAAK,YAAc,KAAK,mBAAmBD,CAAU,EACrD,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,iCAAiC,CACxC,OAAS,EAAG,CACV,KAAK,IACH,kCAAkC,aAAa,MAAQ,EAAE,QAAU,EAAE,GACrE,OACF,CACF,CACF,CAEQ,uBAAuBG,EAAsC,CACnE,IAAMvC,EAAe,KAAK,UAAUuC,CAAS,EAC7C,OAAO,OAAO,KAAKvC,CAAY,EAAE,SAAS,QAAQ,CACpD,CAEQ,6BACNwC,EACmB,CACnB,IAAMxC,EAAe,OAAO,KAAKwC,EAAsB,QAAQ,EAAE,SAC/D,OACF,EACMD,EAAY,KAAK,MAAMvC,CAAY,EACzC,GACE,CAACuC,EAAU,eAAe,YAAY,GACtC,CAACA,EAAU,eAAe,MAAM,EAEhC,MAAM,IAAI,MAAM,4CAA4C,EAG9D,OAAOA,CACT,CAEQ,mBAAmBE,EAAkC,CAC3D,IAAMC,EAAc,KAAK,mBAAmBD,CAAO,EAE7C/B,EAAO,CAAE,GAAGgC,CAAY,EAG9B,OAAAhC,EAAK,UAAY,IAAI,KAAKgC,EAAY,SAAS,EAC/ChC,EAAK,SAAW,IAAI,KAAKgC,EAAY,QAAQ,EAC7ChC,EAAK,UAAY,IAAI,KAAKgC,EAAY,SAAS,EAC/ChC,EAAK,aAAe,IAAI,KAAKgC,EAAY,YAAY,EAErDhC,EAAK,aAAeA,EAAK,aAAa,IAAKO,IACzCA,EAAY,UAAY,IAAI,KAAKA,EAAY,SAAS,EACtDA,EAAY,QAAU,IAAI,KAAKA,EAAY,OAAO,EAC3CA,EACR,EAEMP,CACT,CAEQ,mBAAmB0B,EAAoB,CAE7CA,EAAaA,EAAW,QAAQ,iBAAkB,EAAE,EAGpD,IAAMO,EAAQP,EAAW,MACvB,gIACF,EAEA,GAAI,CAACO,EACH,MAAM,IAAI,MAAM,iCAAiC,EAGnD,IAAMC,EAAwBD,EAAM,OAAQ,sBACtCE,EAAUF,EAAM,OAAQ,cACxBG,EAAYH,EAAM,OAAQ,UAE5BI,EAAcC,EAGlB,GAAI,CACFD,EAAe,KAAK,IAAK,cAAcH,EAAuB,MAAM,CACtE,MAAY,CACV,MAAM,IAAI,MAAM,+CAA+C,CACjE,CAGA,GAAI,CACFI,EAAgBC,EAAS,IAAI,QAAQJ,EAASE,CAAY,EAAE,SAC1DE,EAAS,IAAI,IACf,CACF,MAAY,CACV,MAAM,IAAI,MAAM,qDAAqD,CACvE,CAGA,GACE,KAAK,IAAK,OAAO,OAAO,KAAKD,CAAa,EAAGF,EAAW,OAAQ,QAAQ,EAGxE,OAAO,KAAK,MAAME,CAAa,EAE/B,MAAM,IAAI,MAAM,+BAA+B,CAEnD,CAEO,eAAgB,CACrB,OAAO,KAAK,cACd,CAEA,MAAa,UAAW,CAatB,GAZA,KAAK,eAAiB,GAElB,KAAK,OAAO,kBACd,cAAc,KAAK,sBAAsB,EAEvC,KAAK,qCACP,cAAc,KAAK,mCAAmC,EAEpD,KAAK,iCACP,aAAa,KAAK,+BAA+B,EAG/C,CAAC,KAAK,QAAQ,EAChB,OAG+B,KAAK,YAAY,aAAa,KAC5D/B,GAAgBA,EAAY,aAAe,EAC9C,GAGE,MAAM,KAAK,OAAO,CAAE,2BAA4B,GAAM,MAAO,UAAW,CAAC,CAE7E,CACF","names":["CryptoJS","machineId","NodeRSA","X509Certificate","fetch","getGlobalDispatcher","setGlobalDispatcher","Dispatcher","ProxyAgent","URL","getProxyAgent","variableName","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","defaultDispatcher","options","handler","host","protocol","proxyAgent","postRequest","url","data","controller","timeout","response","responseJson","err","LicenseManager","config","X509Certificate","msg","logLevel","machineId","reservationId","postData","response","postRequest","error","containerStr","errorMsg","e","detachFloatingEntitlements","cause","usageMetrics","responseData","now","useLogger","debug","cert","feature","requireValidCert","quotaFeatureName","currentConsumption","quota","currentFeatures","entitlement","entitlement1","entitlement2","mins15inMs","mins20inMs","expiry","issuedAt","termination","consumerRenewalDue","entitlementRenewalDue","index","offsets","upcomingEventOffsets","offset","a","b","timeTillNextEventInMs","force","x509","licenseKey","publicKey","NodeRSA","container","stringifiedContainer","certStr","certPayload","match","encryptedSymmetricKey","payload","signature","symmetricKey","decryptedData","CryptoJS"]}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import { X509Certificate } from 'node:crypto';
|
|
4
|
+
|
|
5
|
+
export declare function computeDeviceFingerprint(): Promise<string>;
|
|
6
|
+
|
|
7
|
+
export declare const default_alias: {
|
|
8
|
+
postRequest: typeof postRequest;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export declare function generateCertContainerStr(options?: {}): Promise<string>;
|
|
12
|
+
|
|
13
|
+
export declare function generateTamperedCert(options?: Object): Promise<string>;
|
|
14
|
+
|
|
15
|
+
export declare class LicenseManager {
|
|
16
|
+
config: TLicenseManagerConfig;
|
|
17
|
+
private isInitializationCompleted;
|
|
18
|
+
private key?;
|
|
19
|
+
private logger;
|
|
20
|
+
protected licenseCert?: TLicenseCertObj;
|
|
21
|
+
private x509Cert?;
|
|
22
|
+
private x509IssuerCert;
|
|
23
|
+
private deviceFingerprint?;
|
|
24
|
+
private renewalIntervalPointer?;
|
|
25
|
+
private checkUpcomingEntitlementChangesCron?;
|
|
26
|
+
private entitlementChangeTimeoutPointer?;
|
|
27
|
+
private currentFeatures?;
|
|
28
|
+
private isShuttingDown;
|
|
29
|
+
constructor(config: TLicenseManagerConfig);
|
|
30
|
+
log(msg: string, logLevel: LogLevel): void;
|
|
31
|
+
private isInitialized;
|
|
32
|
+
initialize(): Promise<void>;
|
|
33
|
+
reload(): Promise<void>;
|
|
34
|
+
reset(): void;
|
|
35
|
+
computeDeviceFingerprint(): Promise<string>;
|
|
36
|
+
activate(reservationId: string): Promise<void>;
|
|
37
|
+
renew(): Promise<void>;
|
|
38
|
+
_renew({ detachFloatingEntitlements, cause, }?: {
|
|
39
|
+
detachFloatingEntitlements?: Boolean;
|
|
40
|
+
cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown';
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
private hasCert;
|
|
43
|
+
isTerminated(): boolean;
|
|
44
|
+
getExpiryDate(): Date;
|
|
45
|
+
getTerminationDate(): Date;
|
|
46
|
+
isValid(useLogger?: boolean): boolean;
|
|
47
|
+
hasFeatureEnabled(feature: string, requireValidCert?: boolean): boolean;
|
|
48
|
+
hasFeatureDefined(feature: string, requireValidCert?: boolean): boolean;
|
|
49
|
+
hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean;
|
|
50
|
+
getFeatureValue(feature: string, requireValidCert?: boolean): undefined | boolean | number | string;
|
|
51
|
+
private updateCurrentFeatures;
|
|
52
|
+
getFeatures(): TFeatures;
|
|
53
|
+
getCurrentEntitlements(): TEntitlement[];
|
|
54
|
+
getManagementJwt(): string;
|
|
55
|
+
getConsumerId(): string | undefined;
|
|
56
|
+
isRenewalDue(): boolean;
|
|
57
|
+
toString(): string;
|
|
58
|
+
private triggerOnFeatureChangeCallback;
|
|
59
|
+
private setTimerForNextEntitlementChange;
|
|
60
|
+
private renewalCron;
|
|
61
|
+
private initCert;
|
|
62
|
+
private stringifyCertContainer;
|
|
63
|
+
private parseLicenseCertContainerStr;
|
|
64
|
+
private parseLicenseKeyStr;
|
|
65
|
+
private validateLicenseKey;
|
|
66
|
+
getIssuerCert(): X509Certificate;
|
|
67
|
+
shutdown(): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare function licenseManagerFactory(config?: {}): LicenseManager;
|
|
71
|
+
|
|
72
|
+
declare const enum LogLevel {
|
|
73
|
+
ERROR = "error",
|
|
74
|
+
WARN = "warn",
|
|
75
|
+
INFO = "info",
|
|
76
|
+
DEBUG = "debug"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export declare function makeEntitlement({ validFrom, validTo, features, featureOverrides, productId, isFloatable, }: {
|
|
80
|
+
validFrom?: Date;
|
|
81
|
+
validTo?: Date;
|
|
82
|
+
features?: TFeatures;
|
|
83
|
+
featureOverrides?: TFeatures;
|
|
84
|
+
productId?: string;
|
|
85
|
+
isFloatable?: boolean;
|
|
86
|
+
}): {
|
|
87
|
+
id: string;
|
|
88
|
+
productId: string;
|
|
89
|
+
productMetadata: {
|
|
90
|
+
metadataKey1: string;
|
|
91
|
+
};
|
|
92
|
+
features: TFeatures;
|
|
93
|
+
featureOverrides: TFeatures;
|
|
94
|
+
validFrom: Date;
|
|
95
|
+
validTo: Date;
|
|
96
|
+
isFloatable: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export declare function makeRelativeDate(offsetInMinutes: number): Date;
|
|
100
|
+
|
|
101
|
+
export declare function postRequest<T>(url: string, data: {}, options?: {
|
|
102
|
+
timeoutInMs?: number;
|
|
103
|
+
}): Promise<{
|
|
104
|
+
status: number;
|
|
105
|
+
data: T;
|
|
106
|
+
}>;
|
|
107
|
+
|
|
108
|
+
export declare type TEntitlement = {
|
|
109
|
+
id: string;
|
|
110
|
+
productId: string;
|
|
111
|
+
productMetadata: TMetadata;
|
|
112
|
+
features: TFeatures;
|
|
113
|
+
featureOverrides: TFeatures;
|
|
114
|
+
validFrom: Date;
|
|
115
|
+
validTo: Date;
|
|
116
|
+
isFloatable: boolean;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export declare type TFeatures = {
|
|
120
|
+
[key: string]: boolean | number | string;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export declare type TLicenseBlock = string;
|
|
124
|
+
|
|
125
|
+
export declare type TLicenseCertObj = {
|
|
126
|
+
consumerId: string;
|
|
127
|
+
version: number;
|
|
128
|
+
tenantId: number;
|
|
129
|
+
renewalToken: string;
|
|
130
|
+
deviceLock: boolean;
|
|
131
|
+
deviceFingerprint: string;
|
|
132
|
+
createdAt: Date;
|
|
133
|
+
issuedAt: Date;
|
|
134
|
+
expiresAt: Date;
|
|
135
|
+
terminatesAt: Date;
|
|
136
|
+
entitlements: TEntitlement[];
|
|
137
|
+
managementJwt: string;
|
|
138
|
+
isEphemeral: boolean;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export declare type TLicenseContainer = {
|
|
142
|
+
licenseKey: string;
|
|
143
|
+
x509: string;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export declare type TLicenseManagerConfig = {
|
|
147
|
+
server?: string;
|
|
148
|
+
tenantId: number;
|
|
149
|
+
productIdentifier: string;
|
|
150
|
+
autoRenewEnabled?: boolean;
|
|
151
|
+
offlineMode?: boolean;
|
|
152
|
+
renewOnInit?: boolean;
|
|
153
|
+
autoRenewOffset?: number;
|
|
154
|
+
loadCertStr: () => Promise<TLicenseBlock>;
|
|
155
|
+
saveCertStr: (cert: TLicenseBlock) => Promise<void>;
|
|
156
|
+
collectUsageMetrics?: () => Promise<Array<TUsageMetric>>;
|
|
157
|
+
deviceFingerprint?: () => string | Promise<string>;
|
|
158
|
+
onFeatureChange?: (features: TFeatures) => any;
|
|
159
|
+
logger?: TLogger;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export declare type TLogger = {
|
|
163
|
+
error: Function;
|
|
164
|
+
warn: Function;
|
|
165
|
+
info: Function;
|
|
166
|
+
debug: Function;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export declare type TMetadata = {
|
|
170
|
+
[key: string]: boolean | number | string | Array<any> | {};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export declare type TUsageMetric = {
|
|
174
|
+
name: string;
|
|
175
|
+
value: number;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export { }
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import { X509Certificate } from 'node:crypto';
|
|
4
|
+
|
|
5
|
+
export declare function computeDeviceFingerprint(): Promise<string>;
|
|
6
|
+
|
|
7
|
+
export declare const default_alias: {
|
|
8
|
+
postRequest: typeof postRequest;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export declare function generateCertContainerStr(options?: {}): Promise<string>;
|
|
12
|
+
|
|
13
|
+
export declare function generateTamperedCert(options?: Object): Promise<string>;
|
|
14
|
+
|
|
15
|
+
export declare class LicenseManager {
|
|
16
|
+
config: TLicenseManagerConfig;
|
|
17
|
+
private isInitializationCompleted;
|
|
18
|
+
private key?;
|
|
19
|
+
private logger;
|
|
20
|
+
protected licenseCert?: TLicenseCertObj;
|
|
21
|
+
private x509Cert?;
|
|
22
|
+
private x509IssuerCert;
|
|
23
|
+
private deviceFingerprint?;
|
|
24
|
+
private renewalIntervalPointer?;
|
|
25
|
+
private checkUpcomingEntitlementChangesCron?;
|
|
26
|
+
private entitlementChangeTimeoutPointer?;
|
|
27
|
+
private currentFeatures?;
|
|
28
|
+
private isShuttingDown;
|
|
29
|
+
constructor(config: TLicenseManagerConfig);
|
|
30
|
+
log(msg: string, logLevel: LogLevel): void;
|
|
31
|
+
private isInitialized;
|
|
32
|
+
initialize(): Promise<void>;
|
|
33
|
+
reload(): Promise<void>;
|
|
34
|
+
reset(): void;
|
|
35
|
+
computeDeviceFingerprint(): Promise<string>;
|
|
36
|
+
activate(reservationId: string): Promise<void>;
|
|
37
|
+
renew(): Promise<void>;
|
|
38
|
+
_renew({ detachFloatingEntitlements, cause, }?: {
|
|
39
|
+
detachFloatingEntitlements?: Boolean;
|
|
40
|
+
cause?: 'startup' | 'shutdown' | 'request' | 'auto' | 'unknown';
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
private hasCert;
|
|
43
|
+
isTerminated(): boolean;
|
|
44
|
+
getExpiryDate(): Date;
|
|
45
|
+
getTerminationDate(): Date;
|
|
46
|
+
isValid(useLogger?: boolean): boolean;
|
|
47
|
+
hasFeatureEnabled(feature: string, requireValidCert?: boolean): boolean;
|
|
48
|
+
hasFeatureDefined(feature: string, requireValidCert?: boolean): boolean;
|
|
49
|
+
hasQuotaLeft(quotaFeatureName: string, currentConsumption: number): boolean;
|
|
50
|
+
getFeatureValue(feature: string, requireValidCert?: boolean): undefined | boolean | number | string;
|
|
51
|
+
private updateCurrentFeatures;
|
|
52
|
+
getFeatures(): TFeatures;
|
|
53
|
+
getCurrentEntitlements(): TEntitlement[];
|
|
54
|
+
getManagementJwt(): string;
|
|
55
|
+
getConsumerId(): string | undefined;
|
|
56
|
+
isRenewalDue(): boolean;
|
|
57
|
+
toString(): string;
|
|
58
|
+
private triggerOnFeatureChangeCallback;
|
|
59
|
+
private setTimerForNextEntitlementChange;
|
|
60
|
+
private renewalCron;
|
|
61
|
+
private initCert;
|
|
62
|
+
private stringifyCertContainer;
|
|
63
|
+
private parseLicenseCertContainerStr;
|
|
64
|
+
private parseLicenseKeyStr;
|
|
65
|
+
private validateLicenseKey;
|
|
66
|
+
getIssuerCert(): X509Certificate;
|
|
67
|
+
shutdown(): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare function licenseManagerFactory(config?: {}): LicenseManager;
|
|
71
|
+
|
|
72
|
+
declare const enum LogLevel {
|
|
73
|
+
ERROR = "error",
|
|
74
|
+
WARN = "warn",
|
|
75
|
+
INFO = "info",
|
|
76
|
+
DEBUG = "debug"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export declare function makeEntitlement({ validFrom, validTo, features, featureOverrides, productId, isFloatable, }: {
|
|
80
|
+
validFrom?: Date;
|
|
81
|
+
validTo?: Date;
|
|
82
|
+
features?: TFeatures;
|
|
83
|
+
featureOverrides?: TFeatures;
|
|
84
|
+
productId?: string;
|
|
85
|
+
isFloatable?: boolean;
|
|
86
|
+
}): {
|
|
87
|
+
id: string;
|
|
88
|
+
productId: string;
|
|
89
|
+
productMetadata: {
|
|
90
|
+
metadataKey1: string;
|
|
91
|
+
};
|
|
92
|
+
features: TFeatures;
|
|
93
|
+
featureOverrides: TFeatures;
|
|
94
|
+
validFrom: Date;
|
|
95
|
+
validTo: Date;
|
|
96
|
+
isFloatable: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export declare function makeRelativeDate(offsetInMinutes: number): Date;
|
|
100
|
+
|
|
101
|
+
export declare function postRequest<T>(url: string, data: {}, options?: {
|
|
102
|
+
timeoutInMs?: number;
|
|
103
|
+
}): Promise<{
|
|
104
|
+
status: number;
|
|
105
|
+
data: T;
|
|
106
|
+
}>;
|
|
107
|
+
|
|
108
|
+
export declare type TEntitlement = {
|
|
109
|
+
id: string;
|
|
110
|
+
productId: string;
|
|
111
|
+
productMetadata: TMetadata;
|
|
112
|
+
features: TFeatures;
|
|
113
|
+
featureOverrides: TFeatures;
|
|
114
|
+
validFrom: Date;
|
|
115
|
+
validTo: Date;
|
|
116
|
+
isFloatable: boolean;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export declare type TFeatures = {
|
|
120
|
+
[key: string]: boolean | number | string;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export declare type TLicenseBlock = string;
|
|
124
|
+
|
|
125
|
+
export declare type TLicenseCertObj = {
|
|
126
|
+
consumerId: string;
|
|
127
|
+
version: number;
|
|
128
|
+
tenantId: number;
|
|
129
|
+
renewalToken: string;
|
|
130
|
+
deviceLock: boolean;
|
|
131
|
+
deviceFingerprint: string;
|
|
132
|
+
createdAt: Date;
|
|
133
|
+
issuedAt: Date;
|
|
134
|
+
expiresAt: Date;
|
|
135
|
+
terminatesAt: Date;
|
|
136
|
+
entitlements: TEntitlement[];
|
|
137
|
+
managementJwt: string;
|
|
138
|
+
isEphemeral: boolean;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export declare type TLicenseContainer = {
|
|
142
|
+
licenseKey: string;
|
|
143
|
+
x509: string;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export declare type TLicenseManagerConfig = {
|
|
147
|
+
server?: string;
|
|
148
|
+
tenantId: number;
|
|
149
|
+
productIdentifier: string;
|
|
150
|
+
autoRenewEnabled?: boolean;
|
|
151
|
+
offlineMode?: boolean;
|
|
152
|
+
renewOnInit?: boolean;
|
|
153
|
+
autoRenewOffset?: number;
|
|
154
|
+
loadCertStr: () => Promise<TLicenseBlock>;
|
|
155
|
+
saveCertStr: (cert: TLicenseBlock) => Promise<void>;
|
|
156
|
+
collectUsageMetrics?: () => Promise<Array<TUsageMetric>>;
|
|
157
|
+
deviceFingerprint?: () => string | Promise<string>;
|
|
158
|
+
onFeatureChange?: (features: TFeatures) => any;
|
|
159
|
+
logger?: TLogger;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export declare type TLogger = {
|
|
163
|
+
error: Function;
|
|
164
|
+
warn: Function;
|
|
165
|
+
info: Function;
|
|
166
|
+
debug: Function;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export declare type TMetadata = {
|
|
170
|
+
[key: string]: boolean | number | string | Array<any> | {};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export declare type TUsageMetric = {
|
|
174
|
+
name: string;
|
|
175
|
+
value: number;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export { }
|
package/dist/httpRequest.d.ts
CHANGED
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}): Promise<{
|
|
4
|
-
status: number;
|
|
5
|
-
data: T;
|
|
6
|
-
}>;
|
|
7
|
-
declare const _default: {
|
|
8
|
-
postRequest: typeof postRequest;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export { _default as default, postRequest };
|
|
1
|
+
export { postRequest } from './_tsup-dts-rollup';
|
|
2
|
+
export { default_alias as default } from './_tsup-dts-rollup';
|
package/dist/httpRequest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/httpRequest.ts"],"sourcesContent":["import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAMO,kBAEPC,EAAoB,eAEpB,SAASC,EAAcC,EAAsB,CAC3C,IAAMC,EAAW,QAAQ,IAAID,
|
|
1
|
+
{"version":3,"sources":["../src/httpRequest.ts"],"sourcesContent":["import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAMO,kBAEPC,EAAoB,eAEpB,SAASC,EAAcC,EAAsB,CAC3C,IAAMC,EAAW,QAAQ,IAAID,CAAY,EACzC,OAAOC,EAAW,IAAI,aAAWA,CAAQ,EAAI,IAC/C,CAEA,IAAMC,EACJH,EAAc,2BAA2B,GAAKA,EAAc,YAAY,EACpEI,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,GAAgB,QAAQ,IAAI,UAAe,IAC9C,MAAM,GAAG,EACT,IAAKC,GAASA,EAAK,KAAK,CAAC,EAEtBC,KAAoB,uBAAoB,KAE9C,uBACE,IAAK,cAAc,YAAW,CAC5B,SAASC,EAAcC,EAAc,CACnC,GAAID,EAAQ,OAAQ,CAClB,GAAM,CAAE,KAAAE,EAAM,SAAAC,CAAS,EACrB,OAAOH,EAAQ,QAAW,SACtB,IAAI,MAAIA,EAAQ,MAAM,EACtBA,EAAQ,OACd,GACE,CAACH,EAAa,KAAMC,GAClBA,EAAK,WAAW,GAAG,EAAII,EAAK,SAASJ,CAAI,EAAII,IAASJ,CACxD,EACA,CACA,IAAMM,EAAaR,EAAYO,CAA8B,EACzDC,GACFA,EAAW,SAASJ,EAASC,CAAO,CAExC,CACF,CACA,OAAOF,EAAkB,SAASC,EAASC,CAAO,CACpD,CACF,CACF,EAEA,eAAsBd,EACpBkB,EACAC,EACAN,EAEI,CAAC,EACL,CACA,IAAMO,EAAa,IAAI,gBAEjBC,EAAU,WAAW,IAAM,CAC/BD,EAAW,MAAM,CACnB,EAAGP,EAAQ,aAAe,GAAK,EAE/B,GAAI,CACF,IAAMS,EAAW,QAAM,SAAMJ,EAAK,CAChC,OAAQ,OACR,KAAM,KAAK,UAAUC,CAAI,EACzB,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,OAAQC,EAAW,MACrB,CAAC,EAEKG,EAAe,MAAMD,EAAS,KAAK,EAEzC,MAAO,CACL,OAAQA,EAAS,OACjB,KAAMC,CACR,CACF,OAASC,EAAK,CACZ,MAAM,IAAI,MAAM,mBAAoB,CAAE,MAAOA,CAAI,CAAC,CACpD,QAAE,CACA,aAAaH,CAAO,CACtB,CACF,CAEA,IAAOtB,EAAQ,CACb,YAAAC,CACF","names":["httpRequest_exports","__export","httpRequest_default","postRequest","__toCommonJS","import_undici","import_node_url","getProxyAgent","variableName","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","defaultDispatcher","options","handler","host","protocol","proxyAgent","url","data","controller","timeout","response","responseJson","err"]}
|
package/dist/httpRequest.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/httpRequest.ts"],"sourcesContent":["import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"AAAA,OACE,SAAAA,EACA,uBAAAC,EACA,uBAAAC,EACA,cAAAC,EACA,cAAAC,MACK,SAEP,OAAS,OAAAC,MAAW,MAEpB,SAASC,EAAcC,EAAsB,CAC3C,IAAMC,EAAW,QAAQ,IAAID,
|
|
1
|
+
{"version":3,"sources":["../src/httpRequest.ts"],"sourcesContent":["import {\n fetch,\n getGlobalDispatcher,\n setGlobalDispatcher,\n Dispatcher,\n ProxyAgent,\n} from 'undici'\n\nimport { URL } from 'node:url'\n\nfunction getProxyAgent(variableName: string) {\n const proxyURI = process.env[variableName]\n return proxyURI ? new ProxyAgent(proxyURI) : null\n}\n\nconst httpProxy =\n getProxyAgent('http_proxy_license_server') || getProxyAgent('http_proxy')\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 = (process.env['no_proxy'] ?? '')\n .split(',')\n .map((rule) => rule.trim())\n\nconst defaultDispatcher = getGlobalDispatcher()\n\nsetGlobalDispatcher(\n new (class extends Dispatcher {\n dispatch(options: any, handler: any) {\n if (options.origin) {\n const { host, protocol } =\n typeof options.origin === 'string'\n ? new URL(options.origin)\n : options.origin\n if (\n !noProxyRules.some((rule) =>\n rule.startsWith('.') ? host.endsWith(rule) : host === rule\n )\n ) {\n const proxyAgent = proxyAgents[protocol as 'http:' | 'https:']\n if (proxyAgent) {\n proxyAgent.dispatch(options, handler)\n }\n }\n }\n return defaultDispatcher.dispatch(options, handler)\n }\n })()\n)\n\nexport async function postRequest<T>(\n url: string,\n data: {},\n options: {\n timeoutInMs?: number\n } = {}\n) {\n const controller = new AbortController()\n\n const timeout = setTimeout(() => {\n controller.abort()\n }, options.timeoutInMs ?? 30000)\n\n try {\n const response = await fetch(url, {\n method: 'post',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/json' },\n signal: controller.signal,\n })\n\n const responseJson = await response.json()\n\n return {\n status: response.status,\n data: responseJson as T,\n }\n } catch (err) {\n throw new Error('Connection Error', { cause: err })\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport default {\n postRequest,\n}\n"],"mappings":"AAAA,OACE,SAAAA,EACA,uBAAAC,EACA,uBAAAC,EACA,cAAAC,EACA,cAAAC,MACK,SAEP,OAAS,OAAAC,MAAW,MAEpB,SAASC,EAAcC,EAAsB,CAC3C,IAAMC,EAAW,QAAQ,IAAID,CAAY,EACzC,OAAOC,EAAW,IAAIJ,EAAWI,CAAQ,EAAI,IAC/C,CAEA,IAAMC,EACJH,EAAc,2BAA2B,GAAKA,EAAc,YAAY,EACpEI,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,GAAgB,QAAQ,IAAI,UAAe,IAC9C,MAAM,GAAG,EACT,IAAKC,GAASA,EAAK,KAAK,CAAC,EAEtBC,EAAoBb,EAAoB,EAE9CC,EACE,IAAK,cAAcC,CAAW,CAC5B,SAASY,EAAcC,EAAc,CACnC,GAAID,EAAQ,OAAQ,CAClB,GAAM,CAAE,KAAAE,EAAM,SAAAC,CAAS,EACrB,OAAOH,EAAQ,QAAW,SACtB,IAAIV,EAAIU,EAAQ,MAAM,EACtBA,EAAQ,OACd,GACE,CAACH,EAAa,KAAMC,GAClBA,EAAK,WAAW,GAAG,EAAII,EAAK,SAASJ,CAAI,EAAII,IAASJ,CACxD,EACA,CACA,IAAMM,EAAaR,EAAYO,CAA8B,EACzDC,GACFA,EAAW,SAASJ,EAASC,CAAO,CAExC,CACF,CACA,OAAOF,EAAkB,SAASC,EAASC,CAAO,CACpD,CACF,CACF,EAEA,eAAsBI,EACpBC,EACAC,EACAP,EAEI,CAAC,EACL,CACA,IAAMQ,EAAa,IAAI,gBAEjBC,EAAU,WAAW,IAAM,CAC/BD,EAAW,MAAM,CACnB,EAAGR,EAAQ,aAAe,GAAK,EAE/B,GAAI,CACF,IAAMU,EAAW,MAAMzB,EAAMqB,EAAK,CAChC,OAAQ,OACR,KAAM,KAAK,UAAUC,CAAI,EACzB,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,OAAQC,EAAW,MACrB,CAAC,EAEKG,EAAe,MAAMD,EAAS,KAAK,EAEzC,MAAO,CACL,OAAQA,EAAS,OACjB,KAAMC,CACR,CACF,OAASC,EAAK,CACZ,MAAM,IAAI,MAAM,mBAAoB,CAAE,MAAOA,CAAI,CAAC,CACpD,QAAE,CACA,aAAaH,CAAO,CACtB,CACF,CAEA,IAAOI,EAAQ,CACb,YAAAR,CACF","names":["fetch","getGlobalDispatcher","setGlobalDispatcher","Dispatcher","ProxyAgent","URL","getProxyAgent","variableName","proxyURI","httpProxy","httpsProxy","proxyAgents","noProxyRules","rule","defaultDispatcher","options","handler","host","protocol","proxyAgent","postRequest","url","data","controller","timeout","response","responseJson","err","httpRequest_default"]}
|