Skip to content

Commit

Permalink
v0.5.5
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsRiprod committed Jul 20, 2024
1 parent 42e458c commit 8391048
Show file tree
Hide file tree
Showing 36 changed files with 763 additions and 204 deletions.
8 changes: 2 additions & 6 deletions AppExamples/mediawin/mediawin.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ class MediaWin {
}
};

this.cliPath = path.join(__dirname, 'DeskThingMediaCLI.exe');

const manifestPath = path.join(__dirname, 'manifest.json');
this.manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));

Expand Down Expand Up @@ -78,7 +76,7 @@ class MediaWin {

async executeCommand(command, args = '') {
return new Promise((resolve, reject) => {
exec(`${this.cliPath} ${command} ${args}`, (error, stdout, stderr) => {
exec(`cd ${__dirname} && DeskThingMediaCLI.exe ${command} ${args}`, (error, stdout, stderr) => {
if (error) {
this.sendError(`exec error: ${error}`);
reject(false);
Expand All @@ -98,10 +96,8 @@ class MediaWin {
}

async exeVol(...args) {
const executablePath = path.join(__dirname, 'adjust_get_current_system_volume_vista_plus.exe')

return new Promise((resolve, reject) => {
exec(`${executablePath} ${args}`, (error, stdout, stderr) => {
exec(`cd ${__dirname} && adjust_get_current_system_volume_vista_plus.exe ${args}`, (error, stdout, stderr) => {
if (error) {
this.sendError(`exec error: ${error}`);
reject(false);
Expand Down
1 change: 1 addition & 0 deletions AppExamples/spotify/builds/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13869,6 +13869,7 @@ var require_spotify = __commonJS({
try {
if (this.settings.output_device.value !== "default" && this.settings.output_device.value) {
this.transferPlayback(this.settings.output_device.value);
this.sendLog("Transferred successfully");
}
} catch (error) {
this.sendError("Error changing playback!" + error);
Expand Down
2 changes: 1 addition & 1 deletion AppExamples/utility/builds/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"isLocalApp": true,
"requires": [],
"label": "Utility App",
"version": "v0.5.4",
"version": "v0.5.5",
"description": "This app is a utility app that controls the settings of the DeskThing",
"author": "Riprod",
"platforms": [
Expand Down
2 changes: 1 addition & 1 deletion AppExamples/weather/builds/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"isLocalApp": true,
"requires": [],
"label": "Weather App",
"version": "v0.5.4",
"version": "v0.5.5",
"description": "Displays the current weather",
"author": "Riprod",
"platforms": [
Expand Down
23 changes: 0 additions & 23 deletions DeskThing/src/components/icons/icon/Icons/AIconTemplate.tsx

This file was deleted.

10 changes: 10 additions & 0 deletions DeskThing/src/components/icons/icon/Icons/IconCoffee.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Icon } from '..'

function IconCoffee(props): JSX.Element {
const strokeWidth = props.strokeWidth || 1

const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${strokeWidth}" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-coffee"><path d="M10 2v2"/><path d="M14 2v2"/><path d="M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1"/><path d="M6 2v2"/></svg>`
return <Icon {...props} dangerouslySetInnerHTML={{ __html: svgContent }} />
}

export default IconCoffee
2 changes: 1 addition & 1 deletion DeskThing/src/helpers/WebSocketService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const BASE_URL = 'ws://localhost:8891';
const BASE_URL = 'ws://192.168.7.1:8891';

type SocketEventListener = (msg: socketData) => void;

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
66 changes: 64 additions & 2 deletions DeskThingServer/src/main/handlers/appHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* This may be changed. When this code was written, they were the same
*
*/
import { app, ipcMain } from 'electron'
import { app, ipcMain, net } from 'electron'
import { join } from 'path'
import * as fs from 'fs'
import * as unzipper from 'unzipper'
Expand Down Expand Up @@ -337,7 +337,6 @@ async function disableApp(appName: string): Promise<void> {
}
})


sendPrefData()
} catch (error) {
console.error('Error disabling app:', error)
Expand Down Expand Up @@ -455,6 +454,68 @@ async function handleZip(zipFilePath: string): Promise<returnData> {
}
}

async function handleZipFromUrl(
zipUrlPath: string,
reply: (data: string, payload: any) => void
): Promise<void> {
const tempZipPath = join(app.getPath('appData'), 'apps', 'temp')
let returnData: returnData | undefined
try {
if (!fs.existsSync(join(app.getPath('appData'), 'apps', 'temp'))) {
fs.mkdirSync(join(app.getPath('appData'), 'apps', 'temp'), { recursive: true })
}

const writeStream = fs.createWriteStream(join(tempZipPath, 'temp.zip'))
writeStream.on('error', (error) => {
dataListener.emit(MESSAGE_TYPES.ERROR, `Error writing to temp file: ${error.message}`)
throw new Error(`Error writing to temp file: ${error.message}`)
})

const request = net.request(zipUrlPath)
request.on('response', (response) => {
if (response.statusCode !== 200) {
dataListener.emit(
MESSAGE_TYPES.ERROR,
`Failed to download zip file: ${response.statusCode}`
)
return
}

response.on('data', (chunk) => {
writeStream.write(chunk)
})

response.on('end', async () => {
writeStream.end()
try {
// Run file like a normal zip file
returnData = await handleZip(join(tempZipPath, 'temp.zip'))
console.log(`Successfully processed and deleted ${tempZipPath}`)
reply('zip-name', returnData)
} catch (error) {
dataListener.emit(MESSAGE_TYPES.ERROR, `Error processing zip file: ${error}`)
} finally {
// Clean up the temporary zip file
try {
fs.unlinkSync(tempZipPath)
console.log(`Successfully deleted ${tempZipPath}`)
} catch (cleanupError) {
console.error(`Error deleting temp file: ${cleanupError}`)
}
}
})
})

request.on('error', (error) =>
dataListener.emit(MESSAGE_TYPES.ERROR, `Error sending request: ${error}`)
)
request.end()
} catch (error) {
dataListener.emit(MESSAGE_TYPES.ERROR, `Error handling zip file: ${error}`)
throw new Error('Error handling zip file')
}
}

/**
* Loads and runs all enabled apps from appData.json
* This will also get the manifest data of each app and update that in case of there being any changes
Expand Down Expand Up @@ -578,6 +639,7 @@ export {
sendMessageToApp,
stopApp,
stopAllApps,
handleZipFromUrl,
handleZip,
loadAndRunEnabledApps,
addApp,
Expand Down
165 changes: 165 additions & 0 deletions DeskThingServer/src/main/handlers/firewallHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { exec } from 'child_process'
import os from 'os'
import dataListener, { MESSAGE_TYPES } from '../utils/events'
import fs from 'fs'
import { join } from 'path'
import { app } from 'electron'

// Function to execute shell commands
function runCommand(command: string): Promise<string> {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(`Error: ${error.message}`)
return
}
if (stderr) {
reject(`Stderr: ${stderr}`)
return
}
resolve(stdout)
})
})
}

async function checkFirewallRuleExists(port: number): Promise<boolean> {
const platform = os.platform()
let checkCommand: string

try {
if (platform === 'win32') {
// PowerShell command for Windows
checkCommand = `"Get-NetFirewallRule -DisplayName 'Deskthing Server Inbound'"`
const result = await runCommand(`powershell -Command ${checkCommand}`)

return result.trim() !== ''
} else if (platform === 'linux') {
// Bash command for iptables on Linux
checkCommand = `sudo iptables -C INPUT -p tcp --dport ${port} -j ACCEPT 2>/dev/null && echo "true" || echo "false"`
const result = await runCommand(checkCommand)
return result.trim() === 'true'
} else if (platform === 'darwin') {
// Bash command for pfctl on macOS
checkCommand = `sudo pfctl -sr | grep -q "rdr pass on lo0 inet proto tcp from any to any port ${port} -> 127.0.0.1 port ${port}" && echo "true" || echo "false"`
const result = await runCommand(checkCommand)
return result.trim() === 'true'
} else {
dataListener.emit(MESSAGE_TYPES.ERROR, `FIREWALL: Unsupported OS!`)
console.error('Unsupported OS')
return false
}
} catch (error) {
console.error(error)
return false
}
}

// Firewall setup function
async function setupFirewall(port: number): Promise<void> {
const platform = os.platform()
const inboundRuleName = 'Deskthing Server Inbound'
const outboundRuleName = 'Deskthing Server Outbound'

try {
const ruleExists = await checkFirewallRuleExists(port)
if (ruleExists) {
dataListener.emit(
MESSAGE_TYPES.LOGGING,
`FIREWALL: Firewall rule for port ${port} verified successfully`
)
console.log(`Firewall rule for port ${port} verified successfully`)
return
} else {
dataListener.emit(
MESSAGE_TYPES.ERROR,
`FIREWALL: Failed to verify firewall rule for port ${port}!`
)
console.error(`Failed to verify firewall rule for port ${port}`)
}

if (platform === 'win32') {
// PowerShell script for Windows
const script = `
$inboundRuleName = "${inboundRuleName}"
$outboundRuleName = "${outboundRuleName}"
$port = ${port}
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" +$myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
if (-not (Get-NetFirewallRule -DisplayName $inboundRuleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $inboundRuleName -Direction Inbound -Action Allow -Protocol TCP -LocalPort $port
}
if (-not (Get-NetFirewallRule -DisplayName $outboundRuleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $outboundRuleName -Direction Outbound -Action Allow -Protocol TCP -LocalPort $port
}
`

const tempScriptPath = join(app.getPath('temp'), 'setup-firewall.ps1')
fs.writeFileSync(tempScriptPath, script)

await runCommand(`powershell -ExecutionPolicy Bypass -File "${tempScriptPath}"`)

//fs.unlinkSync(tempScriptPath)

dataListener.emit(
MESSAGE_TYPES.LOGGING,
`FIREWALL: Firewall rules set up successfully on Windows`
)
console.log('Firewall rules set up successfully on Windows')
} else if (platform === 'linux') {
// Bash script for iptables on Linux
const script = `
#!/bin/bash
port=${port}
if ! sudo iptables -C INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null; then
sudo iptables -A INPUT -p tcp --dport $port -j ACCEPT
fi
if ! sudo iptables -C OUTPUT -p tcp --dport $port -j ACCEPT 2>/dev/null; then
sudo iptables -A OUTPUT -p tcp --dport $port -j ACCEPT
fi
`

await runCommand(`echo "${script}" | bash`)
dataListener.emit(
MESSAGE_TYPES.LOGGING,
`FIREWALL: Firewall rules set up successfully on Linux`
)
console.log('Firewall rules set up successfully on Linux')
} else if (platform === 'darwin') {
// Bash script for pfctl on macOS
const script = `
#!/bin/bash
port=${port}
anchorName="myAppAnchor"
if ! sudo pfctl -s all | grep -q "rdr pass on lo0 inet proto tcp from any to any port $port -> 127.0.0.1 port $port"; then
echo "rdr pass on lo0 inet proto tcp from any to any port $port -> 127.0.0.1 port $port" | sudo pfctl -a $anchorName -f -
sudo pfctl -e
fi
`

await runCommand(`echo "${script}" | bash`)
dataListener.emit(
MESSAGE_TYPES.LOGGING,
`FIREWALL: Firewall rules set up successfully on macOS`
)
console.log('Firewall rules set up successfully on macOS')
} else {
console.error('Unsupported OS')
}
} catch (error) {
dataListener.emit(
MESSAGE_TYPES.ERROR,
`FIREWALL: Error encountered trying to setup firewall for ${port}! Run administrator and try again`
)
console.error(error)
}
}

export { setupFirewall }
4 changes: 2 additions & 2 deletions DeskThingServer/src/main/handlers/websocketServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import dataListener, { MESSAGE_TYPES } from '../utils/events'
import { HandleDeviceData } from './deviceHandler'

// Create a WebSocket server that listens on port 8891
const server = new WebSocketServer({ port: 8891 })
// Check if the requested app is enabled in app_config.json
const server = new WebSocketServer({ port: 8891, host: '0.0.0.0' })

let numConnections = 0

export interface socketData {
Expand Down
Loading

0 comments on commit 8391048

Please sign in to comment.