mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-09 05:50:08 +00:00
added an option to reuse private keys stored in the vault
This commit is contained in:
parent
52c37f8988
commit
63355d1a74
@ -25,6 +25,7 @@ export { HomeBaseService } from '../services/homeBase.service'
|
|||||||
export { HotkeysService } from '../services/hotkeys.service'
|
export { HotkeysService } from '../services/hotkeys.service'
|
||||||
export { NotificationsService } from '../services/notifications.service'
|
export { NotificationsService } from '../services/notifications.service'
|
||||||
export { ThemesService } from '../services/themes.service'
|
export { ThemesService } from '../services/themes.service'
|
||||||
|
export { SelectorService } from '../services/selector.service'
|
||||||
export { TabsService } from '../services/tabs.service'
|
export { TabsService } from '../services/tabs.service'
|
||||||
export { UpdaterService } from '../services/updater.service'
|
export { UpdaterService } from '../services/updater.service'
|
||||||
export { VaultService, Vault, VaultSecret, VAULT_SECRET_TYPE_FILE } from '../services/vault.service'
|
export { VaultService, Vault, VaultSecret, VAULT_SECRET_TYPE_FILE } from '../services/vault.service'
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
import { Observable, Subject, AsyncSubject } from 'rxjs'
|
import { Observable, Subject, AsyncSubject } from 'rxjs'
|
||||||
import { takeUntil } from 'rxjs/operators'
|
import { takeUntil } from 'rxjs/operators'
|
||||||
import { Injectable, Inject } from '@angular/core'
|
import { Injectable, Inject } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
|
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { SplitTabComponent } from '../components/splitTab.component'
|
import { SplitTabComponent } from '../components/splitTab.component'
|
||||||
import { SelectorModalComponent } from '../components/selectorModal.component'
|
|
||||||
import { SelectorOption } from '../api/selector'
|
import { SelectorOption } from '../api/selector'
|
||||||
import { RecoveryToken } from '../api/tabRecovery'
|
import { RecoveryToken } from '../api/tabRecovery'
|
||||||
import { BootstrapData, BOOTSTRAP_DATA } from '../api/mainProcess'
|
import { BootstrapData, BOOTSTRAP_DATA } from '../api/mainProcess'
|
||||||
@ -16,6 +14,7 @@ import { HostAppService } from '../api/hostApp'
|
|||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { TabRecoveryService } from './tabRecovery.service'
|
import { TabRecoveryService } from './tabRecovery.service'
|
||||||
import { TabsService, TabComponentType } from './tabs.service'
|
import { TabsService, TabComponentType } from './tabs.service'
|
||||||
|
import { SelectorService } from './selector.service'
|
||||||
|
|
||||||
class CompletionObserver {
|
class CompletionObserver {
|
||||||
get done$ (): Observable<void> { return this.done }
|
get done$ (): Observable<void> { return this.done }
|
||||||
@ -77,7 +76,7 @@ export class AppService {
|
|||||||
private hostWindow: HostWindowService,
|
private hostWindow: HostWindowService,
|
||||||
private tabRecovery: TabRecoveryService,
|
private tabRecovery: TabRecoveryService,
|
||||||
private tabsService: TabsService,
|
private tabsService: TabsService,
|
||||||
private ngbModal: NgbModal,
|
private selector: SelectorService,
|
||||||
@Inject(BOOTSTRAP_DATA) private bootstrapData: BootstrapData,
|
@Inject(BOOTSTRAP_DATA) private bootstrapData: BootstrapData,
|
||||||
) {
|
) {
|
||||||
this.tabsChanged$.subscribe(() => {
|
this.tabsChanged$.subscribe(() => {
|
||||||
@ -366,11 +365,8 @@ export class AppService {
|
|||||||
this.completionObservers.delete(tab)
|
this.completionObservers.delete(tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
showSelector <T> (name: string, options: SelectorOption<T>[]): Promise<T> {
|
showSelector <T> (name: string, options: SelectorOption<T>[]): Promise<T> {
|
||||||
const modal = this.ngbModal.open(SelectorModalComponent)
|
return this.selector.show(name, options)
|
||||||
const instance: SelectorModalComponent<T> = modal.componentInstance
|
|
||||||
instance.name = name
|
|
||||||
instance.options = options
|
|
||||||
return modal.result as Promise<T>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Inject, Injectable } from '@angular/core'
|
import { Inject, Injectable } from '@angular/core'
|
||||||
import { AppService, FileProvider, NotificationsService } from '../api'
|
import { FileProvider, NotificationsService, SelectorService } from '../api'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class FileProvidersService {
|
export class FileProvidersService {
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
private constructor (
|
private constructor (
|
||||||
private app: AppService,
|
private selector: SelectorService,
|
||||||
private notifications: NotificationsService,
|
private notifications: NotificationsService,
|
||||||
@Inject(FileProvider) private fileProviders: FileProvider[],
|
@Inject(FileProvider) private fileProviders: FileProvider[],
|
||||||
) { }
|
) { }
|
||||||
@ -40,7 +40,7 @@ export class FileProvidersService {
|
|||||||
if (providers.length === 1) {
|
if (providers.length === 1) {
|
||||||
return providers[0]
|
return providers[0]
|
||||||
}
|
}
|
||||||
return this.app.showSelector('Select file storage', providers.map(p => ({
|
return this.selector.show('Select file storage', providers.map(p => ({
|
||||||
name: p.name,
|
name: p.name,
|
||||||
result: p,
|
result: p,
|
||||||
})))
|
})))
|
||||||
|
22
terminus-core/src/services/selector.service.ts
Normal file
22
terminus-core/src/services/selector.service.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
|
||||||
|
import { SelectorModalComponent } from '../components/selectorModal.component'
|
||||||
|
import { SelectorOption } from '../api/selector'
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class SelectorService {
|
||||||
|
/** @hidden */
|
||||||
|
private constructor (
|
||||||
|
private ngbModal: NgbModal,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
show <T> (name: string, options: SelectorOption<T>[]): Promise<T> {
|
||||||
|
const modal = this.ngbModal.open(SelectorModalComponent)
|
||||||
|
const instance: SelectorModalComponent<T> = modal.componentInstance
|
||||||
|
instance.name = name
|
||||||
|
instance.options = options
|
||||||
|
return modal.result as Promise<T>
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,8 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
|||||||
import { AsyncSubject, Subject, Observable } from 'rxjs'
|
import { AsyncSubject, Subject, Observable } from 'rxjs'
|
||||||
import { wrapPromise } from '../utils'
|
import { wrapPromise } from '../utils'
|
||||||
import { UnlockVaultModalComponent } from '../components/unlockVaultModal.component'
|
import { UnlockVaultModalComponent } from '../components/unlockVaultModal.component'
|
||||||
import { NotificationsService } from '../services/notifications.service'
|
import { NotificationsService } from './notifications.service'
|
||||||
|
import { SelectorService } from './selector.service'
|
||||||
import { FileProvider } from '../api/fileProvider'
|
import { FileProvider } from '../api/fileProvider'
|
||||||
import { PlatformService } from '../api/platform'
|
import { PlatformService } from '../api/platform'
|
||||||
|
|
||||||
@ -226,6 +227,7 @@ export class VaultFileProvider extends FileProvider {
|
|||||||
constructor (
|
constructor (
|
||||||
private vault: VaultService,
|
private vault: VaultService,
|
||||||
private platform: PlatformService,
|
private platform: PlatformService,
|
||||||
|
private selector: SelectorService,
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@ -236,6 +238,32 @@ export class VaultFileProvider extends FileProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async selectAndStoreFile (description: string): Promise<string> {
|
async selectAndStoreFile (description: string): Promise<string> {
|
||||||
|
const vault = await this.vault.load()
|
||||||
|
if (!vault) {
|
||||||
|
throw new Error('Vault is locked')
|
||||||
|
}
|
||||||
|
const files = vault.secrets.filter(x => x.type === VAULT_SECRET_TYPE_FILE)
|
||||||
|
if (files.length) {
|
||||||
|
const result = await this.selector.show<VaultSecret|null>('Select file', [
|
||||||
|
{
|
||||||
|
name: 'Add a new file',
|
||||||
|
icon: 'plus',
|
||||||
|
result: null,
|
||||||
|
},
|
||||||
|
...files.map(f => ({
|
||||||
|
name: f.key.description,
|
||||||
|
icon: 'file',
|
||||||
|
result: f,
|
||||||
|
})),
|
||||||
|
])
|
||||||
|
if (result) {
|
||||||
|
return `${this.prefix}${result.key.id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.addNewFile(description)
|
||||||
|
}
|
||||||
|
|
||||||
|
async addNewFile (description: string): Promise<string> {
|
||||||
const transfers = await this.platform.startUpload()
|
const transfers = await this.platform.startUpload()
|
||||||
if (!transfers.length) {
|
if (!transfers.length) {
|
||||||
throw new Error('Nothing selected')
|
throw new Error('Nothing selected')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { ToolbarButtonProvider, ToolbarButton, ConfigService, SelectorOption, AppService } from 'terminus-core'
|
import { ToolbarButtonProvider, ToolbarButton, ConfigService, SelectorOption, SelectorService } from 'terminus-core'
|
||||||
import { ElectronService } from 'terminus-electron'
|
import { ElectronService } from 'terminus-electron'
|
||||||
|
|
||||||
import { TerminalService } from './services/terminal.service'
|
import { TerminalService } from './services/terminal.service'
|
||||||
@ -10,7 +10,7 @@ import { TerminalService } from './services/terminal.service'
|
|||||||
export class ButtonProvider extends ToolbarButtonProvider {
|
export class ButtonProvider extends ToolbarButtonProvider {
|
||||||
constructor (
|
constructor (
|
||||||
electron: ElectronService,
|
electron: ElectronService,
|
||||||
private app: AppService,
|
private selector: SelectorService,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
private terminal: TerminalService,
|
private terminal: TerminalService,
|
||||||
) {
|
) {
|
||||||
@ -29,7 +29,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.app.showSelector('Select profile', options)
|
await this.selector.show('Select profile', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
provide (): ToolbarButton[] {
|
provide (): ToolbarButton[] {
|
||||||
|
@ -3,6 +3,7 @@ import colors from 'ansi-colors'
|
|||||||
import { Spinner } from 'cli-spinner'
|
import { Spinner } from 'cli-spinner'
|
||||||
import { Component, Injector } from '@angular/core'
|
import { Component, Injector } from '@angular/core'
|
||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
|
import { SelectorService } from 'terminus-core'
|
||||||
import { BaseTerminalTabComponent } from 'terminus-terminal'
|
import { BaseTerminalTabComponent } from 'terminus-terminal'
|
||||||
import { SerialService } from '../services/serial.service'
|
import { SerialService } from '../services/serial.service'
|
||||||
import { SerialConnection, SerialSession, BAUD_RATES } from '../api'
|
import { SerialConnection, SerialSession, BAUD_RATES } from '../api'
|
||||||
@ -23,6 +24,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||||
constructor (
|
constructor (
|
||||||
injector: Injector,
|
injector: Injector,
|
||||||
|
private selector: SelectorService,
|
||||||
) {
|
) {
|
||||||
super(injector)
|
super(injector)
|
||||||
this.serialService = injector.get(SerialService)
|
this.serialService = injector.get(SerialService)
|
||||||
@ -122,7 +124,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async changeBaudRate () {
|
async changeBaudRate () {
|
||||||
const rate = await this.app.showSelector('Baud rate', BAUD_RATES.map(x => ({
|
const rate = await this.selector.show('Baud rate', BAUD_RATES.map(x => ({
|
||||||
name: x.toString(), result: x,
|
name: x.toString(), result: x,
|
||||||
})))
|
})))
|
||||||
this.serialPort.update({ baudRate: rate })
|
this.serialPort.update({ baudRate: rate })
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import SerialPort from 'serialport'
|
import SerialPort from 'serialport'
|
||||||
import { LogService, AppService, SelectorOption, ConfigService, NotificationsService } from 'terminus-core'
|
import { LogService, AppService, SelectorOption, ConfigService, NotificationsService, SelectorService } from 'terminus-core'
|
||||||
import { SettingsTabComponent } from 'terminus-settings'
|
import { SettingsTabComponent } from 'terminus-settings'
|
||||||
import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api'
|
import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api'
|
||||||
import { SerialTabComponent } from '../components/serialTab.component'
|
import { SerialTabComponent } from '../components/serialTab.component'
|
||||||
@ -12,6 +12,7 @@ export class SerialService {
|
|||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private notifications: NotificationsService,
|
private notifications: NotificationsService,
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
|
private selector: SelectorService,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ export class SerialService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
await this.app.showSelector('Open a serial port', options)
|
await this.selector.show('Open a serial port', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect (connection: SerialConnection): Promise<SerialTabComponent> {
|
async connect (connection: SerialConnection): Promise<SerialTabComponent> {
|
||||||
@ -170,7 +171,7 @@ export class SerialService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async connectFoundPort (port: SerialPortInfo): Promise<SerialTabComponent> {
|
async connectFoundPort (port: SerialPortInfo): Promise<SerialTabComponent> {
|
||||||
const rate = await this.app.showSelector('Baud rate', BAUD_RATES.map(x => ({
|
const rate = await this.selector.show('Baud rate', BAUD_RATES.map(x => ({
|
||||||
name: x.toString(), result: x,
|
name: x.toString(), result: x,
|
||||||
})))
|
})))
|
||||||
return this.quickConnect(`${port.name}@${rate}`)
|
return this.quickConnect(`${port.name}@${rate}`)
|
||||||
|
@ -5,7 +5,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
|||||||
import { Client } from 'ssh2'
|
import { Client } from 'ssh2'
|
||||||
import { exec } from 'child_process'
|
import { exec } from 'child_process'
|
||||||
import { Subject, Observable } from 'rxjs'
|
import { Subject, Observable } from 'rxjs'
|
||||||
import { Logger, LogService, AppService, SelectorOption, ConfigService, NotificationsService, HostAppService, Platform, PlatformService } from 'terminus-core'
|
import { Logger, LogService, AppService, SelectorOption, ConfigService, NotificationsService, HostAppService, Platform, PlatformService, SelectorService } from 'terminus-core'
|
||||||
import { SettingsTabComponent } from 'terminus-settings'
|
import { SettingsTabComponent } from 'terminus-settings'
|
||||||
import { ALGORITHM_BLACKLIST, ForwardedPort, SSHConnection, SSHSession } from '../api'
|
import { ALGORITHM_BLACKLIST, ForwardedPort, SSHConnection, SSHSession } from '../api'
|
||||||
import { PromptModalComponent } from '../components/promptModal.component'
|
import { PromptModalComponent } from '../components/promptModal.component'
|
||||||
@ -26,6 +26,7 @@ export class SSHService {
|
|||||||
private passwordStorage: PasswordStorageService,
|
private passwordStorage: PasswordStorageService,
|
||||||
private notifications: NotificationsService,
|
private notifications: NotificationsService,
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
|
private selector: SelectorService,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
hostApp: HostAppService,
|
hostApp: HostAppService,
|
||||||
private platform: PlatformService,
|
private platform: PlatformService,
|
||||||
@ -230,7 +231,7 @@ export class SSHService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
await this.app.showSelector('Open an SSH connection', options)
|
await this.selector.show('Open an SSH connection', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect (connection: SSHConnection): Promise<SSHTabComponent> {
|
async connect (connection: SSHConnection): Promise<SSHTabComponent> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user