refactore: create feature modules (#387)
* add @angular/cli to the project * increase nodejs version -> 8.2.1 * add lerna * merge web and shared module * move electron module into packages as uhk-agent Electron agent functionality is not working * delete symlinker * convert private properties to public of component if used in html * revert uhk-message.component * fix component path * fix the correct name of the uhk-message.component.scss * building web and electron module * delete uhk-renderer package * handle device connect disconnect state * add privilege detection * fix set privilege functionality * turn back download keymap functionality * add bootstrap, select2 js and fix null pointer exception * turn back upload data to keyboard * fix send keymap * fix test-serializer * add missing package.json * merging * fix appveyor build * fix linting * turn back electron storage service * commit the missing electron-datastorage-repository * update node to 8.3.0 in .nvmrc and log node version in appveyor build * set exact version number in appveyor build * vertical align privilege and missing device components * set back node version to 8 in appveyor * move node-usb dependency from usb dir to root maybe it is fix the appveyor build * revert usb to root * fix electron builder script * fix electron builder script * turn off electron devtools * remove CTRL+U functionality * fix CTRL+o * fix lint error * turnoff store freeze * start process when got `Error: EPERM: operation not permitted` error * move files from root usb dir -> packages/usb
This commit is contained in:
committed by
László Monda
parent
97770f67c0
commit
0f558e4132
1
packages/uhk-agent/src/custom_types/command-line-args.d.ts
vendored
Normal file
1
packages/uhk-agent/src/custom_types/command-line-args.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'command-line-args';
|
||||
1
packages/uhk-agent/src/custom_types/electron-is-dev.d.ts
vendored
Normal file
1
packages/uhk-agent/src/custom_types/electron-is-dev.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'electron-is-dev';
|
||||
22
packages/uhk-agent/src/dev-extension.ts
Normal file
22
packages/uhk-agent/src/dev-extension.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference path="./custom_types/electron-is-dev.d.ts"/>
|
||||
|
||||
/*
|
||||
* Install DevTool extensions when Electron is in development mode
|
||||
*/
|
||||
import { app } from 'electron';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
|
||||
if (isDev) {
|
||||
|
||||
app.once('ready', () => {
|
||||
|
||||
const { default: installExtension, REDUX_DEVTOOLS } = require('electron-devtools-installer');
|
||||
|
||||
installExtension(REDUX_DEVTOOLS)
|
||||
.then((name: string) => console.log(`Added Extension: ${name}`))
|
||||
.catch((err: any) => console.log('An error occurred: ', err));
|
||||
|
||||
require('electron-debug')({ showDevTools: true });
|
||||
});
|
||||
|
||||
}
|
||||
117
packages/uhk-agent/src/electron-main.ts
Normal file
117
packages/uhk-agent/src/electron-main.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/// <reference path="./custom_types/electron-is-dev.d.ts"/>
|
||||
/// <reference path="./custom_types/command-line-args.d.ts"/>
|
||||
|
||||
import './polyfills';
|
||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
import * as commandLineArgs from 'command-line-args';
|
||||
|
||||
// import { ElectronDataStorageRepositoryService } from './services/electron-datastorage-repository.service';
|
||||
import { CommandLineArgs } from 'uhk-common';
|
||||
import { DeviceService } from './services/device.service';
|
||||
import { logger } from './services/logger.service';
|
||||
import { AppUpdateService } from './services/app-update.service';
|
||||
import { AppService } from './services/app.service';
|
||||
import { SudoService } from './services/sudo.service';
|
||||
|
||||
const optionDefinitions = [
|
||||
{ name: 'addons', type: Boolean, defaultOption: false }
|
||||
];
|
||||
|
||||
const options: CommandLineArgs = commandLineArgs(optionDefinitions);
|
||||
|
||||
// import './dev-extension';
|
||||
// require('electron-debug')({ showDevTools: true, enabled: true });
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let win: Electron.BrowserWindow;
|
||||
autoUpdater.logger = logger;
|
||||
|
||||
let deviceService: DeviceService;
|
||||
let appUpdateService: AppUpdateService;
|
||||
let appService: AppService;
|
||||
let sudoService: SudoService;
|
||||
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
win = new BrowserWindow({
|
||||
title: 'UHK Agent',
|
||||
width: 1024,
|
||||
height: 768,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
},
|
||||
icon: 'assets/images/agent-icon.png'
|
||||
});
|
||||
win.setMenuBarVisibility(false);
|
||||
win.maximize();
|
||||
deviceService = new DeviceService(logger, win);
|
||||
appUpdateService = new AppUpdateService(logger, win, app);
|
||||
appService = new AppService(logger, win, deviceService, options);
|
||||
sudoService = new SudoService(logger);
|
||||
// and load the index.html of the app.
|
||||
|
||||
win.loadURL(url.format({
|
||||
pathname: path.join(__dirname, 'renderer/index.html'),
|
||||
protocol: 'file:',
|
||||
slashes: true
|
||||
}));
|
||||
|
||||
win.on('page-title-updated', (event: any) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Emitted when the window is closed.
|
||||
win.on('closed', () => {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
win = null;
|
||||
deviceService = null;
|
||||
appUpdateService = null;
|
||||
appService = null;
|
||||
sudoService = null;
|
||||
});
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
});
|
||||
|
||||
win.webContents.on('crashed', (event: any) => {
|
||||
logger.error(event);
|
||||
});
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow);
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('will-quit', () => {
|
||||
if (appUpdateService) {
|
||||
appUpdateService.saveFirtsRun();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (win === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here
|
||||
6
packages/uhk-agent/src/manifest.json
Normal file
6
packages/uhk-agent/src/manifest.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "UHK-Agent",
|
||||
"version": "1.0",
|
||||
"devtools_page": "foo.html",
|
||||
"default_locale": "en"
|
||||
}
|
||||
19
packages/uhk-agent/src/package.json
Normal file
19
packages/uhk-agent/src/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "uhk-agent",
|
||||
"main": "electron-main.js",
|
||||
"version": "0.0.0",
|
||||
"description": "Agent is the configuration application of the Ultimate Hacking Keyboard.",
|
||||
"author": "Ultimate Gadget Laboratories",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:UltimateHackingKeyboard/agent.git"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"engines": {
|
||||
"node": ">=8.1.0 <9.0.0",
|
||||
"npm": ">=5.1.0 <6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-hid": "0.5.4"
|
||||
}
|
||||
}
|
||||
5
packages/uhk-agent/src/polyfills.ts
Normal file
5
packages/uhk-agent/src/polyfills.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
/** Evergreen browsers require these. **/
|
||||
import 'core-js/es6/reflect';
|
||||
import 'core-js/es7/array';
|
||||
import 'core-js/es7/object';
|
||||
import 'core-js/es7/reflect';
|
||||
110
packages/uhk-agent/src/services/app-update.service.ts
Normal file
110
packages/uhk-agent/src/services/app-update.service.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { ipcMain, BrowserWindow } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import { ProgressInfo } from 'electron-builder-http/out/ProgressCallbackTransform';
|
||||
import { VersionInfo } from 'electron-builder-http/out/publishOptions';
|
||||
import * as settings from 'electron-settings';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
|
||||
import { IpcEvents, LogService } from 'uhk-common';
|
||||
import { MainServiceBase } from './main-service-base';
|
||||
|
||||
export class AppUpdateService extends MainServiceBase {
|
||||
constructor(protected logService: LogService,
|
||||
protected win: Electron.BrowserWindow,
|
||||
private app: Electron.App) {
|
||||
super(logService, win);
|
||||
|
||||
this.initListeners();
|
||||
logService.info('AppUpdateService init success');
|
||||
}
|
||||
|
||||
saveFirtsRun() {
|
||||
settings.set('firstRunVersion', this.app.getVersion());
|
||||
}
|
||||
|
||||
private initListeners() {
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.checkingForUpdate);
|
||||
});
|
||||
|
||||
autoUpdater.on('update-available', (ev: any, info: VersionInfo) => {
|
||||
autoUpdater.downloadUpdate();
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.updateAvailable, info);
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', (ev: any, info: VersionInfo) => {
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.updateNotAvailable, info);
|
||||
});
|
||||
|
||||
autoUpdater.on('error', (ev: any, err: string) => {
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateError, err.substr(0, 100));
|
||||
});
|
||||
|
||||
autoUpdater.on('download-progress', (progressObj: ProgressInfo) => {
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateDownloadProgress, progressObj);
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', (ev: any, info: VersionInfo) => {
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateDownloaded, info);
|
||||
});
|
||||
|
||||
ipcMain.on(IpcEvents.autoUpdater.updateAndRestart, () => autoUpdater.quitAndInstall(true));
|
||||
|
||||
ipcMain.on(IpcEvents.app.appStarted, () => {
|
||||
if (this.checkForUpdateAtStartup()) {
|
||||
this.checkForUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on(IpcEvents.autoUpdater.checkForUpdate, () => this.checkForUpdate());
|
||||
}
|
||||
|
||||
private checkForUpdate() {
|
||||
if (isDev) {
|
||||
const msg = 'Application update is not working in dev mode.';
|
||||
this.logService.info(msg);
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.checkForUpdateNotAvailable, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isFirstRun()) {
|
||||
const msg = 'Application update is skipping at first run.';
|
||||
this.logService.info(msg);
|
||||
this.sendIpcToWindow(IpcEvents.autoUpdater.checkForUpdateNotAvailable, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
autoUpdater.allowPrerelease = this.allowPreRelease();
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
|
||||
private isFirstRun() {
|
||||
if (!settings.has('firstRunVersion')) {
|
||||
return true;
|
||||
}
|
||||
const firstRunVersion = settings.get('firstRunVersion');
|
||||
this.logService.info(`firstRunVersion: ${firstRunVersion}`);
|
||||
this.logService.info(`package.version: ${this.app.getVersion()}`);
|
||||
|
||||
return firstRunVersion !== this.app.getVersion();
|
||||
}
|
||||
|
||||
private allowPreRelease() {
|
||||
const autoUpdateSettings = this.getAutoUpdateSettings();
|
||||
|
||||
return autoUpdateSettings && autoUpdateSettings.usePreReleaseUpdate;
|
||||
}
|
||||
|
||||
private checkForUpdateAtStartup() {
|
||||
const autoUpdateSettings = this.getAutoUpdateSettings();
|
||||
|
||||
return autoUpdateSettings && autoUpdateSettings.checkForUpdateOnStartUp;
|
||||
}
|
||||
|
||||
private getAutoUpdateSettings() {
|
||||
// const storageService = new ElectronDataStorageRepositoryService();
|
||||
// return storageService.getAutoUpdateSettings();
|
||||
return { checkForUpdateOnStartUp: false, usePreReleaseUpdate: false };
|
||||
}
|
||||
|
||||
}
|
||||
28
packages/uhk-agent/src/services/app.service.ts
Normal file
28
packages/uhk-agent/src/services/app.service.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ipcMain, BrowserWindow } from 'electron';
|
||||
|
||||
import { CommandLineArgs, IpcEvents, AppStartInfo, LogService } from 'uhk-common';
|
||||
import { MainServiceBase } from './main-service-base';
|
||||
import { DeviceService } from './device.service';
|
||||
|
||||
export class AppService extends MainServiceBase {
|
||||
constructor(protected logService: LogService,
|
||||
protected win: Electron.BrowserWindow,
|
||||
private deviceService: DeviceService,
|
||||
private options: CommandLineArgs) {
|
||||
super(logService, win);
|
||||
|
||||
ipcMain.on(IpcEvents.app.getAppStartInfo, this.handleAppStartInfo.bind(this));
|
||||
logService.info('AppService init success');
|
||||
}
|
||||
|
||||
private handleAppStartInfo(event: Electron.Event) {
|
||||
this.logService.info('getStartInfo');
|
||||
const response: AppStartInfo = {
|
||||
commandLineArgs: this.options,
|
||||
deviceConnected: this.deviceService.isConnected,
|
||||
hasPermission: this.deviceService.hasPermission()
|
||||
};
|
||||
this.logService.info('getStartInfo response:', response);
|
||||
return event.sender.send(IpcEvents.app.getAppStartInfoReply, response);
|
||||
}
|
||||
}
|
||||
167
packages/uhk-agent/src/services/device.service.ts
Normal file
167
packages/uhk-agent/src/services/device.service.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { ipcMain, BrowserWindow } from 'electron';
|
||||
|
||||
import { Constants, IpcEvents, LogService, IpcResponse } from 'uhk-common';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { Device, devices, HID } from 'node-hid';
|
||||
|
||||
import 'rxjs/add/observable/interval';
|
||||
import 'rxjs/add/operator/startWith';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
|
||||
enum Command {
|
||||
UploadConfig = 8,
|
||||
ApplyConfig = 9
|
||||
}
|
||||
|
||||
export class DeviceService {
|
||||
private static convertBufferToIntArray(buffer: Buffer): number[] {
|
||||
return Array.prototype.slice.call(buffer, 0);
|
||||
}
|
||||
|
||||
private pollTimer$: Subscription;
|
||||
private connected: boolean = false;
|
||||
|
||||
constructor(private logService: LogService,
|
||||
private win: Electron.BrowserWindow) {
|
||||
this.pollUhkDevice();
|
||||
ipcMain.on(IpcEvents.device.saveUserConfiguration, this.saveUserConfiguration.bind(this));
|
||||
logService.info('DeviceService init success');
|
||||
}
|
||||
|
||||
public get isConnected(): boolean {
|
||||
return this.connected;
|
||||
}
|
||||
|
||||
public hasPermission(): boolean {
|
||||
try {
|
||||
const devs = devices();
|
||||
return true;
|
||||
} catch (err) {
|
||||
this.logService.error('[DeviceService] hasPermission', err);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* HID API not support device attached and detached event.
|
||||
* This method check the keyboard is attached to the computer or not.
|
||||
* Every second check the HID device list.
|
||||
*/
|
||||
private pollUhkDevice(): void {
|
||||
this.pollTimer$ = Observable.interval(1000)
|
||||
.startWith(0)
|
||||
.map(() => {
|
||||
return devices().some((dev: Device) => dev.vendorId === Constants.VENDOR_ID &&
|
||||
dev.productId === Constants.PRODUCT_ID);
|
||||
})
|
||||
.distinctUntilChanged()
|
||||
.do((connected: boolean) => {
|
||||
this.connected = connected;
|
||||
this.win.webContents.send(IpcEvents.device.deviceConnectionStateChanged, connected);
|
||||
this.logService.info(`Device connection state changed to: ${connected}`);
|
||||
})
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
private saveUserConfiguration(event: Electron.Event, json: string): void {
|
||||
const response = new IpcResponse();
|
||||
|
||||
try {
|
||||
const buffer: Buffer = new Buffer(JSON.parse(json).data);
|
||||
const fragments = this.getTransferBuffers(buffer);
|
||||
const device = this.getDevice();
|
||||
device.read((err, data) => {
|
||||
if (err) {
|
||||
this.logService.error('Send data to device err:', err);
|
||||
}
|
||||
this.logService.debug('send data to device response:', data.toString());
|
||||
});
|
||||
|
||||
for (const fragment of fragments) {
|
||||
const transferData = this.getTransferData(fragment);
|
||||
this.logService.debug('Fragment: ', JSON.stringify(transferData));
|
||||
device.write(transferData);
|
||||
}
|
||||
|
||||
const applyBuffer = new Buffer([Command.ApplyConfig]);
|
||||
const applyTransferData = this.getTransferData(applyBuffer);
|
||||
this.logService.debug('Fragment: ', JSON.stringify(applyTransferData));
|
||||
device.write(applyTransferData);
|
||||
|
||||
response.success = true;
|
||||
this.logService.info('transferring finished');
|
||||
}
|
||||
catch (error) {
|
||||
this.logService.error('transferring error', error);
|
||||
response.error = { message: error.message };
|
||||
}
|
||||
|
||||
event.sender.send(IpcEvents.device.saveUserConfigurationReply, response);
|
||||
}
|
||||
|
||||
private getTransferData(buffer: Buffer): number[] {
|
||||
const data = DeviceService.convertBufferToIntArray(buffer);
|
||||
// if data start with 0 need to add additional leading zero because HID API remove it.
|
||||
// https://github.com/node-hid/node-hid/issues/187
|
||||
if (data.length > 0 && data[0] === 0) {
|
||||
data.unshift(0);
|
||||
}
|
||||
|
||||
// From HID API documentation:
|
||||
// http://www.signal11.us/oss/hidapi/hidapi/doxygen/html/group__API.html#gad14ea48e440cf5066df87cc6488493af
|
||||
// The first byte of data[] must contain the Report ID.
|
||||
// For devices which only support a single report, this must be set to 0x0.
|
||||
data.unshift(0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private getTransferBuffers(configBuffer: Buffer): Buffer[] {
|
||||
const fragments: Buffer[] = [];
|
||||
const MAX_SENDING_PAYLOAD_SIZE = Constants.MAX_PAYLOAD_SIZE - 4;
|
||||
for (let offset = 0; offset < configBuffer.length; offset += MAX_SENDING_PAYLOAD_SIZE) {
|
||||
const length = offset + MAX_SENDING_PAYLOAD_SIZE < configBuffer.length
|
||||
? MAX_SENDING_PAYLOAD_SIZE
|
||||
: configBuffer.length - offset;
|
||||
const header = new Buffer([Command.UploadConfig, length, offset & 0xFF, offset >> 8]);
|
||||
fragments.push(Buffer.concat([header, configBuffer.slice(offset, offset + length)]));
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 0 interface of the keyboard.
|
||||
* @returns {HID}
|
||||
*/
|
||||
private getDevice(): HID {
|
||||
try {
|
||||
const devs = devices();
|
||||
this.logService.silly('Available devices:', devs);
|
||||
|
||||
const dev = devs.find((x: Device) =>
|
||||
x.vendorId === Constants.VENDOR_ID &&
|
||||
x.productId === Constants.PRODUCT_ID &&
|
||||
((x.usagePage === 128 && x.usage === 129) || x.interface === 0));
|
||||
|
||||
if (!dev) {
|
||||
this.logService.info('[DeviceService] UHK Device not found:');
|
||||
return null;
|
||||
}
|
||||
const device = new HID(dev.path);
|
||||
this.logService.info('Used device:', dev);
|
||||
return device;
|
||||
}
|
||||
catch (err) {
|
||||
this.logService.error('Can not create device:', err);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
4
packages/uhk-agent/src/services/logger.service.ts
Normal file
4
packages/uhk-agent/src/services/logger.service.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import * as log from 'electron-log';
|
||||
log.transports.file.level = 'debug';
|
||||
|
||||
export const logger = log;
|
||||
16
packages/uhk-agent/src/services/main-service-base.ts
Normal file
16
packages/uhk-agent/src/services/main-service-base.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { LogService } from 'uhk-common';
|
||||
|
||||
export class MainServiceBase {
|
||||
constructor(protected logService: LogService,
|
||||
protected win: Electron.BrowserWindow) {}
|
||||
|
||||
protected sendIpcToWindow(message: string, arg?: any) {
|
||||
this.logService.info('sendIpcToWindow:', message, arg);
|
||||
if (!this.win || this.win.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.win.webContents.send(message, arg);
|
||||
}
|
||||
|
||||
}
|
||||
57
packages/uhk-agent/src/services/sudo.service.ts
Normal file
57
packages/uhk-agent/src/services/sudo.service.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { ipcMain, app } from 'electron';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
import * as path from 'path';
|
||||
import * as sudo from 'sudo-prompt';
|
||||
|
||||
import { IpcEvents, LogService, IpcResponse } from 'uhk-common';
|
||||
|
||||
export class SudoService {
|
||||
private rootDir: string;
|
||||
|
||||
constructor(private logService: LogService) {
|
||||
if (isDev) {
|
||||
this.rootDir = path.join(path.join(process.cwd(), process.argv[1]), '../../..');
|
||||
} else {
|
||||
this.rootDir = path.dirname(app.getAppPath());
|
||||
}
|
||||
this.logService.info('[SudoService] App root dir: ', this.rootDir);
|
||||
ipcMain.on(IpcEvents.device.setPrivilegeOnLinux, this.setPrivilege.bind(this));
|
||||
}
|
||||
|
||||
private setPrivilege(event: Electron.Event) {
|
||||
switch (process.platform) {
|
||||
case 'linux':
|
||||
this.setPrivilegeOnLinux(event);
|
||||
break;
|
||||
default:
|
||||
const response: IpcResponse = {
|
||||
success: false,
|
||||
error: { message: 'Permissions couldn\'t be set. Invalid platform: ' + process.platform }
|
||||
};
|
||||
|
||||
event.sender.send(IpcEvents.device.setPrivilegeOnLinuxReply, response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private setPrivilegeOnLinux(event: Electron.Event) {
|
||||
const scriptPath = path.join(this.rootDir, 'rules/setup-rules.sh');
|
||||
const options = {
|
||||
name: 'Setting UHK access rules'
|
||||
};
|
||||
const command = `sh ${scriptPath}`;
|
||||
console.log(command);
|
||||
sudo.exec(command, options, (error: any) => {
|
||||
const response = new IpcResponse();
|
||||
|
||||
if (error) {
|
||||
response.success = false;
|
||||
response.error = error;
|
||||
} else {
|
||||
response.success = true;
|
||||
}
|
||||
|
||||
event.sender.send(IpcEvents.device.setPrivilegeOnLinuxReply, response);
|
||||
});
|
||||
}
|
||||
}
|
||||
1
packages/uhk-agent/src/vendor.ts
Normal file
1
packages/uhk-agent/src/vendor.ts
Normal file
@@ -0,0 +1 @@
|
||||
import 'sudo-prompt';
|
||||
Reference in New Issue
Block a user