UNPKG

electron-lisenser

Version:
487 lines (467 loc) 18.5 kB
import $hgUW1$electron, {Menu as $hgUW1$Menu, app as $hgUW1$app} from "electron"; import $hgUW1$fs, {promises as $hgUW1$promises} from "fs"; import $hgUW1$path from "path"; import {getLicenseStatus as $hgUW1$getLicenseStatus, activateLicenseKey as $hgUW1$activateLicenseKey, startTrial as $hgUW1$startTrial, getTrialStatus as $hgUW1$getTrialStatus, generate3rdPartyToken as $hgUW1$generate3rdPartyToken, resetLicense as $hgUW1$resetLicense, requestOtpForLicenseReset as $hgUW1$requestOtpForLicenseReset} from "lisenser"; import {platform as $hgUW1$platform} from "process"; import {type as $hgUW1$type, platform as $hgUW1$platform1, arch as $hgUW1$arch, cpus as $hgUW1$cpus} from "os"; import {createHmac as $hgUW1$createHmac} from "crypto"; import {execSync as $hgUW1$execSync} from "child_process"; import $hgUW1$systeminformation from "systeminformation"; function $2a996eb956f475ba$export$1cf7ffb9847dddd6(window, appName) { const template = $hgUW1$platform === "darwin" ? $2a996eb956f475ba$var$buildDarwinTemplate(appName) : $2a996eb956f475ba$var$buildDefaultTemplate(window); return (0, $hgUW1$Menu).buildFromTemplate(template); } function $2a996eb956f475ba$var$buildDarwinTemplate(appName) { const subMenuAbout = { label: appName, submenu: [ { label: `About ${appName}`, selector: "orderFrontStandardAboutPanel:" }, { type: "separator" }, { label: "Services", submenu: [] }, { type: "separator" }, { label: `Hide ${appName}`, accelerator: "Command+H", selector: "hide:" }, { label: "Hide Others", accelerator: "Command+Shift+H", selector: "hideOtherApplications:" }, { label: "Show All", selector: "unhideAllApplications:" }, { type: "separator" }, { label: "Quit", accelerator: "Command+Q", click: ()=>{ (0, $hgUW1$app).quit(); } } ] }; const subMenuEdit = { label: "Edit", submenu: [ { label: "Undo", accelerator: "Command+Z", selector: "undo:" }, { label: "Redo", accelerator: "Shift+Command+Z", selector: "redo:" }, { type: "separator" }, { label: "Cut", accelerator: "Command+X", selector: "cut:" }, { label: "Copy", accelerator: "Command+C", selector: "copy:" }, { label: "Paste", accelerator: "Command+V", selector: "paste:" }, { label: "Select All", accelerator: "Command+A", selector: "selectAll:" } ] }; const subMenuWindow = { label: "Window", submenu: [ { label: "Minimize", accelerator: "Command+M", selector: "performMiniaturize:" }, { label: "Close", accelerator: "Command+W", selector: "performClose:" }, { type: "separator" }, { label: "Bring All to Front", selector: "arrangeInFront:" } ] }; return [ subMenuAbout, subMenuEdit, subMenuWindow ]; } function $2a996eb956f475ba$var$buildDefaultTemplate(window) { const templateDefault = [ { label: "&File", submenu: [ { label: "&Open", accelerator: "Ctrl+O" }, { label: "&Close", accelerator: "Ctrl+W", click: ()=>{ window.close(); } } ] } ]; return templateDefault; } class $ca02b5392fefcaaa$export$1b8b81297aac6025 { fallBackUsed = false; constructor(){ this.metas = {}; this.secret = "|machine-digest|"; this.initialized = false; this.initPromise = null; } async _init() { this.metas.OS_TYPE = $hgUW1$type(); this.metas.OS_PLATFORM = $hgUW1$platform1(); this.metas.OS_ARCH = $hgUW1$arch(); // this.metas.OS_RELEASE = os.release() this.metas.OS_CPU = $hgUW1$cpus().map((k)=>`${k.model}`).sort().join("."); let _id; try { if (this.metas.OS_PLATFORM == "darwin") { const idMatch = /IOPlatformUUID"\s=\s"([^\s]+)"/.exec((0, $hgUW1$execSync)("ioreg -rd1 -c IOPlatformExpertDevice").toString("utf8")); if (idMatch) _id = idMatch[1]; } else if (this.metas.OS_PLATFORM == "linux") _id = (0, $hgUW1$execSync)("cat /var/lib/dbus/machine-id").toString("utf8"); else if ([ "win32", "win64" ].includes(this.metas.OS_PLATFORM)) _id = (0, $hgUW1$execSync)("wmic CsProduct Get UUID").toString("utf8").replace("UUID", ""); } catch (e) {} _id = _id?.replace("\n", ""); const isWindows = [ "win32", "win64" ].includes(this.metas.OS_PLATFORM); const isValidUuid = Boolean(_id && _id.includes("-")); if (isWindows && !isValidUuid) { const result = await $ca02b5392fefcaaa$var$sysInfo().catch(()=>undefined); _id = result?.uuid && result.uuid !== "-" ? result.uuid.toUpperCase() : _id; this.fallBackUsed = Boolean(result?.uuid && result.uuid !== "-"); } this.metas.id = _id == null ? "machine unique id" : _id.replace("\n", ""); } async _ensureInit() { if (this.initialized) return; if (this.initPromise) { await this.initPromise; return; } this.initPromise = this._init(); await this.initPromise; this.initialized = true; this.initPromise = null; } async get() { await this._ensureInit(); const digest = this._make().digest("hex"); return { digest: digest, machine: this.metas, fallBackUsed: this.fallBackUsed }; } _make() { const ss = Object.keys(this.metas).sort().map((k)=>`${k}-|-${this.metas[k]}`).join("-"); const _raw = `M${ss}D`; return this._hash(_raw); } _hash(raw) { return $hgUW1$createHmac("sha256", this.secret).update(raw); } } async function $ca02b5392fefcaaa$var$sysInfo() { return await new Promise((resolve)=>{ const timeoutId = setTimeout(()=>resolve(undefined), 60000); (0, $hgUW1$systeminformation).system().then((res)=>{ clearTimeout(timeoutId); resolve(res); }, ()=>{ clearTimeout(timeoutId); resolve(undefined); }); }); } class $7b03903ff1b88a70$export$e90be4d393e62eeb { /** * Initializes a new instance of the `Lisenser` class. * * @param productId The product ID of the app. * @param appName The name of the app. * @param machineId A unique identifier for the machine running the app. * If not provided, a machine ID will be generated using the `machine-digest` package. */ constructor(productId, appName = "", machineId, telemetry){ this.productId = productId; this.appName = appName; this.machineId = machineId; this.machineDigest = new (0, $ca02b5392fefcaaa$export$1b8b81297aac6025)(); this.telemetry = telemetry; } async getMachineId() { if (this.machineId) return this.machineId; const digest = await this.machineDigest.get(); if (digest.fallBackUsed && this.telemetry) this.telemetry("fallback-digest-used"); this.machineId = digest.digest; return this.machineId; } /** * Determines whether the app has write access to the user data directory. * * @returns A `Promise` that resolves to `true` if the app has write access * to the user data directory, or `false` if it does not. */ async canUseFileStorage() { try { await (0, $hgUW1$promises).access(`${(0, $hgUW1$electron).app.getPath("userData")}/`, (0, $hgUW1$fs).constants.W_OK); return true; } catch (error) { return false; } } /** * Returns the license key stored on the local file system. If no license key is found, returns an empty string. * If the app does not have permission to access the file system in the user's App Data folder, throws a * "File Permission Error" CustomError. */ async getLocallyStoredLicenseKey() { if (!await this.canUseFileStorage()) throw new $7b03903ff1b88a70$var$CustomError("Unable to access the folder path of this App", "File Permission Error"); try { const licensePath = (0, $hgUW1$path).join((0, $hgUW1$electron).app.getPath("userData"), this.productId); return await (0, $hgUW1$promises).readFile(licensePath, "utf8"); } catch (error) { return ""; } } /** * Stores the provided license key on the local file system. * If the app does not have permission to access the file system in the user's App Data folder, throws a "File Permission Error" CustomError. */ async storeLicenseKeyLocally(licenseKey) { if (!await this.canUseFileStorage()) throw new $7b03903ff1b88a70$var$CustomError("Unable to access the folder path of this App", "File Permission Error"); const licensePath = (0, $hgUW1$path).join((0, $hgUW1$electron).app.getPath("userData"), this.productId); await (0, $hgUW1$promises).writeFile(licensePath, licenseKey); } /** * Returns the status of the license key. If no license key is stored locally, returns `no-key`. * * @returns {Promise<client.LicenseStatus>} The status of the license key */ async getLicenseStatus(polling) { const licenseKey = await this.getLocallyStoredLicenseKey(); if (!licenseKey) return { status: "no-key", daysToExpiry: 0, isActive: false }; const machineId = await this.getMachineId(); const req = { machineId: machineId, productId: this.productId, polling: polling }; return await $hgUW1$getLicenseStatus({ licenseKey: licenseKey, ...req }); } /** * Activates the given license key. * * @param {string} licenseKey The license key to activate * @returns {Promise<client.LicenseStatus>} The status of the license key */ async activateLicenseKey(licenseKey) { const machineId = await this.getMachineId(); const req = { machineId: machineId, productId: this.productId }; const status = await $hgUW1$activateLicenseKey({ licenseKey: licenseKey, ...req }); if (!status.isActive) return status; await this.storeLicenseKeyLocally(licenseKey); return status; } /** * Activates the trial for this product. * * @returns {Promise<client.TrialActivationStatus>} The status of the trial activation */ async startTrial() { const machineId = await this.getMachineId(); return $hgUW1$startTrial(this.productId, machineId); } /** * Returns the status of the trial for this product. * * @returns {Promise<client.TrialStatus>} The status of the trial */ async getTrialStatus() { const machineId = await this.getMachineId(); return $hgUW1$getTrialStatus(this.productId, machineId); } /** * Generates a third party token for the given license. * @param req The license request. * @returns {Promise<string>} The token generated */ async generate3rdPartyToken() { const licenseKey = await this.getLocallyStoredLicenseKey(); if (!licenseKey) throw new Error("Could not find user License key"); const machineId = await this.getMachineId(); const req = { machineId: machineId, productId: this.productId, licenseKey: licenseKey }; return $hgUW1$generate3rdPartyToken(req); } async createOtpWindow(iconPath, appName, licenseKey) { const window = new (0, $hgUW1$electron).BrowserWindow({ width: 500, height: 375, icon: iconPath, minWidth: 500, minHeight: 375, title: `${appName} - One Time Code`, webPreferences: { preload: (0, $hgUW1$path).join($7b03903ff1b88a70$var$callsites()[0].getFileName(), "../preloads/forotp.js") } }); window.loadFile((0, $hgUW1$path).join($7b03903ff1b88a70$var$callsites()[0].getFileName(), "../renderer/otp.html")); return new Promise(async (resolve)=>{ window.on("close", ()=>resolve()); (0, $hgUW1$electron).ipcMain.handle("license:reset", async (_event, otp)=>{ const hasReset = await $hgUW1$resetLicense(otp, this.productId, licenseKey).catch(()=>false); if (!hasReset) return "Passcode verification failed."; window.close(); }); (0, $hgUW1$electron).ipcMain.handle("license:otp:resend", async ()=>{ await $hgUW1$requestOtpForLicenseReset(this.productId, licenseKey); }); await $hgUW1$requestOtpForLicenseReset(this.productId, licenseKey); }); } /** * Creates a window that prompts the user to enter a license key. * * @param {string} iconPath The file path to the app's icon * @param {string} urlToBuy The URL where the user can purchase a license key * @param {string} [overrideAppName] An optional name to override the app's default name * @param {boolean} [setMenu=true] Whether to allow Lisenser replace the menu for the app or not. * @returns {Promise<boolean>} */ async createLicenseKeyWindow(iconPath, urlToBuy, overrideAppName, setMenu = true) { const appName = overrideAppName || this.appName; const window = new (0, $hgUW1$electron).BrowserWindow({ width: 600, height: 365, icon: iconPath, minWidth: 600, minHeight: 365, title: `${appName} - License Key`, webPreferences: { preload: (0, $hgUW1$path).join($7b03903ff1b88a70$var$callsites()[0].getFileName(), "../preloads/foractivate.js") } }); window.loadFile((0, $hgUW1$path).join($7b03903ff1b88a70$var$callsites()[0].getFileName(), "../renderer/activate.html")); // disable dev console and enable copy-pasting if (setMenu) (0, $hgUW1$electron).Menu.setApplicationMenu((0, $2a996eb956f475ba$export$1cf7ffb9847dddd6)(window, appName)); let isResolved = false; return new Promise((resolve, reject)=>{ window.on("close", ()=>{ if (!isResolved) resolve(false); }); (0, $hgUW1$electron).ipcMain.handle("license:activate", async (_, key)=>{ const status = await this.activateLicenseKey(key); if (!status.isActive && !status.isConflict) { const messages = { invalid: "The License Key provided is invalid.", expired: "The Licens Key provided has expired.", // a case for these keys won't happen active: "--", "no-key": "--" }; (0, $hgUW1$electron).dialog.showErrorBox(`${appName} - License ${status.status.toUpperCase()}`, messages[status.status]); return; } if (status.isConflict) { window.hide(); // if license is activated elsewere, we give user the // option to disconnect it from that machine using otp. await this.createOtpWindow(iconPath, appName, key); // show the license key window once the otp window is resolved. window.show(); return; } try { await this.storeLicenseKeyLocally(key); } catch (error) { if (error instanceof $7b03903ff1b88a70$var$CustomError) { (0, $hgUW1$electron).dialog.showErrorBox(error.title, error.message); return; } reject(error); } isResolved = true; window.close(); resolve(true); }); (0, $hgUW1$electron).ipcMain.on("license:buy", ()=>{ (0, $hgUW1$electron).shell.openExternal(urlToBuy); }); }); } } class $7b03903ff1b88a70$var$CustomError extends Error { constructor(message, title){ super(message); this.title = title; } } // adding code from https://github.com/sindresorhus/callsites // directly since importing its npm package keeps failing // due to esm module incompatibility function $7b03903ff1b88a70$var$callsites() { const _prepareStackTrace = Error.prepareStackTrace; Error.prepareStackTrace = (_, stack)=>stack; const stack = new Error().stack.slice(1) // eslint-disable-line unicorn/error-message ; Error.prepareStackTrace = _prepareStackTrace; // @ts-ignore return stack; } export {$7b03903ff1b88a70$export$e90be4d393e62eeb as Lisenser}; //# sourceMappingURL=module.js.map