mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-14 04:14:36 +00:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4efcf1bbd6 | ||
![]() |
abea964d94 | ||
![]() |
2e7b66ac60 | ||
![]() |
c4a514fc4a | ||
![]() |
d525374061 | ||
![]() |
6db08b765f | ||
![]() |
d8d346c507 | ||
![]() |
6ffeb61c9c | ||
![]() |
92c729dada | ||
![]() |
302f88058c | ||
![]() |
66c173b1b5 | ||
![]() |
f9dadf0816 |
20
.github/workflows/build.yml
vendored
20
.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)
|
||||
|
@@ -144,7 +144,7 @@ Plugins and themes can be installed directly from the Settings view inside Tabby
|
||||
|
||||
# Sponsors <!-- omit in toc -->
|
||||
|
||||
[](https://packagecloud.io)
|
||||
<a href="https://packagecloud.io"><img src="https://assets-production.packagecloud.io/assets/logo_v1-d5895e7b89b2dee19030e85515fd0f91d8f3b37c82d218a6531fc89c2b1b613c.png" width="200"></a>
|
||||
|
||||
[**packagecloud**](https://packagecloud.io) has provided free Debian/RPM repository hosting
|
||||
|
||||
@@ -152,7 +152,7 @@ Plugins and themes can be installed directly from the Settings view inside Tabby
|
||||
|
||||
[**keygen**](https://keygen.sh/?via=eugene) has provided free release & auto-update hosting
|
||||
|
||||
<a href="https://iqhive.com/"><img src="https://private-user-images.githubusercontent.com/161476/361584584-ed292436-1d50-46bc-b479-78222c83ed22.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ3MDg3NjgsIm5iZiI6MTcyNDcwODQ2OCwicGF0aCI6Ii8xNjE0NzYvMzYxNTg0NTg0LWVkMjkyNDM2LTFkNTAtNDZiYy1iNDc5LTc4MjIyYzgzZWQyMi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwODI2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDgyNlQyMTQxMDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1iYzNlZjIxN2JiYzBkYTU5NGE4YmZlZDJiNmIxZWE1ZTAyOTNhYjJlZTRhOGZjYTk4N2E4MzMzZjg0ZTNkZWQ0JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.pQzR2d71YV4TIxOH3Lg20HpNKrm_r2D-xfkEM_F2DTs" width="100"></a>
|
||||
<a href="https://iqhive.com/"><img src="https://iqhive.com/img/icons/logo.svg" width="200"></a>
|
||||
|
||||
[**IQ Hive**](https://iqhive.com) is providing financial support for the project development
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as glasstron from 'glasstron'
|
||||
import { autoUpdater } from 'electron-updater'
|
||||
import { Subject, Observable, debounceTime } from 'rxjs'
|
||||
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowConstructorOptions, TouchBar, nativeImage, WebContents } from 'electron'
|
||||
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowConstructorOptions, TouchBar, nativeImage, WebContents, nativeTheme } from 'electron'
|
||||
import ElectronConfig = require('electron-config')
|
||||
import { enable as enableRemote } from '@electron/remote/main'
|
||||
import * as os from 'os'
|
||||
@@ -100,6 +100,10 @@ export class Window {
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
bwOptions.visualEffectState = 'active'
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
this.window = new BrowserWindow(bwOptions) as GlasstronWindow
|
||||
} else {
|
||||
@@ -115,6 +119,8 @@ export class Window {
|
||||
this.setVibrancy(true)
|
||||
}
|
||||
|
||||
this.setDarkMode(this.configStore.appearance?.colorSchemeMode ?? 'dark')
|
||||
|
||||
if (!options.hidden) {
|
||||
if (maximized) {
|
||||
this.window.maximize()
|
||||
@@ -201,6 +207,18 @@ export class Window {
|
||||
}
|
||||
}
|
||||
|
||||
setDarkMode (mode: string): void {
|
||||
if (process.platform === 'darwin') {
|
||||
if ('light' === mode ) {
|
||||
nativeTheme.themeSource = 'light'
|
||||
} else if ('auto' === mode) {
|
||||
nativeTheme.themeSource = 'system'
|
||||
} else {
|
||||
nativeTheme.themeSource = 'dark'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
focus (): void {
|
||||
this.window.focus()
|
||||
}
|
||||
@@ -373,6 +391,10 @@ export class Window {
|
||||
this.setVibrancy(enabled, type)
|
||||
})
|
||||
|
||||
this.on('window-set-dark-mode', (_, mode) => {
|
||||
this.setDarkMode(mode)
|
||||
})
|
||||
|
||||
this.on('window-set-window-controls-color', (_, theme) => {
|
||||
if (process.platform === 'win32') {
|
||||
const symbolColor: string = theme.foreground
|
||||
|
@@ -30,7 +30,7 @@
|
||||
"native-process-working-directory": "^1.0.2",
|
||||
"npm": "6",
|
||||
"rxjs": "^7.5.7",
|
||||
"russh": "0.1.11",
|
||||
"russh": "0.1.14",
|
||||
"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.11:
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.11.tgz#22e74f93ec1cb045930c85f8ba1daf2e5efcae4b"
|
||||
integrity sha512-3CuI+rMoGpnnFDJxsEmcHYRSHInf3bz3fbgeyPnX8n1wgsX6wdbyI1DKL188oQlsrFWEjO3/7ebbYliCi0Qz7w==
|
||||
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"
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core'
|
||||
import { TerminalColorSchemeProvider } from 'tabby-terminal'
|
||||
import { TerminalColorSchemeProvider, TerminalDecorator } from 'tabby-terminal'
|
||||
import { SFTPContextMenuItemProvider, SSHProfileImporter, AutoPrivateKeyLocator } from 'tabby-ssh'
|
||||
import { PTYInterface, ShellProvider, UACService } from 'tabby-local'
|
||||
import { auditTime } from 'rxjs'
|
||||
@@ -23,6 +23,7 @@ import { ElectronConfigProvider } from './config'
|
||||
import { EditSFTPContextMenu } from './sftpContextMenu'
|
||||
import { OpenSSHImporter, PrivateKeyLocator, StaticFileImporter } from './sshImporters'
|
||||
import { ElectronPTYInterface } from './pty'
|
||||
import { PathDropDecorator } from './pathDrop'
|
||||
|
||||
import { CmderShellProvider } from './shells/cmder'
|
||||
import { Cygwin32ShellProvider } from './shells/cygwin32'
|
||||
@@ -73,6 +74,8 @@ import { VSDevToolsProvider } from './shells/vs'
|
||||
|
||||
{ provide: PTYInterface, useClass: ElectronPTYInterface },
|
||||
|
||||
{ provide: TerminalDecorator, useClass: PathDropDecorator, multi: true },
|
||||
|
||||
// For WindowsDefaultShellProvider
|
||||
PowerShellCoreShellProvider,
|
||||
WSLShellProvider,
|
||||
@@ -130,7 +133,10 @@ export default class ElectronModule {
|
||||
})
|
||||
})
|
||||
|
||||
config.changed$.subscribe(() => this.updateVibrancy())
|
||||
config.changed$.subscribe(() => {
|
||||
this.updateVibrancy()
|
||||
this.updateDarkMode()
|
||||
})
|
||||
|
||||
config.changed$.subscribe(() => this.updateWindowControlsColor())
|
||||
|
||||
@@ -173,6 +179,11 @@ export default class ElectronModule {
|
||||
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
||||
}
|
||||
|
||||
private updateDarkMode () {
|
||||
const colorSchemeMode = this.config.store.appearance.colorSchemeMode
|
||||
this.electron.ipcRenderer.send('window-set-dark-mode', colorSchemeMode)
|
||||
}
|
||||
|
||||
private updateWindowControlsColor () {
|
||||
// if windows and not using native frame, WCO does not exist, return.
|
||||
if (this.hostApp.platform === Platform.Windows && this.config.store.appearance.frame === 'native') {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { TerminalDecorator } from '../api/decorator'
|
||||
import { BaseTerminalTabComponent } from '../api/baseTerminalTab.component'
|
||||
import { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'
|
||||
import { webUtils } from 'electron'
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
@@ -11,8 +11,8 @@ export class PathDropDecorator extends TerminalDecorator {
|
||||
event.preventDefault()
|
||||
}))
|
||||
this.subscribeUntilDetached(terminal, terminal.frontend?.drop$.subscribe((event: DragEvent) => {
|
||||
for (const file of event.dataTransfer!.files as any) {
|
||||
this.injectPath(terminal, file.path)
|
||||
for (const file of event.dataTransfer!.files as unknown as Iterable<File>) {
|
||||
this.injectPath(terminal, webUtils.getPathForFile(file))
|
||||
}
|
||||
event.preventDefault()
|
||||
}))
|
@@ -50,6 +50,18 @@ type AuthMethod = {
|
||||
kind: 'pageant',
|
||||
}
|
||||
|
||||
function sshAuthTypeForMethod (m: AuthMethod): string {
|
||||
switch (m.type) {
|
||||
case 'none': return 'none'
|
||||
case 'hostbased': return 'hostbased'
|
||||
case 'prompt-password': return 'password'
|
||||
case 'saved-password': return 'password'
|
||||
case 'keyboard-interactive': return 'keyboard-interactive'
|
||||
case 'publickey': return 'publickey'
|
||||
case 'agent': return 'publickey'
|
||||
}
|
||||
}
|
||||
|
||||
export class KeyboardInteractivePrompt {
|
||||
readonly responses: string[] = []
|
||||
|
||||
@@ -181,6 +193,13 @@ export class SSHSession {
|
||||
})
|
||||
}
|
||||
}
|
||||
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 })
|
||||
@@ -191,13 +210,6 @@ export class SSHSession {
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'prompt-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.remainingAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'keyboard-interactive' })
|
||||
}
|
||||
this.remainingAuthMethods.push({ type: 'hostbased' })
|
||||
}
|
||||
|
||||
@@ -495,7 +507,7 @@ export class SSHSession {
|
||||
this.keyboardInteractivePrompt.next(prompt)
|
||||
}
|
||||
|
||||
async handleAuth (methodsLeft?: string[] | null): Promise<russh.AuthenticatedSSHClient|null> {
|
||||
async handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
||||
this.activePrivateKey = null
|
||||
|
||||
if (!(this.ssh instanceof russh.SSHClient)) {
|
||||
@@ -506,22 +518,36 @@ export class SSHSession {
|
||||
throw new Error('No username')
|
||||
}
|
||||
|
||||
const noneResult = await this.ssh.authenticateNone(this.authUsername)
|
||||
if (noneResult instanceof russh.AuthenticatedSSHClient) {
|
||||
return noneResult
|
||||
}
|
||||
|
||||
let methodsLeft = noneResult.remainingMethods
|
||||
|
||||
function maybeSetRemainingMethods (r: russh.AuthFailure) {
|
||||
if (r.remainingMethods.length) {
|
||||
methodsLeft = r.remainingMethods
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const method = this.remainingAuthMethods.shift()
|
||||
const m = methodsLeft
|
||||
const method = this.remainingAuthMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
|
||||
|
||||
if (!method) {
|
||||
return null
|
||||
}
|
||||
if (methodsLeft && !methodsLeft.includes(method.type) && method.type !== 'agent') {
|
||||
// Agent can still be used even if not in methodsLeft
|
||||
this.logger.info('Server does not support auth method', method.type)
|
||||
continue
|
||||
}
|
||||
|
||||
this.remainingAuthMethods = this.remainingAuthMethods.filter(x => x !== method)
|
||||
|
||||
if (method.type === 'saved-password') {
|
||||
this.emitServiceMessage(this.translate.instant('Using saved password'))
|
||||
const result = await this.ssh.authenticateWithPassword(this.authUsername, method.password)
|
||||
if (result instanceof russh.AuthenticatedSSHClient) {
|
||||
return result
|
||||
}
|
||||
maybeSetRemainingMethods(result)
|
||||
}
|
||||
if (method.type === 'prompt-password') {
|
||||
const modal = this.ngbModal.open(PromptModalComponent)
|
||||
@@ -539,6 +565,7 @@ export class SSHSession {
|
||||
if (result instanceof russh.AuthenticatedSSHClient) {
|
||||
return result
|
||||
}
|
||||
maybeSetRemainingMethods(result)
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
@@ -556,6 +583,7 @@ export class SSHSession {
|
||||
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}`)
|
||||
@@ -567,6 +595,7 @@ export class SSHSession {
|
||||
|
||||
while (true) {
|
||||
if (state.state === 'failure') {
|
||||
maybeSetRemainingMethods(state)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -602,7 +631,7 @@ export class SSHSession {
|
||||
}
|
||||
}
|
||||
|
||||
state = await this.ssh .continueKeyboardInteractiveAuthentication(responses)
|
||||
state = await this.ssh.continueKeyboardInteractiveAuthentication(responses)
|
||||
|
||||
if (state instanceof russh.AuthenticatedSSHClient) {
|
||||
return state
|
||||
@@ -615,6 +644,7 @@ export class SSHSession {
|
||||
if (result instanceof russh.AuthenticatedSSHClient) {
|
||||
return result
|
||||
}
|
||||
maybeSetRemainingMethods(result)
|
||||
} catch (e) {
|
||||
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Failed to authenticate using agent: ${e}`)
|
||||
continue
|
||||
|
@@ -26,7 +26,6 @@ import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
|
||||
import { TerminalColorSchemeProvider } from './api/colorSchemeProvider'
|
||||
import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ColorSchemeSettingsTabProvider } from './settings'
|
||||
import { DebugDecorator } from './features/debug'
|
||||
import { PathDropDecorator } from './features/pathDrop'
|
||||
import { ZModemDecorator } from './features/zmodem'
|
||||
import { TerminalConfigProvider } from './config'
|
||||
import { TerminalHotkeyProvider } from './hotkeys'
|
||||
@@ -54,7 +53,6 @@ import { DefaultColorSchemes } from './colorSchemes'
|
||||
|
||||
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
|
||||
{ provide: HotkeyProvider, useClass: TerminalHotkeyProvider, multi: true },
|
||||
{ provide: TerminalDecorator, useClass: PathDropDecorator, multi: true },
|
||||
{ provide: TerminalDecorator, useClass: ZModemDecorator, multi: true },
|
||||
{ provide: TerminalDecorator, useClass: DebugDecorator, multi: true },
|
||||
|
||||
|
Reference in New Issue
Block a user