Skip to content

Commit

Permalink
feat: add local and dynamic port forward methods
Browse files Browse the repository at this point in the history
  • Loading branch information
henrybarreto committed Oct 8, 2024
1 parent 48c7c43 commit c411d27
Show file tree
Hide file tree
Showing 10 changed files with 1,465 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v2
with:
node-version: '18'
node-version: '20'
- name: Install wine
if: ${{ matrix.platform == 'windows' }}
run: |
Expand Down
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"main": "./out/main/index.js",
"author": "ShellHub <[email protected]>(https://shellhub.io)",
"homepage": "https://github.com/shellhub-io/desktop",
"engines": {
"node": "^20"
},
"scripts": {
"format": "prettier --write .",
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix",
Expand All @@ -17,7 +20,8 @@
"postinstall": "electron-builder install-app-deps",
"build:win": "npm run build && electron-builder --win --config",
"build:mac": "npm run build && electron-builder --mac --config",
"build:linux": "npm run build && electron-builder --linux --config"
"build:linux": "npm run build && electron-builder --linux --config",
"test": "vitest"
},
"dependencies": {
"@electron-toolkit/preload": "^2.0.0",
Expand All @@ -31,6 +35,8 @@
"electron-updater": "^6.1.1",
"pinia": "^2.1.7",
"sass": "^1.69.5",
"socksv5": "^0.0.6",
"ssh2": "^1.16.0",
"vee-validate": "^4.12.7",
"vue-router": "^4.2.5",
"vuetify": "^3.4.6",
Expand All @@ -42,7 +48,7 @@
"@electron-toolkit/eslint-config-ts": "^1.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@rushstack/eslint-patch": "^1.3.3",
"@types/node": "^18.17.5",
"@types/node": "^22.7.4",
"@vitejs/plugin-vue": "^4.3.1",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^11.0.3",
Expand All @@ -56,6 +62,7 @@
"typescript": "^5.1.6",
"vite": "^4.4.9",
"vite-plugin-vuetify": "^2.0.1",
"vitest": "^2.1.2",
"vue": "^3.3.4",
"vue-tsc": "^1.8.8"
}
Expand Down
9 changes: 9 additions & 0 deletions src/preload/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
export * from './ssh/index.d'

import { ElectronAPI } from '@electron-toolkit/preload'
import EventEmitter from 'events'

export interface SSH {
localPortForward(): SSHConnection
dynamicPortForward(): SSHConnection
}

declare global {
interface Window {
ssh: SSH
electron: ElectronAPI
api: unknown
}
Expand Down
40 changes: 40 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,54 @@
import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
import {
SSH,
SSHConnection,
SSHConnectionLocalPortForward,
SSHConnectionDynamicPortForward
} from './index.d'

// Custom APIs for renderer
const api = {}

const ssh: SSH = {
localPortForward: (): SSHConnection => {
const localPortForwardInstance = new SSHConnectionLocalPortForward()

return {
events: localPortForwardInstance.events,
client: localPortForwardInstance.client,
connect: localPortForwardInstance.connect.bind(this),
disconnect: localPortForwardInstance.disconnect.bind(this),
onAuth: localPortForwardInstance.onAuth.bind(this),
onConnect: localPortForwardInstance.onConnect.bind(this),
onError: localPortForwardInstance.onError.bind(this),
onDisconnect: localPortForwardInstance.onDisconnect.bind(this)
}
},
dynamicPortForward: (): SSHConnection => {
const dynamicPortForwardInstance = new SSHConnectionDynamicPortForward()

return {
events: dynamicPortForwardInstance.events,
client: dynamicPortForwardInstance.client,
connect: dynamicPortForwardInstance.connect.bind(this),
disconnect: dynamicPortForwardInstance.disconnect.bind(this),
onAuth: dynamicPortForwardInstance.onAuth.bind(this),
onConnect: dynamicPortForwardInstance.onConnect.bind(this),
onError: dynamicPortForwardInstance.onError.bind(this),
onDisconnect: dynamicPortForwardInstance.onDisconnect.bind(this)
}
}
}

// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('electron', electronAPI)
contextBridge.exposeInMainWorld('api', api)
contextBridge.exposeInMainWorld('ssh', ssh)
} catch (error) {
console.error(error)
}
Expand All @@ -19,4 +57,6 @@ if (process.contextIsolated) {
window.electron = electronAPI
// @ts-ignore (define in dts)
window.api = api
// @ts-ignore (define in dts)
window.ssh = ssh
}
44 changes: 44 additions & 0 deletions src/preload/ssh/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import EventEmitter from 'node:events'
import ssh2 from 'ssh2'

export enum SSHEvent {
Auth = 'auth',
Connect = 'connect',
Error = 'error',
Disconnect = 'disconnect'
}

export class SSHEmitter extends EventEmitter {}

export type SSHConnectionAuth = {
host: string
username: string
password: string
namespace: string
device: string
}

export type SSHLocalPortForwardSettings = {
sourceAddr: string
sourcePort: number
destinationAddr: string
destinationPort: number
}

export type SSHDynamicPortForwardSettings = {
destinationAddr: string
destinationPort: number
}

export interface SSHConnection {
events: SSHEmitter
client: ssh2.Client
connect(auth: SSHConnectionAuth, settings: any): void
disconnect(): void
onAuth(callback: any): void
onConnect(callback: any): void
onError(callback: any): void
onDisconnect(callback: any): void
}

export * from './ssh'
Loading

0 comments on commit c411d27

Please sign in to comment.