diff --git a/Darwin/applet.icns b/Darwin/applet.icns deleted file mode 100644 index fd03ed5..0000000 Binary files a/Darwin/applet.icns and /dev/null differ diff --git a/Darwin/main.scpt b/Darwin/main.scpt deleted file mode 100644 index 8f938f5..0000000 Binary files a/Darwin/main.scpt and /dev/null differ diff --git a/Linux/install.sh b/Linux/install.sh deleted file mode 100755 index 777d29e..0000000 --- a/Linux/install.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -# apt install remmina gnome-terminal deepin-terminal -y - -NAME='JumpServerClient' -INSTALLDIR=$HOME/$NAME - -if [ -d "$INSTALLDIR" ]; then - # delete old version - rm -rf "$INSTALLDIR" -fi - -ARCHIVE=`awk '/^__ARCHIVE_BOUNDARY__/ { print NR + 1; exit 0; }' $0` -tail -n +$ARCHIVE $0 > $NAME.tar.gz -tar -zvxf $NAME.tar.gz -C $HOME - -chmod 777 $INSTALLDIR/ -chmod 777 $INSTALLDIR/JumpServerClient -chmod 777 $INSTALLDIR/client - -mkdir -p $HOME/.local/share/applications/ - -echo "[Desktop Entry] -Name=jms -Exec=$INSTALLDIR/JumpServerClient %u -Type=Application -Terminal=false -MimeType=x-scheme-handler/jms;" > $HOME/.local/share/applications/jms.desktop -echo x-scheme-handler/jms=jms.desktop >> $HOME/.local/share/applications/mimeapps.list -update-desktop-database $HOME/.local/share/applications - -rm $NAME.tar.gz - -exit 0 -__ARCHIVE_BOUNDARY__ diff --git a/README.md b/README.md index 50b2428..0ae2117 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # Jumpserve Clients -JumpServer 客户端,目前仅 支持 RDP SSH的本地拉起。 +JumpServer 客户端,支持本地本地客户端拉起。 +## 概览 + +### Win +![windows](static/windows.png) + +### Mac +![macos](static/macos.png) ## 安装 @@ -10,7 +17,7 @@ JumpServer 客户端,目前仅 支持 RDP SSH的本地拉起。 ### Win -下载Win安装包,双击JumpServer.msi 文件(需要等待10几秒钟)。 +下载Win安装包,双击JumpServer.exe 文件(需要等待10几秒钟)。 ## 卸载 @@ -22,20 +29,10 @@ JumpServer 客户端,目前仅 支持 RDP SSH的本地拉起。 移除JumpServer.app。 -## 测试 - -rdp url link: jms: -//eyJmaWxlbmFtZSI6ICJmZW5ncWlhbmctMTA0XHU4ZDQ0XHU0ZWE3LWp1bXBzZXJ2ZXIiLCAicHJvdG9jb2wiOiAicmRwIiwgInVzZXJuYW1lIjogImZlbmdxaWFuZyIsICJjb25maWciOiAiZnVsbCBhZGRyZXNzOnM6MTI3LjAuMC4xOjMzODlcbnVzZXJuYW1lOnM6ZmVuZ3FpYW5nfFBLV3lvVWdtRXJESlM5dmtnRkllQU9DdFhEVkJrZ3RpRmFsYVxudXNlIG11bHRpbW9uOmk6MFxuc2Vzc2lvbiBicHA6aTozMlxuYXVkaW9tb2RlOmk6MlxuZGlzYWJsZSB3YWxscGFwZXI6aTowXG5kaXNhYmxlIGZ1bGwgd2luZG93IGRyYWc6aTowXG5kaXNhYmxlIG1lbnUgYW5pbXM6aTowXG5kaXNhYmxlIHRoZW1lczppOjBcbmFsdGVybmF0ZSBzaGVsbDpzOlxuc2hlbGwgd29ya2luZyBkaXJlY3Rvcnk6czpcbmF1dGhlbnRpY2F0aW9uIGxldmVsOmk6MlxuY29ubmVjdCB0byBjb25zb2xlOmk6MFxuZGlzYWJsZSBjdXJzb3Igc2V0dGluZzppOjBcbmFsbG93IGZvbnQgc21vb3RoaW5nOmk6MVxuYWxsb3cgZGVza3RvcCBjb21wb3NpdGlvbjppOjFcbnJlZGlyZWN0cHJpbnRlcnM6aTowXG5wcm9tcHQgZm9yIGNyZWRlbnRpYWxzIG9uIGNsaWVudDppOjBcbmF1dG9yZWNvbm5lY3Rpb24gZW5hYmxlZDppOjFcbmJvb2ttYXJrdHlwZTppOjNcbnVzZSByZWRpcmVjdGlvbiBzZXJ2ZXIgbmFtZTppOjBcbnNtYXJ0IHNpemluZzppOjFcbnNjcmVlbiBtb2RlIGlkOmk6MVxuIn0= - -ssh url link: jms: -//eyJmaWxlbmFtZSI6ICJmZW5ncWlhbmctZmVuZ3FpYW5nbG9jYWxob3N0LWp1bXBzZXJ2ZXIiLCAicHJvdG9jb2wiOiAic3NoIiwgInVzZXJuYW1lIjogImZlbmdxaWFuZyIsICJ0b2tlbiI6ICJ7XCJpcFwiOiBcIjEyNy4wLjAuMVwiLCBcInBvcnRcIjogXCIyMjIyXCIsIFwidXNlcm5hbWVcIjogXCJKTVMtNHd1cDc3bjJYSEMwTkp5d1hFcTkxRlRLSEFKNDhUeWozUDFxXCIsIFwicGFzc3dvcmRcIjogXCJKVUJKVVBYR01SbDloS01BXCJ9IiwgImNvbmZpZyI6ICIifQ== - -mysql url link: jms: -//eyJwcm90b2NvbCI6ICJteXNxbCIsICJ1c2VybmFtZSI6ICJhZG1pbiIsICJjb21tYW5kIjogIm15c3FsIC11IE0yQXhQVTNVUURmcFlFaUhCYjlFUGtHamg5NzVyZVJRdEJWRCAtcFplM2xicGtkMGlSWlhKNm4gLWgganVtcHNlcnZlci10ZXQxMjMxMjMuZml0MmNsb3VkLmNvbSAtUCAzMzA2MCBteXNxbDovLzE3Mi4xNi4xMC4xMTA6MzMwNyJ9 ## 打包 -- [Win Mac打包方法](https://github.com/jumpserver/apps/blob/master/README_PACK.md) +- [打包方法](https://github.com/jumpserver/apps/blob/master/README_PACK.md) ## 参考 diff --git a/README_PACK.md b/README_PACK.md index 3835429..f73ac88 100644 --- a/README_PACK.md +++ b/README_PACK.md @@ -1,72 +1,28 @@ -## Pack - -### Mac - -- 双击打开JumpServer.scpt文件。 - -- 点击 文件 --> - 导出(导出为应用程序)app - -- 当前目录上会生成一个JumpServer.app 应用程序。(打开JumpServer.app包 前往 Contents --> Resources 去更换applet.icns图标)。 - -- 打开JumpServer.app包 将JumpServer.py放入包中(下个版本JumpServer.py 将转换为golang语言编写 打包成二进制文件) - -- 前往JumpServer.app包 --> Contents 修改Info.plist文件,添加代码如下: - - ``` - CFBundleURLTypes - - - CFBundleURLName - Jms - CFBundleURLSchemes - - jms - - - - ``` - -- 选择Mac自带的磁盘工具 选择文件 --> 新建映像 --> 空白映像 - 存储。空白映像 - -- 打开映盘文件 - 将app文件及Applications的快捷方式放入(可修改背景)。打包dmg - -- 推出磁盘映像。 - -- 最后通过磁盘工具 选择 映像 --> 转换 --> 选取文件后 --> 映像格式选压缩 --> 点击转换。(完成) - -### Windows - -- 打包JumpServer.py成exe文件(具体查找Python Pyinstaller模块用法)。 - - ```python - ''' - pip install pyinstaller tinyaes - ''' - pyinstaller -F -w --key=*** --clean CloudRouse.py - ``` - -- 下载并安装Advanced Installer Windows软件安装程序制作工具。 - -- 打开advanced - installer软件win1 - -- 选中Product - Detailswin2 - -- 选中Files and Folders-->选中Application Folder-->右击,选择Add Folder--> - 选中所需要打包的目录win3 - -- 添加注册表等信息:选中Registry --> 选中HKEY_CLASSES_ROOT --> 右击,选择 New key --> 添加对应的key - valuewin4 - -- 双击buildwin5 - -- Win目录下的JMS.aip 为Windows打包的配置文件(可直接用打包工具打开进行打包) - -### Linux - -- [打包.run文件](http://qchenmo.com/typecho/build/index.php/2021/12/08/56.html) - +# 打包步骤 +## 拉起程序打包 +``` +cd go-client + +make +``` +![make](static/make.png) + +## 用户界面 electron 打包 +``` +cd interface +``` + +#### Mac +``` +npm run build:mac +``` + +#### Windows +``` +npm run build:mac +``` + +#### Linux +``` +npm run build:mac +``` diff --git a/Windows/install.reg b/Windows/install.reg deleted file mode 100755 index 7ae7c3e..0000000 --- a/Windows/install.reg +++ /dev/null @@ -1,13 +0,0 @@ -Windows Registry Editor Version 5.00 - -[HKEY_CLASSES_ROOT\jms] -"URL Protocol"="" -@="jms" - -[HKEY_CLASSES_ROOT\jms\shell] -[HKEY_CLASSES_ROOT\jms\shell\open] -[HKEY_CLASSES_ROOT\jms\shell\open\command] -@="JumoServer.exe \"%1\"" - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Terminal Server Client] -"AuthenticationLevelOverride"=dword:00000000 \ No newline at end of file diff --git a/Windows/uninstall.reg b/Windows/uninstall.reg deleted file mode 100755 index 3fd850f..0000000 --- a/Windows/uninstall.reg +++ /dev/null @@ -1,5 +0,0 @@ -Windows Registry Editor Version 5.00 -[-HKEY_CLASSES_ROOT\jms] - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Terminal Server Client] -"AuthenticationLevelOverride"=- \ No newline at end of file diff --git a/go-client/Makefile b/go-client/Makefile index cc08eaa..8ded9ea 100644 --- a/go-client/Makefile +++ b/go-client/Makefile @@ -22,4 +22,5 @@ build-client: GOARCH=arm64 GOOS=linux $(CLIENTBUILD) -ldflags "$(LDFLAGS)" -o $(BUILDDIR)/linux-arm64/client $(SSHCSRCFILE) cp -R $(BUILDDIR)/* $(BASEPATH)/../interface/bin/ - cp $(BASEPATH)/config.json $(BASEPATH)/../interface/bin/ \ No newline at end of file + cp $(BASEPATH)/config.json $(BASEPATH)/../interface/bin/ + cp $(BASEPATH)/putty.exe $(BASEPATH)/../interface/bin/windows/ \ No newline at end of file diff --git a/go-client/config.json b/go-client/config.json index 9b5364c..7759b34 100644 --- a/go-client/config.json +++ b/go-client/config.json @@ -9,7 +9,7 @@ "ssh", "telnet" ], - "comment": "PuTTY是一个Telnet、SSH、rlogin纯TCP以及串行阜连线软件。", + "comment": "PuTTY是一个Telnet、SSH、rlogin、纯TCP以及串行接口连接软件。", "download_url": "内置", "type": "linux", "path": "putty.exe", @@ -52,6 +52,23 @@ "is_internal": false, "is_default": false, "is_set": false + }, + { + "name": "mobaxterm", + "display_name": "MobaXterm", + "protocol": [ + "ssh", + "telnet" + ], + "comment": "MobaXterm是一款功能丰富的远程计算机管理工具,其包括了SSH客户端、FTP客户端、远程桌面等。", + "download_url": "https://mobaxterm.mobatek.net/download-home-edition.html", + "type": "linux", + "path": "", + "arg_format": "-newtab * sshpass -p{value} ssh -o StrictHostKeyChecking=no {username}@{host} -p{port}", + "match_first": [], + "is_internal": false, + "is_default": false, + "is_set": false } ], "remotedesktop": [ @@ -177,6 +194,23 @@ "is_internal": true, "is_default": true, "is_set": true + }, + { + "name": "securecrt", + "display_name": "SecureCRT", + "protocol": [ + "ssh", + "telnet" + ], + "comment": "SecureCRT是VanDyke Software所开发销售的一个SSH、Telnet客户端和虚拟终端软件。\n\n!!!手动下载安装,点击保存启用!!!", + "download_url": "https://www.vandyke.com/cgi-bin/releases.php?product=securecrt", + "type": "linux", + "path": "/Applications/SecureCRT.app/Contents/MacOS/SecureCRT", + "arg_format": "/N {name} /T /SSH2 /ACCEPTHOSTKEYS /p {port} /password {value} /L {username} {host}", + "match_first": [], + "is_internal": false, + "is_default": false, + "is_set": false } ], "remotedesktop": [ diff --git a/go-client/pkg/awaken/awaken.go b/go-client/pkg/awaken/awaken.go index d63b3e9..e2e7115 100755 --- a/go-client/pkg/awaken/awaken.go +++ b/go-client/pkg/awaken/awaken.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "regexp" + "strings" ) /*{ @@ -76,7 +77,7 @@ func (r *Rouse) getUserName() string { func (r *Rouse) getName() string { name, _ := url.QueryUnescape(r.Name) - return name + return strings.Replace(name, " ", "", -1) } func removeCurRdpFile() { diff --git a/go-client/pkg/awaken/awaken_darwin.go b/go-client/pkg/awaken/awaken_darwin.go index facde44..ecc117f 100755 --- a/go-client/pkg/awaken/awaken_darwin.go +++ b/go-client/pkg/awaken/awaken_darwin.go @@ -101,7 +101,7 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { case "oracle": argFormat = "sqlplus {username}/{value}@{host}:{port}/{dbname}" case "postgresql": - argFormat = "psql user={username} password={value} host={host} dbname={dbname} port={port}" + argFormat = "psql 'user={username} password={value} host={host} dbname={dbname} port={port}'" case "mysql", "mariadb": argFormat = "mysql -u {username} -p{value} -h {host} -P {port} {dbname}" } diff --git a/go-client/pkg/awaken/awaken_linux.go b/go-client/pkg/awaken/awaken_linux.go index 24e8e1e..88a9911 100755 --- a/go-client/pkg/awaken/awaken_linux.go +++ b/go-client/pkg/awaken/awaken_linux.go @@ -113,7 +113,7 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { case "oracle": argFormat = "sqlplus {username}/{value}@{host}:{port}/{dbname}" case "postgresql": - argFormat = "psql user={username} password={value} host={host} dbname={dbname} port={port}" + argFormat = "psql 'user={username} password={value} host={host} dbname={dbname} port={port}'" case "mysql", "mariadb": argFormat = "mysql -u {username} -p{value} -h {host} -P {port} {dbname}" } diff --git a/go-client/pkg/awaken/awaken_windows.go b/go-client/pkg/awaken/awaken_windows.go index 959a69f..92a15e9 100755 --- a/go-client/pkg/awaken/awaken_windows.go +++ b/go-client/pkg/awaken/awaken_windows.go @@ -61,7 +61,7 @@ func handleSSH(r *Rouse, cfg *config.AppConfig) *exec.Cmd { } connectMap := map[string]string{ - "name": r.Name, + "name": r.getName(), "protocol": r.Protocol, "username": r.getUserName(), "value": r.Value, @@ -69,7 +69,13 @@ func handleSSH(r *Rouse, cfg *config.AppConfig) *exec.Cmd { "port": strconv.Itoa(r.Port), } commands := getCommandFromArgs(connectMap, appItem.ArgFormat) - return exec.Command(appPath, strings.Split(commands, " ")...) + if strings.Contains(commands, "*") { + commands := strings.Split(commands, "*") + return exec.Command(appPath, commands...) + } else { + commands := strings.Split(commands, " ") + return exec.Command(appPath, commands...) + } } func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { @@ -87,7 +93,7 @@ func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { appPath := appItem.Path connectMap := map[string]string{ - "name": r.Name, + "name": r.getName(), "protocol": r.Protocol, "username": r.getUserName(), "value": r.Value, diff --git a/go-client/putty.exe b/go-client/putty.exe new file mode 100644 index 0000000..aecb337 Binary files /dev/null and b/go-client/putty.exe differ diff --git a/interface/build/sign/notarize.js b/interface/build/sign/notarize.js new file mode 100644 index 0000000..c176184 --- /dev/null +++ b/interface/build/sign/notarize.js @@ -0,0 +1,36 @@ +const { notarize } = require("@electron/notarize") + +const { + XCODE_APP_LOADER_EMAIL, // 你的apple Id + XCODE_APP_LOADER_PASSWORD, // 准备工作中生成的app专用密码,注意不能用apple Id的密码 + XCODE_APP_TEAM_ID, // Team ID +} = process.env + +async function main(context) { + const { electronPlatformName, appOutDir } = context + + if ( + electronPlatformName !== "darwin" || + !XCODE_APP_LOADER_EMAIL || + !XCODE_APP_LOADER_PASSWORD || + !XCODE_APP_TEAM_ID + ) { + console.log("Skipping Apple notarization.") + return; + } + + console.log("Starting Apple notarization.") + const appName = context.packager.appInfo.productFilename; + + await notarize({ + appBundleId: "com.jumpserver.client", // 将com.example.app替换为你自己项目的id + appPath: `${appOutDir}/${appName}.app`, + teamId: XCODE_APP_TEAM_ID, + appleId: XCODE_APP_LOADER_EMAIL, + appleIdPassword: XCODE_APP_LOADER_PASSWORD, + }) + + console.log("Finished Apple notarization.") +} + +exports.default = main; \ No newline at end of file diff --git a/interface/build/win/installer.nsh b/interface/build/win/installer.nsh new file mode 100644 index 0000000..2b2b731 --- /dev/null +++ b/interface/build/win/installer.nsh @@ -0,0 +1,15 @@ +!macro customHeader + RequestExecutionLevel admin +!macroend + +!macro customInstall + WriteRegStr HKCR "jms" "" "URL:jms" + WriteRegStr HKCR "jms" "URL Protocol" "" + WriteRegStr HKCR "jms\shell" "" "" + WriteRegStr HKCR "jms\shell\open" "" "" + WriteRegStr HKCR "jms\shell\open\command" "" '$INSTDIR\resources\bin\windows\JumpServerClient.exe "%1"' +!macroend + +!macro customUnInstall + DeleteRegKey HKCR "jms" +!macroend \ No newline at end of file diff --git a/interface/package.json b/interface/package.json index 467598c..dc9c04b 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,7 +1,7 @@ { "name": "jumpserver-client", "author": "Fit2Cloud Technology Co., Ltd.; ", - "version": "v2.0.0", + "version": "v2.0.1", "homepage": "https://jumpserver.org", "private": true, "scripts": { @@ -27,6 +27,7 @@ "devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", + "@electron/notarize": "^2.1.0", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-service": "~5.0.0", diff --git a/interface/src/background.js b/interface/src/background.js index 482608d..54a880b 100644 --- a/interface/src/background.js +++ b/interface/src/background.js @@ -162,28 +162,16 @@ const hideWindow = () => { } } -// app.on('second-instance', (event, commandLine, workingDirectory) => { -// let commands = commandLine.slice(); -// // commandLine 是一个数组, 其中最后一个数组元素为我们唤醒的链接 -// let urlStr = commands.pop(); -// handleOpenFromUrl(urlStr) -// }) - - -let STORE_PATH let configFilePath -if (process.platform === "win32") { - STORE_PATH = app.getPath('appData') - configFilePath = path.join(STORE_PATH, 'JumpServer', 'Client', 'config.json') + +let subPath +if (isDevelopment && !process.env.IS_TEST) { + subPath = "bin" } else { - let subPath - if (isDevelopment && !process.env.IS_TEST) { - subPath = "bin" - } else { - subPath = process.resourcesPath + "/bin" - } - configFilePath = path.join(subPath, 'config.json') + subPath = process.resourcesPath + "/bin" } +configFilePath = path.join(subPath, 'config.json') + const callBackUrlName = 'config-reply-get'//消息发布-发布名称 //读取本地文件 diff --git a/interface/src/renderer/assets/mobaxterm.png b/interface/src/renderer/assets/mobaxterm.png new file mode 100644 index 0000000..9e69e99 Binary files /dev/null and b/interface/src/renderer/assets/mobaxterm.png differ diff --git a/interface/src/renderer/pages/Databases.vue b/interface/src/renderer/pages/Databases.vue index 604dea8..d11301c 100644 --- a/interface/src/renderer/pages/Databases.vue +++ b/interface/src/renderer/pages/Databases.vue @@ -23,13 +23,13 @@