mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-31 06:26:59 +00:00
Compare commits
38 Commits
v1.0.220
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e041ddb8b5 | ||
![]() |
82a429089d | ||
![]() |
4ae59604a7 | ||
![]() |
e596fe71f3 | ||
![]() |
2a884868a3 | ||
![]() |
82dc762779 | ||
![]() |
694b9dd662 | ||
![]() |
a44d2e4a90 | ||
![]() |
d0804a5ad1 | ||
![]() |
b6ed50bbbb | ||
![]() |
3f9b905bed | ||
![]() |
42b88e4e33 | ||
![]() |
ba24069b8a | ||
![]() |
424b062d5b | ||
![]() |
5deb725758 | ||
![]() |
4069c22891 | ||
![]() |
4a515d9432 | ||
![]() |
b83b2e5acc | ||
![]() |
e407ee8bf1 | ||
![]() |
c7b39bdca7 | ||
![]() |
934cdff0f8 | ||
![]() |
ab87099b8b | ||
![]() |
47b4b54557 | ||
![]() |
15f4182e0e | ||
![]() |
4be1e12559 | ||
![]() |
5d2d179677 | ||
![]() |
4197cefdfd | ||
![]() |
7c1421ffcf | ||
![]() |
380c306d89 | ||
![]() |
cf0da75224 | ||
![]() |
d1c1b48502 | ||
![]() |
a3c5b41bb1 | ||
![]() |
2fa7678bec | ||
![]() |
c6939b114d | ||
![]() |
d3e8e2a6af | ||
![]() |
d1b161364b | ||
![]() |
c4a514fc4a | ||
![]() |
d525374061 |
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -130,7 +130,7 @@ jobs:
|
||||
path: artifact-zip
|
||||
|
||||
Linux-Build:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ${{matrix.os}}
|
||||
needs: Lint
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -138,14 +138,17 @@ jobs:
|
||||
- build-arch: x64
|
||||
arch: amd64
|
||||
rust_triple: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- build-arch: arm64
|
||||
arch: arm64
|
||||
rust_triple: aarch64-unknown-linux-gnu
|
||||
triplet: aarch64-linux-gnu-
|
||||
os: ubuntu-24.04-arm
|
||||
- build-arch: arm
|
||||
arch: armhf
|
||||
rust_triple: arm-unknown-linux-gnueabihf
|
||||
triplet: arm-linux-gnueabihf-
|
||||
os: ubuntu-24.04
|
||||
fail-fast: false
|
||||
|
||||
env:
|
||||
@@ -167,6 +170,10 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Install FPM
|
||||
run: |
|
||||
sudo gem install fpm
|
||||
|
||||
- run: rustup target add ${{matrix.rust_triple}}
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -176,12 +183,12 @@ jobs:
|
||||
|
||||
- name: Setup tar to run as root
|
||||
run: sudo chmod u+s "$(command -v tar)"
|
||||
if: matrix.build-arch != 'x64'
|
||||
if: matrix.build-arch == 'arm'
|
||||
|
||||
- name: Download cached sysroot
|
||||
uses: actions/cache@v3
|
||||
id: dl-cached-sysroot
|
||||
if: matrix.build-arch !='x64'
|
||||
if: matrix.build-arch == 'arm'
|
||||
with:
|
||||
key: sysroot-${{matrix.build-arch}}
|
||||
path: /${{matrix.build-arch}}-sysroot
|
||||
@@ -191,7 +198,7 @@ jobs:
|
||||
sudo apt-get update -y && sudo apt-get install debootstrap qemu-user-static binfmt-support -y
|
||||
sudo qemu-debootstrap --include=libfontconfig1-dev,libsecret-1-dev,libnss3,libatk1.0-0,libatk-bridge2.0-0,libgdk-pixbuf2.0-0,libgtk-3-0,libgbm1 --variant=buildd --exclude=snapd --components=main,restricted,universe,multiverse --extractor=dpkg-deb --arch ${{matrix.arch}} bionic /${{matrix.build-arch}}-sysroot/ http://ports.ubuntu.com/ubuntu-ports/
|
||||
sudo find /${{matrix.build-arch}}-sysroot -type l -lname '/*' -exec sh -c 'file="$0"; dir=$(dirname "$file"); target=$(readlink "$0"); prefix=$(dirname "$dir" | sed 's@[^/]*@\.\.@g'); newtarget="$prefix$target"; ln -snf $newtarget $file' {} \; ;
|
||||
if: matrix.build-arch != 'x64' && steps.dl-cached-sysroot.outputs.cache-hit != 'true'
|
||||
if: matrix.build-arch == 'arm' && steps.dl-cached-sysroot.outputs.cache-hit != 'true'
|
||||
|
||||
- name: Setup env to use ${{matrix.build-arch}} sysroot
|
||||
run: |
|
||||
@@ -206,9 +213,9 @@ jobs:
|
||||
elif [[ ${{matrix.arch}} == 'arm64' ]]; then
|
||||
echo "PKG_CONFIG_PATH=/${{matrix.build-arch}}-sysroot/usr/lib/pkgconfig/:/${{matrix.build-arch}}-sysroot/usr/lib/aarch64-linux-gnu/pkgconfig/" >> $GITHUB_ENV
|
||||
fi
|
||||
if: matrix.build-arch != 'x64'
|
||||
if: matrix.build-arch == 'arm'
|
||||
|
||||
- name: Install npm_modules (amd64)
|
||||
- name: Install npm_modules (native)
|
||||
run: |
|
||||
npm i -g yarn node-gyp
|
||||
yarn --network-timeout 1000000 --arch=${{matrix.build-arch}} --target-arch=${{matrix.build-arch}}
|
||||
@@ -225,6 +232,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
KEYGEN_TOKEN: ${{ secrets.KEYGEN_TOKEN }}
|
||||
USE_HARD_LINKS: false
|
||||
USE_SYSTEM_FPM: true
|
||||
# DEBUG: electron-builder,electron-builder:*
|
||||
|
||||
- name: Build web resources (amd64 only)
|
||||
@@ -250,7 +258,7 @@ jobs:
|
||||
repo: 'eugeny/tabby'
|
||||
dir: 'dist'
|
||||
rpmvers: 'el/9 el/8 ol/6 ol/7'
|
||||
debvers: 'ubuntu/bionic ubuntu/focal ubuntu/hirsute ubuntu/impish ubuntu/jammy ubuntu/kinetic ubuntu/noble ubuntu/oracular debian/jessie debian/stretch debian/buster'
|
||||
debvers: 'ubuntu/bionic ubuntu/focal ubuntu/hirsute ubuntu/impish ubuntu/jammy ubuntu/kinetic ubuntu/noble ubuntu/oracular debian/jessie debian/stretch debian/buster debian/bullseye debian/bookworm debian/trixie'
|
||||
|
||||
- uses: actions/upload-artifact@master
|
||||
name: Upload AppImage (${{matrix.arch}})
|
||||
|
@@ -347,6 +347,7 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -346,6 +346,7 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -342,6 +342,7 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -341,6 +341,7 @@ Pull requests and plugins are welcome!
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -365,6 +365,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -31,7 +31,7 @@
|
||||
* Встроенный SSH- и Telnet-клиент и менеджер подключений;
|
||||
* Встроенный последовательный терминал;
|
||||
* Темы и цветовые схемы;
|
||||
* Полностью настраеваемые сочетания клавиш;
|
||||
* Полностью настраиваемые сочетания клавиш;
|
||||
* Панели;
|
||||
* Запоминание вкладок;
|
||||
* Поддержка PowerShell (and PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder и CMD;
|
||||
@@ -342,6 +342,7 @@ Pull-запросы и плагины приветствуются!
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -341,6 +341,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -30,7 +30,7 @@
|
||||
"native-process-working-directory": "^1.0.2",
|
||||
"npm": "6",
|
||||
"rxjs": "^7.5.7",
|
||||
"russh": "0.1.14",
|
||||
"russh": "0.1.24",
|
||||
"source-map-support": "^0.5.20",
|
||||
"v8-compile-cache": "^2.3.0",
|
||||
"yargs": "^17.7.2"
|
||||
|
@@ -3628,10 +3628,10 @@ run-queue@^1.0.0, run-queue@^1.0.3:
|
||||
dependencies:
|
||||
aproba "^1.1.1"
|
||||
|
||||
russh@0.1.14:
|
||||
version "0.1.14"
|
||||
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.14.tgz#d97a6435795f97693414c55c93b823bbbbe34465"
|
||||
integrity sha512-x8n5P/QVm4yuRqRScxbjTt3RRLVLwUGC87OBXrZBOTEjPikGwyy/kcBGf2PjlV8iJ3M8JOro4b1xHj1JM8Khfg==
|
||||
russh@0.1.24:
|
||||
version "0.1.24"
|
||||
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.24.tgz#dce27a3bc63eb78024db60e6767bc80cbf523b9a"
|
||||
integrity sha512-lLMtXHJKL5uwRxwoFNDx71T7+qCXiL80qyGCRgQjYMV10gaW2AlI6mqcz3FVH8dXvdgK2ZE8DuSwlhCBK7schA==
|
||||
dependencies:
|
||||
"@napi-rs/cli" "^2.18.3"
|
||||
|
||||
|
@@ -37,7 +37,8 @@ asarUnpack:
|
||||
win:
|
||||
icon: "./build/windows/icon.ico"
|
||||
artifactName: tabby-${version}-portable-${env.ARCH}.${ext}
|
||||
rfc3161TimeStampServer: http://timestamp.sectigo.com
|
||||
signtoolOptions:
|
||||
rfc3161TimeStampServer: http://timestamp.sectigo.com
|
||||
nsis:
|
||||
oneClick: false
|
||||
artifactName: tabby-${version}-setup-${env.ARCH}.${ext}
|
||||
|
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: tabby\n"
|
||||
"Language-Team: Indonesian\n"
|
||||
"Language: id_ID\n"
|
||||
"PO-Revision-Date: 2024-12-24 22:58\n"
|
||||
"PO-Revision-Date: 2025-01-22 22:02\n"
|
||||
|
||||
#: tabby-local/src/components/terminalTab.component.ts:113
|
||||
msgid "\"{command}\" is still running. Close?"
|
||||
@@ -23,7 +23,7 @@ msgstr "{name} salin"
|
||||
|
||||
#: locale/tmp-html/tabby-terminal/src/components/appearanceSettingsTab.component.html:77
|
||||
msgid "A second font family used to display characters missing in the main font"
|
||||
msgstr "Keluarga font kedua digunakan untuk menampilkan karakter yang hilang di font utama"
|
||||
msgstr "Keluarga huruf kedua digunakan untuk menampilkan karakter yang hilang di huruf utama"
|
||||
|
||||
#: tabby-core/src/components/transfersMenu.component.ts:49
|
||||
msgid "Abort all"
|
||||
@@ -100,12 +100,12 @@ msgstr "Izinkan buka dengan cepat terminal di direktori terpilih"
|
||||
#: locale/tmp-html/tabby-core/src/components/welcomeTab.component.html:25
|
||||
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:11
|
||||
msgid "Always dark"
|
||||
msgstr ""
|
||||
msgstr "Selalu gelap"
|
||||
|
||||
#: locale/tmp-html/tabby-core/src/components/welcomeTab.component.html:27
|
||||
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:13
|
||||
msgid "Always light"
|
||||
msgstr ""
|
||||
msgstr "Selalu terang"
|
||||
|
||||
#: locale/tmp-html/tabby-terminal/src/components/appearanceSettingsTab.component.html:2
|
||||
#: tabby-terminal/src/settings.ts:14
|
||||
@@ -255,7 +255,7 @@ msgstr "Ubah baud rate"
|
||||
|
||||
#: tabby-core/src/tabContextMenu.ts:133
|
||||
msgid "Change tab color"
|
||||
msgstr ""
|
||||
msgstr "Rubah warna label"
|
||||
|
||||
#: locale/tmp-html/tabby-settings/src/components/vaultSettingsTab.component.html:12
|
||||
msgid "Change the master passphrase"
|
||||
@@ -337,7 +337,7 @@ msgstr "Skema warna"
|
||||
|
||||
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:2
|
||||
msgid "Color schemes"
|
||||
msgstr ""
|
||||
msgstr "Warna Skema"
|
||||
|
||||
#: locale/tmp-html/tabby-serial/src/components/serialProfileSettings.component.html:81
|
||||
#: locale/tmp-html/tabby-ssh/src/components/sshProfileSettings.component.html:216
|
||||
@@ -362,7 +362,7 @@ msgstr "Perintah-perintah"
|
||||
|
||||
#: tabby-core/src/theme.ts:16
|
||||
msgid "Compact (legacy)"
|
||||
msgstr ""
|
||||
msgstr "Padat (tua)"
|
||||
|
||||
#: tabby-settings/src/components/configSyncSettingsTab.component.ts:126
|
||||
msgid "Config deleted"
|
||||
@@ -449,7 +449,7 @@ msgstr "Salin jalur saat ini"
|
||||
|
||||
#: tabby-electron/src/sftpContextMenu.ts:29
|
||||
msgid "Copy full path"
|
||||
msgstr ""
|
||||
msgstr "Salin alamat lengkap"
|
||||
|
||||
#: locale/tmp-html/tabby-terminal/src/components/terminalSettingsTab.component.html:97
|
||||
msgid "Copy on select"
|
||||
@@ -1732,7 +1732,7 @@ msgstr "Ganti Nama"
|
||||
#: tabby-core/src/hotkeys.ts:24
|
||||
#: tabby-core/src/tabContextMenu.ts:121
|
||||
msgid "Rename tab"
|
||||
msgstr ""
|
||||
msgstr "Ganti nama label"
|
||||
|
||||
#: locale/tmp-html/tabby-terminal/src/components/terminalSettingsTab.component.html:3
|
||||
msgid "Rendering"
|
||||
@@ -1770,7 +1770,7 @@ msgstr "Mulai ulang sesi SSH saat ini"
|
||||
|
||||
#: tabby-telnet/src/hotkeys.ts:10
|
||||
msgid "Restart current Telnet session"
|
||||
msgstr ""
|
||||
msgstr "Mulai ulang sesi Telnet saat ini"
|
||||
|
||||
#: tabby-core/src/hotkeys.ts:64
|
||||
msgid "Restart tab"
|
||||
@@ -1782,7 +1782,7 @@ msgstr "Mulai ulang aplikasi untuk menerapkan perubahan"
|
||||
|
||||
#: tabby-settings/src/components/profilesSettingsTab.component.ts:316
|
||||
msgid "Restore settings to defaults ?"
|
||||
msgstr ""
|
||||
msgstr "Kembali ke settingan sebelumnya ?"
|
||||
|
||||
#: tabby-settings/src/components/editProfileGroupModal.component.ts:36
|
||||
msgid "Restore settings to inherited defaults ?"
|
||||
|
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: tabby\n"
|
||||
"Language-Team: Italian\n"
|
||||
"Language: it_IT\n"
|
||||
"PO-Revision-Date: 2024-12-24 22:58\n"
|
||||
"PO-Revision-Date: 2025-01-22 22:02\n"
|
||||
|
||||
#: tabby-local/src/components/terminalTab.component.ts:113
|
||||
msgid "\"{command}\" is still running. Close?"
|
||||
@@ -2177,7 +2177,7 @@ msgstr "Cambia l'implementazione del frontend del terminale (sperimentale)"
|
||||
|
||||
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:4
|
||||
msgid "Sync"
|
||||
msgstr "Sincronizazione"
|
||||
msgstr "Sincronizzazione"
|
||||
|
||||
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:53
|
||||
msgid "Sync automatically"
|
||||
|
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: tabby\n"
|
||||
"Language-Team: Turkish\n"
|
||||
"Language: tr_TR\n"
|
||||
"PO-Revision-Date: 2024-12-24 22:58\n"
|
||||
"PO-Revision-Date: 2025-01-22 22:02\n"
|
||||
|
||||
#: tabby-local/src/components/terminalTab.component.ts:113
|
||||
msgid "\"{command}\" is still running. Close?"
|
||||
@@ -966,7 +966,7 @@ msgstr "Hazır bir GitHub sorunu oluşturun"
|
||||
|
||||
#: locale/tmp-html/tabby-plugin-manager/src/components/pluginsSettingsTab.component.html:25
|
||||
msgid "Get"
|
||||
msgstr "Getir"
|
||||
msgstr "Yükle"
|
||||
|
||||
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:18
|
||||
msgid "Get it from the Tabby Web settings window"
|
||||
|
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: tabby\n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
"PO-Revision-Date: 2024-12-24 22:58\n"
|
||||
"PO-Revision-Date: 2025-01-22 22:02\n"
|
||||
|
||||
#: tabby-local/src/components/terminalTab.component.ts:113
|
||||
msgid "\"{command}\" is still running. Close?"
|
||||
|
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: tabby\n"
|
||||
"Language-Team: Chinese Traditional\n"
|
||||
"Language: zh_TW\n"
|
||||
"PO-Revision-Date: 2024-12-24 22:58\n"
|
||||
"PO-Revision-Date: 2025-01-22 22:02\n"
|
||||
|
||||
#: tabby-local/src/components/terminalTab.component.ts:113
|
||||
msgid "\"{command}\" is still running. Close?"
|
||||
|
@@ -40,7 +40,7 @@
|
||||
"css-loader": "^6.7.3",
|
||||
"deep-equal": "2.0.5",
|
||||
"electron": "^32.2.7",
|
||||
"electron-builder": "^26.0.0-alpha.8",
|
||||
"electron-builder": "^26.0.0-alpha.10",
|
||||
"electron-download": "^4.1.1",
|
||||
"electron-installer-snap": "^5.1.0",
|
||||
"@electron/rebuild": "^3.7.1",
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git a/node_modules/app-builder-lib/out/appInfo.js b/node_modules/app-builder-lib/out/appInfo.js
|
||||
index 49f6dca..0ea11f2 100644
|
||||
index 7fbbef7..0821807 100644
|
||||
--- a/node_modules/app-builder-lib/out/appInfo.js
|
||||
+++ b/node_modules/app-builder-lib/out/appInfo.js
|
||||
@@ -112,9 +112,7 @@ class AppInfo {
|
||||
@@ -116,9 +116,7 @@ class AppInfo {
|
||||
return this.info.metadata.name;
|
||||
}
|
||||
get linuxPackageName() {
|
@@ -28,9 +28,7 @@ builder({
|
||||
},
|
||||
mac: {
|
||||
identity: !process.env.CI || process.env.CSC_LINK ? undefined : null,
|
||||
notarize: process.env.APPLE_TEAM_ID ? {
|
||||
teamId: process.env.APPLE_TEAM_ID,
|
||||
} : false,
|
||||
notarize: !!process.env.APPLE_TEAM_ID,
|
||||
},
|
||||
npmRebuild: process.env.ARCH !== 'arm64',
|
||||
publish: process.env.KEYGEN_TOKEN ? [
|
||||
|
@@ -28,27 +28,29 @@ builder({
|
||||
] : undefined,
|
||||
forceCodeSigning: !!keypair,
|
||||
win: {
|
||||
certificateSha1: process.env.SM_CODE_SIGNING_CERT_SHA1_HASH,
|
||||
publisherName: process.env.SM_PUBLISHER_NAME,
|
||||
signingHashAlgorithms: ['sha256'],
|
||||
sign: keypair ? async function (configuration) {
|
||||
console.log('Signing', configuration)
|
||||
if (configuration.path) {
|
||||
try {
|
||||
const out = execSync(
|
||||
`smctl sign --keypair-alias=${keypair} --input "${String(configuration.path)}"`
|
||||
)
|
||||
if (out.toString().includes('FAILED')) {
|
||||
throw new Error(out.toString())
|
||||
signtoolOptions: {
|
||||
certificateSha1: process.env.SM_CODE_SIGNING_CERT_SHA1_HASH,
|
||||
publisherName: process.env.SM_PUBLISHER_NAME,
|
||||
signingHashAlgorithms: ['sha256'],
|
||||
sign: keypair ? async function (configuration) {
|
||||
console.log('Signing', configuration)
|
||||
if (configuration.path) {
|
||||
try {
|
||||
const out = execSync(
|
||||
`smctl sign --keypair-alias=${keypair} --input "${String(configuration.path)}"`
|
||||
)
|
||||
if (out.toString().includes('FAILED')) {
|
||||
throw new Error(out.toString())
|
||||
}
|
||||
console.log(out.toString())
|
||||
} catch (e) {
|
||||
console.error(`Failed to sign ${configuration.path}`)
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log(out.toString())
|
||||
} catch (e) {
|
||||
console.error(`Failed to sign ${configuration.path}`)
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
} : undefined,
|
||||
} : undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
44
tabby-community-color-schemes/schemes/TokyoNight
Normal file
44
tabby-community-color-schemes/schemes/TokyoNight
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xreources.py
|
||||
!
|
||||
*.foreground: #c0caf5
|
||||
*.background: #1a1b26
|
||||
*.cursorColor: #c0caf5
|
||||
!
|
||||
! Black
|
||||
*.color0: #15161e
|
||||
*.color8: #414868
|
||||
!
|
||||
! Red
|
||||
*.color1: #f7768e
|
||||
*.color9: #f7768e
|
||||
!
|
||||
! Green
|
||||
*.color2: #9ece6a
|
||||
*.color10: #9ece6a
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #e0af68
|
||||
*.color11: #e0af68
|
||||
!
|
||||
! Blue
|
||||
*.color4: #7aa2f7
|
||||
*.color12: #7aa2f7
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #bb9af7
|
||||
*.color13: #bb9af7
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #7dcfff
|
||||
*.color14: #7dcfff
|
||||
!
|
||||
! White
|
||||
*.color7: #a9b1d6
|
||||
*.color15: #c0caf5
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #eeeeee
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/TokyoNight Day
Normal file
44
tabby-community-color-schemes/schemes/TokyoNight Day
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xreources.py
|
||||
!
|
||||
*.foreground: #3760bf
|
||||
*.background: #e1e2e7
|
||||
*.cursorColor: #3760bf
|
||||
!
|
||||
! Black
|
||||
*.color0: #e9e9ed
|
||||
*.color8: #a1a6c5
|
||||
!
|
||||
! Red
|
||||
*.color1: #f52a65
|
||||
*.color9: #f52a65
|
||||
!
|
||||
! Green
|
||||
*.color2: #587539
|
||||
*.color10: #587539
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #8c6c3e
|
||||
*.color11: #8c6c3e
|
||||
!
|
||||
! Blue
|
||||
*.color4: #2e7de9
|
||||
*.color12: #2e7de9
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #9854f1
|
||||
*.color13: #9854f1
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #007197
|
||||
*.color14: #007197
|
||||
!
|
||||
! White
|
||||
*.color7: #6172b0
|
||||
*.color15: #3760bf
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #eeeeee
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/TokyoNight Storm
Normal file
44
tabby-community-color-schemes/schemes/TokyoNight Storm
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xreources.py
|
||||
!
|
||||
*.foreground: #c0caf5
|
||||
*.background: #24283b
|
||||
*.cursorColor: #c0caf5
|
||||
!
|
||||
! Black
|
||||
*.color0: #1d202f
|
||||
*.color8: #414868
|
||||
!
|
||||
! Red
|
||||
*.color1: #f7768e
|
||||
*.color9: #f7768e
|
||||
!
|
||||
! Green
|
||||
*.color2: #9ece6a
|
||||
*.color10: #9ece6a
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #e0af68
|
||||
*.color11: #e0af68
|
||||
!
|
||||
! Blue
|
||||
*.color4: #7aa2f7
|
||||
*.color12: #7aa2f7
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #bb9af7
|
||||
*.color13: #bb9af7
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #7dcfff
|
||||
*.color14: #7dcfff
|
||||
!
|
||||
! White
|
||||
*.color7: #a9b1d6
|
||||
*.color15: #c0caf5
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #eeeeee
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -23,6 +23,7 @@ export class ThemesService {
|
||||
) {
|
||||
this.rootElementStyleBackup = document.documentElement.style.cssText
|
||||
this.applyTheme(standardTheme)
|
||||
this.applyThemeVariables()
|
||||
config.ready$.toPromise().then(() => {
|
||||
this.applyCurrentTheme()
|
||||
this.applyThemeVariables()
|
||||
@@ -37,6 +38,11 @@ export class ThemesService {
|
||||
})
|
||||
}
|
||||
|
||||
private getConfigStoreOrDefaults (): any {
|
||||
/// Theme service is active before the vault is unlocked and config is available
|
||||
return this.config.store ?? this.config.getDefaults()
|
||||
}
|
||||
|
||||
private applyThemeVariables () {
|
||||
if (!this.findCurrentTheme().followsColorScheme) {
|
||||
document.documentElement.style.cssText = this.rootElementStyleBackup
|
||||
@@ -60,7 +66,7 @@ export class ThemesService {
|
||||
}
|
||||
|
||||
let background = Color(theme.background)
|
||||
if (this.config.store?.appearance.vibrancy) {
|
||||
if (this.getConfigStoreOrDefaults().appearance.vibrancy) {
|
||||
background = background.fade(0.6)
|
||||
}
|
||||
// const background = theme.background
|
||||
@@ -148,13 +154,13 @@ export class ThemesService {
|
||||
vars['--bs-form-switch-bg'] = `url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27${switchBackground}%27/%3e%3c/svg%3e")`
|
||||
}
|
||||
|
||||
vars['--spaciness'] = this.config.store.appearance.spaciness
|
||||
vars['--spaciness'] = this.getConfigStoreOrDefaults().appearance.spaciness
|
||||
|
||||
for (const [bg, fg] of contrastPairs) {
|
||||
const colorBg = Color(vars[bg]).hsl()
|
||||
const colorFg = Color(vars[fg]).hsl()
|
||||
const bgContrast = colorBg.contrast(colorFg)
|
||||
if (bgContrast < this.config.store.terminal.minimumContrastRatio) {
|
||||
if (bgContrast < this.getConfigStoreOrDefaults().terminal.minimumContrastRatio) {
|
||||
vars[fg] = this.ensureContrast(colorFg, colorBg).string()
|
||||
}
|
||||
}
|
||||
@@ -163,7 +169,7 @@ export class ThemesService {
|
||||
document.documentElement.style.setProperty(key, value)
|
||||
}
|
||||
|
||||
document.body.classList.toggle('no-animations', !this.config.store.accessibility.animations)
|
||||
document.body.classList.toggle('no-animations', !this.getConfigStoreOrDefaults().accessibility.animations)
|
||||
}
|
||||
|
||||
private ensureContrast (color: Color, against: Color): Color {
|
||||
@@ -178,7 +184,7 @@ export class ThemesService {
|
||||
while (
|
||||
(step < 1 && color.color[2] > 1 ||
|
||||
step > 1 && color.color[2] < 99) &&
|
||||
color.contrast(against) < this.config.store.terminal.minimumContrastRatio) {
|
||||
color.contrast(against) < this.getConfigStoreOrDefaults().terminal.minimumContrastRatio) {
|
||||
color.color[2] *= step
|
||||
}
|
||||
return color
|
||||
@@ -189,22 +195,22 @@ export class ThemesService {
|
||||
}
|
||||
|
||||
findCurrentTheme (): Theme {
|
||||
return this.findTheme(this.config.store.appearance.theme) ?? this.standardTheme
|
||||
return this.findTheme(this.getConfigStoreOrDefaults().appearance.theme) ?? this.standardTheme
|
||||
}
|
||||
|
||||
/// @hidden
|
||||
_getActiveColorScheme (): any {
|
||||
let theme: PlatformTheme = 'dark'
|
||||
if (this.config.store.appearance.colorSchemeMode === 'light') {
|
||||
if (this.getConfigStoreOrDefaults().appearance.colorSchemeMode === 'light') {
|
||||
theme = 'light'
|
||||
} else if (this.config.store.appearance.colorSchemeMode === 'auto') {
|
||||
} else if (this.getConfigStoreOrDefaults().appearance.colorSchemeMode === 'auto') {
|
||||
theme = this.platform.getTheme()
|
||||
}
|
||||
|
||||
if (theme === 'light') {
|
||||
return this.config.store.terminal.lightColorScheme
|
||||
return this.getConfigStoreOrDefaults().terminal.lightColorScheme
|
||||
} else {
|
||||
return this.config.store.terminal.colorScheme
|
||||
return this.getConfigStoreOrDefaults().terminal.colorScheme
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +221,7 @@ export class ThemesService {
|
||||
document.querySelector('head')!.appendChild(this.styleElement)
|
||||
}
|
||||
this.styleElement.textContent = theme.css
|
||||
document.querySelector('style#custom-css')!.innerHTML = this.config.store?.appearance?.css
|
||||
document.querySelector('style#custom-css')!.innerHTML = this.getConfigStoreOrDefaults().appearance.css
|
||||
this.themeChanged.next(theme)
|
||||
}
|
||||
|
||||
|
@@ -195,7 +195,13 @@ export class VaultService {
|
||||
if (!vault) {
|
||||
return null
|
||||
}
|
||||
return vault.secrets.find(s => s.type === type && this.keyMatches(key, s)) ?? null
|
||||
let vaultSecret = vault.secrets.find(s => s.type === type && this.keyMatches(key, s))
|
||||
if (!vaultSecret) {
|
||||
// search for secret without host in vault (like a default user/password used in multiple servers)
|
||||
key['host'] = null
|
||||
vaultSecret = vault.secrets.find(s => s.type === type && this.keyMatches(key, s))
|
||||
}
|
||||
return vaultSecret ?? null
|
||||
}
|
||||
|
||||
async addSecret (secret: VaultSecret): Promise<void> {
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// import * as fs from 'fs/promises'
|
||||
import * as fs from 'fs/promises'
|
||||
import * as crypto from 'crypto'
|
||||
import * as tmp from 'tmp-promise'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ConfigService, HostAppService, Platform, PlatformService } from 'tabby-core'
|
||||
import { ConfigService, FileProvidersService, HostAppService, Platform, PlatformService } from 'tabby-core'
|
||||
import { SSHSession } from '../session/ssh'
|
||||
import { SSHProfile } from '../api'
|
||||
import { PasswordStorageService } from './passwordStorage.service'
|
||||
@@ -15,6 +16,7 @@ export class SSHService {
|
||||
private config: ConfigService,
|
||||
hostApp: HostAppService,
|
||||
private platform: PlatformService,
|
||||
private fileProviders: FileProvidersService,
|
||||
) {
|
||||
if (hostApp.platform === Platform.Windows) {
|
||||
this.detectedWinSCPPath = platform.getWinSCPPath()
|
||||
@@ -47,14 +49,35 @@ export class SSHService {
|
||||
const args = [await this.getWinSCPURI(session.profile, undefined, session.authUsername ?? undefined)]
|
||||
|
||||
let tmpFile: tmp.FileResult|null = null
|
||||
if (session.activePrivateKey) {
|
||||
tmpFile = await tmp.file()
|
||||
// await fs.writeFile(tmpFile.path, session.activePrivateKey)
|
||||
const winSCPcom = path.slice(0, -3) + 'com'
|
||||
await this.platform.exec(winSCPcom, ['/keygen', tmpFile.path, `/output=${tmpFile.path}`])
|
||||
args.push(`/privatekey=${tmpFile.path}`)
|
||||
try {
|
||||
if (session.activePrivateKey && session.profile.options.privateKeys && session.profile.options.privateKeys.length > 0) {
|
||||
tmpFile = await tmp.file()
|
||||
let passphrase: string|null = null
|
||||
for (const pk of session.profile.options.privateKeys) {
|
||||
let privateKeyContent: string|null = null
|
||||
const buffer = await this.fileProviders.retrieveFile(pk)
|
||||
privateKeyContent = buffer.toString()
|
||||
await fs.writeFile(tmpFile.path, privateKeyContent)
|
||||
const keyHash = crypto.createHash('sha512').update(privateKeyContent).digest('hex')
|
||||
// need to pass an default passphrase, otherwise it might get stuck at the passphrase input
|
||||
passphrase = await this.passwordStorage.loadPrivateKeyPassword(keyHash) ?? 'tabby'
|
||||
const winSCPcom = path.slice(0, -3) + 'com'
|
||||
try {
|
||||
await this.platform.exec(winSCPcom, ['/keygen', tmpFile.path, '-o', tmpFile.path, '--old-passphrase', passphrase])
|
||||
} catch (error) {
|
||||
console.warn('Could not convert private key ', error)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
args.push(`/privatekey=${tmpFile.path}`)
|
||||
if (passphrase != null) {
|
||||
args.push(`/passphrase=${passphrase}`)
|
||||
}
|
||||
}
|
||||
await this.platform.exec(path, args)
|
||||
} finally {
|
||||
tmpFile?.cleanup()
|
||||
}
|
||||
await this.platform.exec(path, args)
|
||||
tmpFile?.cleanup()
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ function sshAuthTypeForMethod (m: AuthMethod): string {
|
||||
case 'saved-password': return 'password'
|
||||
case 'keyboard-interactive': return 'keyboard-interactive'
|
||||
case 'publickey': return 'publickey'
|
||||
case 'agent': return 'agent'
|
||||
case 'agent': return 'publickey'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export class SSHSession {
|
||||
|
||||
private logger: Logger
|
||||
private refCount = 0
|
||||
private remainingAuthMethods: AuthMethod[] = []
|
||||
private allAuthMethods: AuthMethod[] = []
|
||||
private serviceMessage = new Subject<string>()
|
||||
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
|
||||
private willDestroy = new Subject<void>()
|
||||
@@ -125,6 +125,7 @@ export class SSHSession {
|
||||
private translate: TranslateService
|
||||
private knownHosts: SSHKnownHostsService
|
||||
private privateKeyImporters: AutoPrivateKeyLocator[]
|
||||
private previouslyDisconnected = false
|
||||
|
||||
constructor (
|
||||
private injector: Injector,
|
||||
@@ -150,7 +151,7 @@ export class SSHSession {
|
||||
}
|
||||
|
||||
private addPublicKeyAuthMethod (name: string, contents: Buffer) {
|
||||
this.remainingAuthMethods.push({
|
||||
this.allAuthMethods.push({
|
||||
type: 'publickey',
|
||||
name,
|
||||
contents,
|
||||
@@ -158,12 +159,14 @@ export class SSHSession {
|
||||
}
|
||||
|
||||
async init (): Promise<void> {
|
||||
this.remainingAuthMethods = [{ type: 'none' }]
|
||||
this.allAuthMethods = [{ type: 'none' }]
|
||||
if (!this.profile.options.auth || this.profile.options.auth === 'publicKey') {
|
||||
if (this.profile.options.privateKeys?.length) {
|
||||
for (const pk of this.profile.options.privateKeys) {
|
||||
for (let pk of this.profile.options.privateKeys) {
|
||||
// eslint-disable-next-line @typescript-eslint/init-declarations
|
||||
let contents: Buffer
|
||||
pk = pk.replace('%h', this.profile.options.host)
|
||||
pk = pk.replace('%r', this.profile.options.user)
|
||||
try {
|
||||
contents = await this.fileProviders.retrieveFile(pk)
|
||||
} catch (error) {
|
||||
@@ -187,30 +190,32 @@ export class SSHSession {
|
||||
if (!spec) {
|
||||
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running Agent process is found`)
|
||||
} else {
|
||||
this.remainingAuthMethods.push({
|
||||
this.allAuthMethods.push({
|
||||
type: 'agent',
|
||||
...spec,
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
|
||||
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
|
||||
if (savedPassword) {
|
||||
this.remainingAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'keyboard-interactive' })
|
||||
}
|
||||
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
|
||||
if (this.profile.options.password) {
|
||||
this.remainingAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
|
||||
this.allAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
|
||||
}
|
||||
const password = await this.passwordStorage.loadPassword(this.profile)
|
||||
if (password) {
|
||||
this.remainingAuthMethods.push({ type: 'saved-password', password })
|
||||
this.allAuthMethods.push({ type: 'saved-password', password })
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'prompt-password' })
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'hostbased' })
|
||||
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
|
||||
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
|
||||
if (savedPassword) {
|
||||
this.allAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
|
||||
}
|
||||
this.allAuthMethods.push({ type: 'keyboard-interactive' })
|
||||
}
|
||||
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
|
||||
this.allAuthMethods.push({ type: 'prompt-password' })
|
||||
}
|
||||
this.allAuthMethods.push({ type: 'hostbased' })
|
||||
}
|
||||
|
||||
private async getAgentConnectionSpec (): Promise<russh.AgentConnectionSpec|null> {
|
||||
@@ -323,9 +328,14 @@ export class SSHSession {
|
||||
}
|
||||
})
|
||||
|
||||
this.previouslyDisconnected = false
|
||||
this.ssh.disconnect$.subscribe(() => {
|
||||
if (this.open) {
|
||||
this.destroy()
|
||||
if (!this.previouslyDisconnected) {
|
||||
this.previouslyDisconnected = true
|
||||
// Let service messages drain
|
||||
setTimeout(() => {
|
||||
this.destroy()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -508,6 +518,22 @@ export class SSHSession {
|
||||
}
|
||||
|
||||
async handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
||||
const subscription = this.ssh.disconnect$.subscribe(() => {
|
||||
// Auto auth and >=3 keys found
|
||||
if (!this.profile.options.auth && this.allAuthMethods.filter(x => x.type === 'publickey').length >= 3) {
|
||||
this.emitServiceMessage('The server has disconnected during authentication.')
|
||||
this.emitServiceMessage('This may happen if too many private key authentication attemps are made.')
|
||||
this.emitServiceMessage('You can set the specific private key for authentication in the profile settings.')
|
||||
}
|
||||
})
|
||||
try {
|
||||
return await this._handleAuth()
|
||||
} finally {
|
||||
subscription.unsubscribe()
|
||||
}
|
||||
}
|
||||
|
||||
private async _handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
||||
this.activePrivateKey = null
|
||||
|
||||
if (!(this.ssh instanceof russh.SSHClient)) {
|
||||
@@ -523,6 +549,7 @@ export class SSHSession {
|
||||
return noneResult
|
||||
}
|
||||
|
||||
let remainingMethods = [...this.allAuthMethods]
|
||||
let methodsLeft = noneResult.remainingMethods
|
||||
|
||||
function maybeSetRemainingMethods (r: russh.AuthFailure) {
|
||||
@@ -533,13 +560,13 @@ export class SSHSession {
|
||||
|
||||
while (true) {
|
||||
const m = methodsLeft
|
||||
const method = this.remainingAuthMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
|
||||
const method = remainingMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
|
||||
|
||||
if (!method) {
|
||||
if (this.previouslyDisconnected || !method) {
|
||||
return null
|
||||
}
|
||||
|
||||
this.remainingAuthMethods = this.remainingAuthMethods.filter(x => x !== method)
|
||||
remainingMethods = remainingMethods.filter(x => x !== method)
|
||||
|
||||
if (method.type === 'saved-password') {
|
||||
this.emitServiceMessage(this.translate.instant('Using saved password'))
|
||||
@@ -576,15 +603,12 @@ export class SSHSession {
|
||||
if (method.type === 'publickey') {
|
||||
try {
|
||||
const key = await this.loadPrivateKey(method.name, method.contents)
|
||||
const possibleHashAlgs = ['ssh-rsa', 'rsa-sha2-256', 'rsa-sha2-512'].includes(key.algorithm) ? ['sha256', 'sha512', 'sha1'] as const : [null] as const
|
||||
this.emitServiceMessage(`Trying private key: ${method.name}`)
|
||||
for (const alg of possibleHashAlgs) {
|
||||
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, alg)
|
||||
if (result instanceof russh.AuthenticatedSSHClient) {
|
||||
return result
|
||||
}
|
||||
maybeSetRemainingMethods(result)
|
||||
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, null)
|
||||
if (result instanceof russh.AuthenticatedSSHClient) {
|
||||
return result
|
||||
}
|
||||
maybeSetRemainingMethods(result)
|
||||
} catch (e) {
|
||||
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Failed to load private key ${method.name}: ${e}`)
|
||||
continue
|
||||
|
@@ -309,10 +309,16 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
|
||||
case 'scroll-to-top':
|
||||
this.frontend?.scrollToTop()
|
||||
break
|
||||
case 'scroll-up':
|
||||
case 'scroll-page-up':
|
||||
this.frontend?.scrollPages(-1)
|
||||
break
|
||||
case 'scroll-up':
|
||||
this.frontend?.scrollLines(-1)
|
||||
break
|
||||
case 'scroll-down':
|
||||
this.frontend?.scrollLines(1)
|
||||
break
|
||||
case 'scroll-page-down':
|
||||
this.frontend?.scrollPages(1)
|
||||
break
|
||||
case 'scroll-to-bottom':
|
||||
|
@@ -101,8 +101,10 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
'⌘-⌥-Shift-I',
|
||||
],
|
||||
'scroll-to-top': ['Shift-PageUp'],
|
||||
'scroll-up': ['⌥-PageUp'],
|
||||
'scroll-down': ['⌥-PageDown'],
|
||||
'scroll-page-up': ['⌥-PageUp'],
|
||||
'scroll-up': ['Ctrl-Shift-Up'],
|
||||
'scroll-down': ['Ctrl-Shift-Down'],
|
||||
'scroll-page-down': ['⌥-PageDown'],
|
||||
'scroll-to-bottom': ['Shift-PageDown'],
|
||||
},
|
||||
},
|
||||
@@ -152,8 +154,10 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
'Ctrl-Alt-Shift-I',
|
||||
],
|
||||
'scroll-to-top': ['Ctrl-PageUp'],
|
||||
'scroll-up': ['Alt-PageUp'],
|
||||
'scroll-down': ['Alt-PageDown'],
|
||||
'scroll-page-up': ['Alt-PageUp'],
|
||||
'scroll-up': ['Ctrl-Shift-Up'],
|
||||
'scroll-down': ['Ctrl-Shift-Down'],
|
||||
'scroll-page-down': ['Alt-PageDown'],
|
||||
'scroll-to-bottom': ['Ctrl-PageDown'],
|
||||
},
|
||||
},
|
||||
@@ -201,8 +205,10 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
'Ctrl-Alt-Shift-I',
|
||||
],
|
||||
'scroll-to-top': ['Ctrl-PageUp'],
|
||||
'scroll-up': ['Alt-PageUp'],
|
||||
'scroll-down': ['Alt-PageDown'],
|
||||
'scroll-page-up': ['Alt-PageUp'],
|
||||
'scroll-up': ['Ctrl-Shift-Up'],
|
||||
'scroll-down': ['Ctrl-Shift-Down'],
|
||||
'scroll-page-down': ['Alt-PageDown'],
|
||||
'scroll-to-bottom': ['Ctrl-PageDown'],
|
||||
},
|
||||
},
|
||||
|
@@ -77,6 +77,7 @@ export abstract class Frontend {
|
||||
abstract visualBell (): void
|
||||
|
||||
abstract scrollToTop (): void
|
||||
abstract scrollLines (amount: number): void
|
||||
abstract scrollPages (pages: number): void
|
||||
abstract scrollToBottom (): void
|
||||
|
||||
|
@@ -357,6 +357,10 @@ export class XTermFrontend extends Frontend {
|
||||
this.xterm.scrollPages(pages)
|
||||
}
|
||||
|
||||
scrollLines (amount: number): void {
|
||||
this.xterm.scrollLines(amount)
|
||||
}
|
||||
|
||||
scrollToBottom (): void {
|
||||
this.xtermCore._scrollToBottom()
|
||||
}
|
||||
|
@@ -86,11 +86,19 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
|
||||
name: this.translate.instant('Scroll terminal to top'),
|
||||
},
|
||||
{
|
||||
id: 'scroll-up',
|
||||
id: 'scroll-page-up',
|
||||
name: this.translate.instant('Scroll terminal one page up'),
|
||||
},
|
||||
{
|
||||
id: 'scroll-up',
|
||||
name: this.translate.instant('Scroll terminal one line up'),
|
||||
},
|
||||
{
|
||||
id: 'scroll-down',
|
||||
name: this.translate.instant('Scroll terminal one line down'),
|
||||
},
|
||||
{
|
||||
id: 'scroll-page-down',
|
||||
name: this.translate.instant('Scroll terminal one page down'),
|
||||
},
|
||||
{
|
||||
@@ -113,3 +121,4 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
|
||||
return this.hotkeys
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ import { Subject, Observable } from 'rxjs'
|
||||
import { SessionMiddleware } from '../api/middleware'
|
||||
|
||||
const OSCPrefix = Buffer.from('\x1b]')
|
||||
const OSCSuffix = Buffer.from('\x07')
|
||||
const OSCSuffixes = [Buffer.from('\x07'), Buffer.from('\x1b\\')]
|
||||
|
||||
export class OSCProcessor extends SessionMiddleware {
|
||||
get cwdReported$ (): Observable<string> { return this.cwdReported }
|
||||
@@ -14,11 +14,22 @@ export class OSCProcessor extends SessionMiddleware {
|
||||
|
||||
feedFromSession (data: Buffer): void {
|
||||
let startIndex = 0
|
||||
while (data.includes(OSCPrefix, startIndex) && data.includes(OSCSuffix, startIndex)) {
|
||||
const params = data.subarray(data.indexOf(OSCPrefix, startIndex) + OSCPrefix.length)
|
||||
const oscString = params.subarray(0, params.indexOf(OSCSuffix)).toString()
|
||||
while (data.includes(OSCPrefix, startIndex)) {
|
||||
const si = startIndex
|
||||
if (!OSCSuffixes.some(s => data.includes(s, si))) {
|
||||
break
|
||||
}
|
||||
|
||||
startIndex = data.indexOf(OSCSuffix, startIndex) + OSCSuffix.length
|
||||
const params = data.subarray(data.indexOf(OSCPrefix, startIndex) + OSCPrefix.length)
|
||||
|
||||
const [closesSuffix, closestSuffixIndex] = OSCSuffixes
|
||||
.map((suffix): [Buffer, number] => [suffix, params.indexOf(suffix)])
|
||||
.filter(([_, index]) => index !== -1)
|
||||
.sort(([_, a], [__, b]) => a - b)[0]
|
||||
|
||||
const oscString = params.subarray(0, closestSuffixIndex).toString()
|
||||
|
||||
startIndex = data.indexOf(closesSuffix, startIndex) + closesSuffix.length
|
||||
|
||||
const [oscCodeString, ...oscParams] = oscString.split(';')
|
||||
const oscCode = parseInt(oscCodeString)
|
||||
|
88
yarn.lock
88
yarn.lock
@@ -321,16 +321,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@electron/asar@3.2.17":
|
||||
version "3.2.17"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.17.tgz#91d28087aad80d1a1c8cc4e667c6476edf50f949"
|
||||
integrity sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==
|
||||
dependencies:
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@electron/asar@^3.2.7":
|
||||
"@electron/asar@3.2.18", "@electron/asar@^3.2.7":
|
||||
version "3.2.18"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.18.tgz#fa607f829209bab8b9e0ce6658d3fe81b2cba517"
|
||||
integrity sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==
|
||||
@@ -363,21 +354,6 @@
|
||||
optionalDependencies:
|
||||
global-agent "^3.0.0"
|
||||
|
||||
"@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2":
|
||||
version "10.2.0-electron.1"
|
||||
resolved "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2"
|
||||
dependencies:
|
||||
env-paths "^2.2.0"
|
||||
exponential-backoff "^3.1.1"
|
||||
glob "^8.1.0"
|
||||
graceful-fs "^4.2.6"
|
||||
make-fetch-happen "^10.2.1"
|
||||
nopt "^6.0.0"
|
||||
proc-log "^2.0.1"
|
||||
semver "^7.3.5"
|
||||
tar "^6.2.1"
|
||||
which "^2.0.2"
|
||||
|
||||
"@electron/node-gyp@https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2":
|
||||
version "10.2.0-electron.1"
|
||||
resolved "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2"
|
||||
@@ -1500,13 +1476,13 @@ app-builder-bin@5.0.0-alpha.12:
|
||||
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz#2daf82f8badc698e0adcc95ba36af4ff0650dc80"
|
||||
integrity sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==
|
||||
|
||||
app-builder-lib@26.0.0-alpha.8:
|
||||
version "26.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0-alpha.8.tgz#2ecc525692fa300414e4906dc001adec0ecb2567"
|
||||
integrity sha512-IvvGAa/RXwuNPiSckIBPjBxI4et8PWb+TsJnhKa/XtxOH64ncs6hDtV7bSxIeUmbvUj3R8dm32dej7UO0Cgtng==
|
||||
app-builder-lib@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0-alpha.10.tgz#3eb3f64ffa5e995595ad61497c5e7a0c2d64b817"
|
||||
integrity sha512-9K3MulGK7j+En4KjH3aq7AzDqe8nn35x7O9l5kwl16nWFdBthcdy1IKsx9CgjMSF+eTNctOZlXwnYiPiGzY+GQ==
|
||||
dependencies:
|
||||
"@develar/schema-utils" "~2.6.5"
|
||||
"@electron/asar" "3.2.17"
|
||||
"@electron/asar" "3.2.18"
|
||||
"@electron/fuses" "^1.8.0"
|
||||
"@electron/notarize" "2.5.0"
|
||||
"@electron/osx-sign" "1.3.1"
|
||||
@@ -1516,7 +1492,7 @@ app-builder-lib@26.0.0-alpha.8:
|
||||
"@types/fs-extra" "9.0.13"
|
||||
async-exit-hook "^2.0.1"
|
||||
bluebird-lst "^1.0.9"
|
||||
builder-util "26.0.0-alpha.8"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
chromium-pickle-js "^0.2.0"
|
||||
config-file-ts "0.2.8-rc1"
|
||||
@@ -1524,7 +1500,7 @@ app-builder-lib@26.0.0-alpha.8:
|
||||
dotenv "^16.4.5"
|
||||
dotenv-expand "^11.0.6"
|
||||
ejs "^3.1.8"
|
||||
electron-publish "26.0.0-alpha.8"
|
||||
electron-publish "26.0.0-alpha.10"
|
||||
fs-extra "^10.1.0"
|
||||
hosted-git-info "^4.1.0"
|
||||
is-ci "^3.0.0"
|
||||
@@ -2054,10 +2030,10 @@ builder-util-runtime@9.3.0-alpha.0:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util@26.0.0-alpha.8:
|
||||
version "26.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0-alpha.8.tgz#83369a6b66d8659281d72ae41102caee7dd6f0f9"
|
||||
integrity sha512-qQLArPCYUvlx1Ess7Bwsdbx7F4lnPRZBMOeoVuofcdBWIg1HbGdgYp9I0VNcD2O9D2+lVUHI1gSkCj03oRXRnQ==
|
||||
builder-util@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0-alpha.10.tgz#f445a530c28da6e3650b93e92263c06c6f89a2cc"
|
||||
integrity sha512-RMVOAgdd+tzwpyF5C8gx9KjzwdUvkUEubpsHTvb2JwlQnBcyBc6hyVCU2gt2MivQCLbjCOEgsUX1/zHrWDqGfg==
|
||||
dependencies:
|
||||
"7zip-bin" "~5.2.0"
|
||||
"@types/debug" "^4.1.6"
|
||||
@@ -2065,7 +2041,7 @@ builder-util@26.0.0-alpha.8:
|
||||
bluebird-lst "^1.0.9"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
chalk "^4.1.2"
|
||||
cross-spawn "^7.0.3"
|
||||
cross-spawn "^7.0.6"
|
||||
debug "^4.3.4"
|
||||
fs-extra "^10.1.0"
|
||||
http-proxy-agent "^7.0.0"
|
||||
@@ -2725,7 +2701,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^7.0.0:
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.6:
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
|
||||
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
|
||||
@@ -2962,13 +2938,13 @@ dir-glob@^3.0.1:
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
dmg-builder@26.0.0-alpha.8:
|
||||
version "26.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0-alpha.8.tgz#d9766adef7124fbaa21300256b53c4bf6c89f62b"
|
||||
integrity sha512-H53RkHuUBIgiZtTTdjGigD5BVKYoH6t7Y+ZNmjdzMuptL6rCni7K0mrqvVycCkYRvdeM8BWZeUvw4iOwRQIhmQ==
|
||||
dmg-builder@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0-alpha.10.tgz#d4d908922005a0c852d0919a7dd0b8f77d3c4bd0"
|
||||
integrity sha512-RWzCNLLu4dGIvBf8kBzjF/zI5aMOSA149S1V2NgAA4La8f8ghdJAm/DI5crSb2zDijFLyTNmUGTtvU6eHgiZyQ==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.0-alpha.8"
|
||||
builder-util "26.0.0-alpha.8"
|
||||
app-builder-lib "26.0.0-alpha.10"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
fs-extra "^10.1.0"
|
||||
iconv-lite "^0.6.2"
|
||||
@@ -3091,16 +3067,16 @@ ejs@^3.1.8:
|
||||
dependencies:
|
||||
jake "^10.8.5"
|
||||
|
||||
electron-builder@^26.0.0-alpha.8:
|
||||
version "26.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0-alpha.8.tgz#61529b4e977deedf2612a5ca152ee14f69a2aba2"
|
||||
integrity sha512-sx9ObBOEPiHdmDkTRehZWZG2Z26dL6v+Ue3PMji6bj6q5EwY+3h8Q0qZk5JEvUYO2LRuGFbkYpnzdOZrbxRd7A==
|
||||
electron-builder@^26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0-alpha.10.tgz#6f629f5f1f3340286af71cabd12d94edc53f15ea"
|
||||
integrity sha512-QTitqOlP5aZ/8zhnxqjRb6BxSR7Kvwv07PoBGeIXADwSPHQhKhZ+S+GRFzUSYQrMTTJLGzUHbnAes6fZ3uThEA==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.0-alpha.8"
|
||||
builder-util "26.0.0-alpha.8"
|
||||
app-builder-lib "26.0.0-alpha.10"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
chalk "^4.1.2"
|
||||
dmg-builder "26.0.0-alpha.8"
|
||||
dmg-builder "26.0.0-alpha.10"
|
||||
fs-extra "^10.1.0"
|
||||
is-ci "^3.0.0"
|
||||
lazy-val "^1.0.5"
|
||||
@@ -3190,13 +3166,13 @@ electron-localshortcut@^3.1.0:
|
||||
keyboardevent-from-electron-accelerator "^2.0.0"
|
||||
keyboardevents-areequal "^0.2.1"
|
||||
|
||||
electron-publish@26.0.0-alpha.8:
|
||||
version "26.0.0-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0-alpha.8.tgz#8e2234905e3a1a1909170543b159283600919562"
|
||||
integrity sha512-IGHPQkfSL+LYAIiqJ2E1mVTxNPFh4XRvQ+OPmBFrgpZrR32NrMlxssUyx1B0N1bGLjevjBMMitlwKFNM5WPnXg==
|
||||
electron-publish@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0-alpha.10.tgz#16ac95acca2d796ca00c7a90ca27ebf31855f284"
|
||||
integrity sha512-yUkCJD7MLN57d6PJ8PMcBCR35xytA+jHyrOiS/H0hlmTOWq1sXN+tIBylX4h0dD/C6mn75/y5eE156Pe2nccPw==
|
||||
dependencies:
|
||||
"@types/fs-extra" "^9.0.11"
|
||||
builder-util "26.0.0-alpha.8"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
chalk "^4.1.2"
|
||||
form-data "^4.0.0"
|
||||
|
Reference in New Issue
Block a user