Compare commits

..

3 Commits

Author SHA1 Message Date
Eugene
4efcf1bbd6 Update build.yml 2025-01-22 23:07:24 +01:00
Eugene
abea964d94 Update build.yml 2025-01-22 22:59:28 +01:00
Eugene
2e7b66ac60 native arm64 build 2025-01-22 22:40:11 +01:00
27 changed files with 157 additions and 356 deletions

View File

@@ -258,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 debian/bullseye debian/bookworm debian/trixie'
debvers: 'ubuntu/bionic ubuntu/focal ubuntu/hirsute ubuntu/impish ubuntu/jammy ubuntu/kinetic ubuntu/noble ubuntu/oracular debian/jessie debian/stretch debian/buster'
- uses: actions/upload-artifact@master
name: Upload AppImage (${{matrix.arch}})

View File

@@ -31,7 +31,7 @@
* Встроенный SSH- и Telnet-клиент и менеджер подключений;
* Встроенный последовательный терминал;
* Темы и цветовые схемы;
* Полностью настраиваемые сочетания клавиш;
* Полностью настраеваемые сочетания клавиш;
* Панели;
* Запоминание вкладок;
* Поддержка PowerShell (and PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder и CMD;

View File

@@ -30,7 +30,7 @@
"native-process-working-directory": "^1.0.2",
"npm": "6",
"rxjs": "^7.5.7",
"russh": "0.1.24",
"russh": "0.1.14",
"source-map-support": "^0.5.20",
"v8-compile-cache": "^2.3.0",
"yargs": "^17.7.2"

View File

@@ -3628,10 +3628,10 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
russh@0.1.24:
version "0.1.24"
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.24.tgz#dce27a3bc63eb78024db60e6767bc80cbf523b9a"
integrity sha512-lLMtXHJKL5uwRxwoFNDx71T7+qCXiL80qyGCRgQjYMV10gaW2AlI6mqcz3FVH8dXvdgK2ZE8DuSwlhCBK7schA==
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==
dependencies:
"@napi-rs/cli" "^2.18.3"

View File

@@ -37,8 +37,7 @@ asarUnpack:
win:
icon: "./build/windows/icon.ico"
artifactName: tabby-${version}-portable-${env.ARCH}.${ext}
signtoolOptions:
rfc3161TimeStampServer: http://timestamp.sectigo.com
rfc3161TimeStampServer: http://timestamp.sectigo.com
nsis:
oneClick: false
artifactName: tabby-${version}-setup-${env.ARCH}.${ext}

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Indonesian\n"
"Language: id_ID\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
"PO-Revision-Date: 2024-12-24 22:58\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 huruf kedua digunakan untuk menampilkan karakter yang hilang di huruf utama"
msgstr "Keluarga font kedua digunakan untuk menampilkan karakter yang hilang di font 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 "Selalu gelap"
msgstr ""
#: 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 "Selalu terang"
msgstr ""
#: 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 "Rubah warna label"
msgstr ""
#: 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 "Warna Skema"
msgstr ""
#: 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 "Padat (tua)"
msgstr ""
#: 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 "Salin alamat lengkap"
msgstr ""
#: 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 "Ganti nama label"
msgstr ""
#: 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 "Mulai ulang sesi Telnet saat ini"
msgstr ""
#: 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 "Kembali ke settingan sebelumnya ?"
msgstr ""
#: tabby-settings/src/components/editProfileGroupModal.component.ts:36
msgid "Restore settings to inherited defaults ?"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Italian\n"
"Language: it_IT\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
"PO-Revision-Date: 2024-12-24 22:58\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 "Sincronizzazione"
msgstr "Sincronizazione"
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:53
msgid "Sync automatically"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Turkish\n"
"Language: tr_TR\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
"PO-Revision-Date: 2024-12-24 22:58\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 "Yükle"
msgstr "Getir"
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:18
msgid "Get it from the Tabby Web settings window"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Chinese Traditional\n"
"Language: zh_TW\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"

View File

@@ -40,7 +40,7 @@
"css-loader": "^6.7.3",
"deep-equal": "2.0.5",
"electron": "^32.2.7",
"electron-builder": "^26.0.0-alpha.10",
"electron-builder": "^26.0.0-alpha.8",
"electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0",
"@electron/rebuild": "^3.7.1",

View File

@@ -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 7fbbef7..0821807 100644
index 49f6dca..0ea11f2 100644
--- a/node_modules/app-builder-lib/out/appInfo.js
+++ b/node_modules/app-builder-lib/out/appInfo.js
@@ -116,9 +116,7 @@ class AppInfo {
@@ -112,9 +112,7 @@ class AppInfo {
return this.info.metadata.name;
}
get linuxPackageName() {

View File

@@ -28,7 +28,9 @@ builder({
},
mac: {
identity: !process.env.CI || process.env.CSC_LINK ? undefined : null,
notarize: !!process.env.APPLE_TEAM_ID,
notarize: process.env.APPLE_TEAM_ID ? {
teamId: process.env.APPLE_TEAM_ID,
} : false,
},
npmRebuild: process.env.ARCH !== 'arm64',
publish: process.env.KEYGEN_TOKEN ? [

View File

@@ -28,29 +28,27 @@ builder({
] : undefined,
forceCodeSigning: !!keypair,
win: {
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)
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)
}
} : undefined,
},
}
} : undefined,
},
},

