UNPKG

electron-lisenser

Version:
494 lines (473 loc) 18.9 kB
var $8zHUo$electron = require("electron"); var $8zHUo$fs = require("fs"); var $8zHUo$path = require("path"); var $8zHUo$lisenser = require("lisenser"); var $8zHUo$process = require("process"); var $8zHUo$os = require("os"); var $8zHUo$crypto = require("crypto"); var $8zHUo$child_process = require("child_process"); var $8zHUo$systeminformation = require("systeminformation"); function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } function $parcel$interopDefault(a) { return a && a.__esModule ? a.default : a; } $parcel$export(module.exports, "Lisenser", () => $83793dccb594ee12$export$e90be4d393e62eeb); function $d19362e08a40f3c2$export$1cf7ffb9847dddd6(window, appName) { const template = $8zHUo$process.platform === "darwin" ? $d19362e08a40f3c2$var$buildDarwinTemplate(appName) : $d19362e08a40f3c2$var$buildDefaultTemplate(window); return (0, $8zHUo$electron.Menu).buildFromTemplate(template); } function $d19362e08a40f3c2$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, $8zHUo$electron.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 $d19362e08a40f3c2$var$buildDefaultTemplate(window) { const templateDefault = [ { label: "&File", submenu: [ { label: "&Open", accelerator: "Ctrl+O" }, { label: "&Close", accelerator: "Ctrl+W", click: ()=>{ window.close(); } } ] } ]; return templateDefault; } class $b7c6249e0413ee6a$export$1b8b81297aac6025 { fallBackUsed = false; constructor(){ this.metas = {}; this.secret = "|machine-digest|"; this.initialized = false; this.initPromise = null; } async _init() { this.metas.OS_TYPE = $8zHUo$os.type(); this.metas.OS_PLATFORM = $8zHUo$os.platform(); this.metas.OS_ARCH = $8zHUo$os.arch(); // this.metas.OS_RELEASE = os.release() this.metas.OS_CPU = $8zHUo$os.cpus().map((k)=>`${k.model}`).sort().join("."); let _id; try { if (this.metas.OS_PLATFORM == "darwin") { const idMatch = /IOPlatformUUID"\s=\s"([^\s]+)"/.exec((0, $8zHUo$child_process.execSync)("ioreg -rd1 -c IOPlatformExpertDevice").toString("utf8")); if (idMatch) _id = idMatch[1]; } else if (this.metas.OS_PLATFORM == "linux") _id = (0, $8zHUo$child_process.execSync)("cat /var/lib/dbus/machine-id").toString("utf8"); else if ([ "win32", "win64" ].includes(this.metas.OS_PLATFORM)) _id = (0, $8zHUo$child_process.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 $b7c6249e0413ee6a$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 $8zHUo$crypto.createHmac("sha256", this.secret).update(raw); } } async function $b7c6249e0413ee6a$var$sysInfo() { return await new Promise((resolve)=>{ const timeoutId = setTimeout(()=>resolve(undefined), 60000); (0, ($parcel$interopDefault($8zHUo$systeminformation))).system().then((res)=>{ clearTimeout(timeoutId); resolve(res); }, ()=>{ clearTimeout(timeoutId); resolve(undefined); }); }); } class $83793dccb594ee12$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, $b7c6249e0413ee6a$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, $8zHUo$fs.promises).access(`${(0, ($parcel$interopDefault($8zHUo$electron))).app.getPath("userData")}/`, (0, ($parcel$interopDefault($8zHUo$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 $83793dccb594ee12$var$CustomError("Unable to access the folder path of this App", "File Permission Error"); try { const licensePath = (0, ($parcel$interopDefault($8zHUo$path))).join((0, ($parcel$interopDefault($8zHUo$electron))).app.getPath("userData"), this.productId); return await (0, $8zHUo$fs.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 $83793dccb594ee12$var$CustomError("Unable to access the folder path of this App", "File Permission Error"); const licensePath = (0, ($parcel$interopDefault($8zHUo$path))).join((0, ($parcel$interopDefault($8zHUo$electron))).app.getPath("userData"), this.productId); await (0, $8zHUo$fs.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 $8zHUo$lisenser.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 $8zHUo$lisenser.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 $8zHUo$lisenser.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 $8zHUo$lisenser.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 $8zHUo$lisenser.generate3rdPartyToken(req); } async createOtpWindow(iconPath, appName, licenseKey) { const window = new (0, ($parcel$interopDefault($8zHUo$electron))).BrowserWindow({ width: 500, height: 375, icon: iconPath, minWidth: 500, minHeight: 375, title: `${appName} - One Time Code`, webPreferences: { preload: (0, ($parcel$interopDefault($8zHUo$path))).join($83793dccb594ee12$var$callsites()[0].getFileName(), "../preloads/forotp.js") } }); window.loadFile((0, ($parcel$interopDefault($8zHUo$path))).join($83793dccb594ee12$var$callsites()[0].getFileName(), "../renderer/otp.html")); return new Promise(async (resolve)=>{ window.on("close", ()=>resolve()); (0, ($parcel$interopDefault($8zHUo$electron))).ipcMain.handle("license:reset", async (_event, otp)=>{ const hasReset = await $8zHUo$lisenser.resetLicense(otp, this.productId, licenseKey).catch(()=>false); if (!hasReset) return "Passcode verification failed."; window.close(); }); (0, ($parcel$interopDefault($8zHUo$electron))).ipcMain.handle("license:otp:resend", async ()=>{ await $8zHUo$lisenser.requestOtpForLicenseReset(this.productId, licenseKey); }); await $8zHUo$lisenser.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, ($parcel$interopDefault($8zHUo$electron))).BrowserWindow({ width: 600, height: 365, icon: iconPath, minWidth: 600, minHeight: 365, title: `${appName} - License Key`, webPreferences: { preload: (0, ($parcel$interopDefault($8zHUo$path))).join($83793dccb594ee12$var$callsites()[0].getFileName(), "../preloads/foractivate.js") } }); window.loadFile((0, ($parcel$interopDefault($8zHUo$path))).join($83793dccb594ee12$var$callsites()[0].getFileName(), "../renderer/activate.html")); // disable dev console and enable copy-pasting if (setMenu) (0, ($parcel$interopDefault($8zHUo$electron))).Menu.setApplicationMenu((0, $d19362e08a40f3c2$export$1cf7ffb9847dddd6)(window, appName)); let isResolved = false; return new Promise((resolve, reject)=>{ window.on("close", ()=>{ if (!isResolved) resolve(false); }); (0, ($parcel$interopDefault($8zHUo$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, ($parcel$interopDefault($8zHUo$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 $83793dccb594ee12$var$CustomError) { (0, ($parcel$interopDefault($8zHUo$electron))).dialog.showErrorBox(error.title, error.message); return; } reject(error); } isResolved = true; window.close(); resolve(true); }); (0, ($parcel$interopDefault($8zHUo$electron))).ipcMain.on("license:buy", ()=>{ (0, ($parcel$interopDefault($8zHUo$electron))).shell.openExternal(urlToBuy); }); }); } } class $83793dccb594ee12$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 $83793dccb594ee12$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; } //# sourceMappingURL=main.js.map