View File

@@ -1,44 +0,0 @@
!
! 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:

View File

@@ -1,44 +0,0 @@
!
! 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:

View File

@@ -1,44 +0,0 @@
!
! 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:

View File

@@ -195,13 +195,7 @@ export class VaultService {
if (!vault) {
return 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
return vault.secrets.find(s => s.type === type && this.keyMatches(key, s)) ?? null
}
async addSecret (secret: VaultSecret): Promise<void> {

View File

@@ -1,8 +1,7 @@
import * as fs from 'fs/promises'
import * as crypto from 'crypto'
// import * as fs from 'fs/promises'
import * as tmp from 'tmp-promise'
import { Injectable } from '@angular/core'
import { ConfigService, FileProvidersService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { ConfigService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { SSHSession } from '../session/ssh'
import { SSHProfile } from '../api'
import { PasswordStorageService } from './passwordStorage.service'
@@ -16,7 +15,6 @@ export class SSHService {
private config: ConfigService,
hostApp: HostAppService,
private platform: PlatformService,
private fileProviders: FileProvidersService,
) {
if (hostApp.platform === Platform.Windows) {
this.detectedWinSCPPath = platform.getWinSCPPath()
@@ -49,35 +47,14 @@ export class SSHService {
const args = [await this.getWinSCPURI(session.profile, undefined, session.authUsername ?? undefined)]
let tmpFile: tmp.FileResult|null = null
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()
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}`)
}
await this.platform.exec(path, args)
tmpFile?.cleanup()
}
}

View File

@@ -111,7 +111,7 @@ export class SSHSession {
private logger: Logger
private refCount = 0
private allAuthMethods: AuthMethod[] = []
private remainingAuthMethods: AuthMethod[] = []
private serviceMessage = new Subject<string>()
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
private willDestroy = new Subject<void>()
@@ -125,7 +125,6 @@ export class SSHSession {
private translate: TranslateService
private knownHosts: SSHKnownHostsService
private privateKeyImporters: AutoPrivateKeyLocator[]
private previouslyDisconnected = false
constructor (
private injector: Injector,
@@ -151,7 +150,7 @@ export class SSHSession {
}
private addPublicKeyAuthMethod (name: string, contents: Buffer) {
this.allAuthMethods.push({
this.remainingAuthMethods.push({
type: 'publickey',
name,
contents,
@@ -159,14 +158,12 @@ export class SSHSession {
}
async init (): Promise<void> {
this.allAuthMethods = [{ type: 'none' }]
this.remainingAuthMethods = [{ type: 'none' }]
if (!this.profile.options.auth || this.profile.options.auth === 'publicKey') {
if (this.profile.options.privateKeys?.length) {
for (let pk of this.profile.options.privateKeys) {
for (const 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) {
@@ -190,32 +187,30 @@ export class SSHSession {
if (!spec) {
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running Agent process is found`)
} else {
this.allAuthMethods.push({
this.remainingAuthMethods.push({
type: 'agent',
...spec,
})
}
}
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
if (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.allAuthMethods.push({ type: 'saved-password', password })
}
}
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.remainingAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
}
this.allAuthMethods.push({ type: 'keyboard-interactive' })
this.remainingAuthMethods.push({ type: 'keyboard-interactive' })
}
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
this.allAuthMethods.push({ type: 'prompt-password' })
if (this.profile.options.password) {
this.remainingAuthMethods.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.remainingAuthMethods.push({ type: 'prompt-password' })
}
this.allAuthMethods.push({ type: 'hostbased' })
this.remainingAuthMethods.push({ type: 'hostbased' })
}
private async getAgentConnectionSpec (): Promise<russh.AgentConnectionSpec|null> {
@@ -328,14 +323,9 @@ export class SSHSession {
}
})
this.previouslyDisconnected = false
this.ssh.disconnect$.subscribe(() => {
if (!this.previouslyDisconnected) {
this.previouslyDisconnected = true
// Let service messages drain
setTimeout(() => {
this.destroy()
})
if (this.open) {
this.destroy()
}
})
@@ -518,22 +508,6 @@ 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)) {
@@ -549,7 +523,6 @@ export class SSHSession {
return noneResult
}
let remainingMethods = [...this.allAuthMethods]
let methodsLeft = noneResult.remainingMethods
function maybeSetRemainingMethods (r: russh.AuthFailure) {
@@ -560,13 +533,13 @@ export class SSHSession {
while (true) {
const m = methodsLeft
const method = remainingMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
const method = this.remainingAuthMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
if (this.previouslyDisconnected || !method) {
if (!method) {
return null
}
remainingMethods = remainingMethods.filter(x => x !== method)
this.remainingAuthMethods = this.remainingAuthMethods.filter(x => x !== method)
if (method.type === 'saved-password') {
this.emitServiceMessage(this.translate.instant('Using saved password'))
@@ -603,12 +576,15 @@ 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}`)
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, null)
if (result instanceof russh.AuthenticatedSSHClient) {
return result
for (const alg of possibleHashAlgs) {
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, alg)
if (result instanceof russh.AuthenticatedSSHClient) {
return result
}
maybeSetRemainingMethods(result)
}
maybeSetRemainingMethods(result)
} catch (e) {
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Failed to load private key ${method.name}: ${e}`)
continue

View File

@@ -309,16 +309,10 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
case 'scroll-to-top':
this.frontend?.scrollToTop()
break
case 'scroll-page-up':
case 'scroll-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':

View File

@@ -101,10 +101,8 @@ export class TerminalConfigProvider extends ConfigProvider {
'⌘-⌥-Shift-I',
],
'scroll-to-top': ['Shift-PageUp'],
'scroll-page-up': ['⌥-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['⌥-PageDown'],
'scroll-up': ['⌥-PageUp'],
'scroll-down': ['⌥-PageDown'],
'scroll-to-bottom': ['Shift-PageDown'],
},
},
@@ -154,10 +152,8 @@ export class TerminalConfigProvider extends ConfigProvider {
'Ctrl-Alt-Shift-I',
],
'scroll-to-top': ['Ctrl-PageUp'],
'scroll-page-up': ['Alt-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['Alt-PageDown'],
'scroll-up': ['Alt-PageUp'],
'scroll-down': ['Alt-PageDown'],
'scroll-to-bottom': ['Ctrl-PageDown'],
},
},
@@ -205,10 +201,8 @@ export class TerminalConfigProvider extends ConfigProvider {
'Ctrl-Alt-Shift-I',
],
'scroll-to-top': ['Ctrl-PageUp'],
'scroll-page-up': ['Alt-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['Alt-PageDown'],
'scroll-up': ['Alt-PageUp'],
'scroll-down': ['Alt-PageDown'],
'scroll-to-bottom': ['Ctrl-PageDown'],
},
},

View File

@@ -77,7 +77,6 @@ export abstract class Frontend {
abstract visualBell (): void
abstract scrollToTop (): void
abstract scrollLines (amount: number): void
abstract scrollPages (pages: number): void
abstract scrollToBottom (): void

View File

@@ -357,10 +357,6 @@ export class XTermFrontend extends Frontend {
this.xterm.scrollPages(pages)
}
scrollLines (amount: number): void {
this.xterm.scrollLines(amount)
}
scrollToBottom (): void {
this.xtermCore._scrollToBottom()
}

View File

@@ -86,19 +86,11 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
name: this.translate.instant('Scroll terminal to top'),
},
{
id: 'scroll-page-up',
id: 'scroll-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'),
},
{
@@ -121,4 +113,3 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
return this.hotkeys
}
}

View File

@@ -3,7 +3,7 @@ import { Subject, Observable } from 'rxjs'
import { SessionMiddleware } from '../api/middleware'
const OSCPrefix = Buffer.from('\x1b]')
const OSCSuffixes = [Buffer.from('\x07'), Buffer.from('\x1b\\')]
const OSCSuffix = Buffer.from('\x07')
export class OSCProcessor extends SessionMiddleware {
get cwdReported$ (): Observable<string> { return this.cwdReported }
@@ -14,22 +14,11 @@ export class OSCProcessor extends SessionMiddleware {
feedFromSession (data: Buffer): void {
let startIndex = 0
while (data.includes(OSCPrefix, startIndex)) {
const si = startIndex
if (!OSCSuffixes.some(s => data.includes(s, si))) {
break
}
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()
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
startIndex = data.indexOf(OSCSuffix, startIndex) + OSCSuffix.length
const [oscCodeString, ...oscParams] = oscString.split(';')
const oscCode = parseInt(oscCodeString)

View File

@@ -321,7 +321,16 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@electron/asar@3.2.18", "@electron/asar@^3.2.7":
"@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":
version "3.2.18"
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.18.tgz#fa607f829209bab8b9e0ce6658d3fe81b2cba517"
integrity sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==
@@ -354,6 +363,21 @@
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"
@@ -1476,13 +1500,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.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==
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==
dependencies:
"@develar/schema-utils" "~2.6.5"
"@electron/asar" "3.2.18"
"@electron/asar" "3.2.17"
"@electron/fuses" "^1.8.0"
"@electron/notarize" "2.5.0"
"@electron/osx-sign" "1.3.1"
@@ -1492,7 +1516,7 @@ app-builder-lib@26.0.0-alpha.10:
"@types/fs-extra" "9.0.13"
async-exit-hook "^2.0.1"
bluebird-lst "^1.0.9"
builder-util "26.0.0-alpha.10"
builder-util "26.0.0-alpha.8"
builder-util-runtime "9.3.0-alpha.0"
chromium-pickle-js "^0.2.0"
config-file-ts "0.2.8-rc1"
@@ -1500,7 +1524,7 @@ app-builder-lib@26.0.0-alpha.10:
dotenv "^16.4.5"
dotenv-expand "^11.0.6"
ejs "^3.1.8"
electron-publish "26.0.0-alpha.10"
electron-publish "26.0.0-alpha.8"
fs-extra "^10.1.0"
hosted-git-info "^4.1.0"
is-ci "^3.0.0"
@@ -2030,10 +2054,10 @@ builder-util-runtime@9.3.0-alpha.0:
debug "^4.3.4"
sax "^1.2.4"
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==
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==
dependencies:
"7zip-bin" "~5.2.0"
"@types/debug" "^4.1.6"
@@ -2041,7 +2065,7 @@ builder-util@26.0.0-alpha.10:
bluebird-lst "^1.0.9"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
cross-spawn "^7.0.6"
cross-spawn "^7.0.3"
debug "^4.3.4"
fs-extra "^10.1.0"
http-proxy-agent "^7.0.0"
@@ -2701,7 +2725,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.6:
cross-spawn@^7.0.0:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
@@ -2938,13 +2962,13 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
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==
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==
dependencies:
app-builder-lib "26.0.0-alpha.10"
builder-util "26.0.0-alpha.10"
app-builder-lib "26.0.0-alpha.8"
builder-util "26.0.0-alpha.8"
builder-util-runtime "9.3.0-alpha.0"
fs-extra "^10.1.0"
iconv-lite "^0.6.2"
@@ -3067,16 +3091,16 @@ ejs@^3.1.8:
dependencies:
jake "^10.8.5"
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==
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==
dependencies:
app-builder-lib "26.0.0-alpha.10"
builder-util "26.0.0-alpha.10"
app-builder-lib "26.0.0-alpha.8"
builder-util "26.0.0-alpha.8"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
dmg-builder "26.0.0-alpha.10"
dmg-builder "26.0.0-alpha.8"
fs-extra "^10.1.0"
is-ci "^3.0.0"
lazy-val "^1.0.5"
@@ -3166,13 +3190,13 @@ electron-localshortcut@^3.1.0:
keyboardevent-from-electron-accelerator "^2.0.0"
keyboardevents-areequal "^0.2.1"
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==
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==
dependencies:
"@types/fs-extra" "^9.0.11"
builder-util "26.0.0-alpha.10"
builder-util "26.0.0-alpha.8"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
form-data "^4.0.0"