added an option to reuse private keys stored in the vault

This commit is contained in:
Eugene Pankov 2021-06-28 21:32:12 +02:00
parent 52c37f8988
commit 63355d1a74
No known key found for this signature in database
GPG Key ID: 5896FCBBDD1CF4F4
9 changed files with 72 additions and 21 deletions

View File

@ -25,6 +25,7 @@ export { HomeBaseService } from '../services/homeBase.service'
export { HotkeysService } from '../services/hotkeys.service'
export { NotificationsService } from '../services/notifications.service'
export { ThemesService } from '../services/themes.service'
export { SelectorService } from '../services/selector.service'
export { TabsService } from '../services/tabs.service'
export { UpdaterService } from '../services/updater.service'
export { VaultService, Vault, VaultSecret, VAULT_SECRET_TYPE_FILE } from '../services/vault.service'

View File

@ -2,11 +2,9 @@
import { Observable, Subject, AsyncSubject } from 'rxjs'
import { takeUntil } from 'rxjs/operators'
import { Injectable, Inject } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseTabComponent } from '../components/baseTab.component'
import { SplitTabComponent } from '../components/splitTab.component'
import { SelectorModalComponent } from '../components/selectorModal.component'
import { SelectorOption } from '../api/selector'
import { RecoveryToken } from '../api/tabRecovery'
import { BootstrapData, BOOTSTRAP_DATA } from '../api/mainProcess'
@ -16,6 +14,7 @@ import { HostAppService } from '../api/hostApp'
import { ConfigService } from './config.service'
import { TabRecoveryService } from './tabRecovery.service'
import { TabsService, TabComponentType } from './tabs.service'
import { SelectorService } from './selector.service'
class CompletionObserver {
get done$ (): Observable<void> { return this.done }
@ -77,7 +76,7 @@ export class AppService {
private hostWindow: HostWindowService,
private tabRecovery: TabRecoveryService,
private tabsService: TabsService,
private ngbModal: NgbModal,
private selector: SelectorService,
@Inject(BOOTSTRAP_DATA) private bootstrapData: BootstrapData,
) {
this.tabsChanged$.subscribe(() => {
@ -366,11 +365,8 @@ export class AppService {
this.completionObservers.delete(tab)
}
// Deprecated
showSelector <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>
return this.selector.show(name, options)
}
}

View File

@ -1,11 +1,11 @@
import { Inject, Injectable } from '@angular/core'
import { AppService, FileProvider, NotificationsService } from '../api'
import { FileProvider, NotificationsService, SelectorService } from '../api'
@Injectable({ providedIn: 'root' })
export class FileProvidersService {
/** @hidden */
private constructor (
private app: AppService,
private selector: SelectorService,
private notifications: NotificationsService,
@Inject(FileProvider) private fileProviders: FileProvider[],
) { }
@ -40,7 +40,7 @@ export class FileProvidersService {
if (providers.length === 1) {
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,
result: p,
})))

View 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>
}
}

View File

@ -5,7 +5,8 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { AsyncSubject, Subject, Observable } from 'rxjs'
import { wrapPromise } from '../utils'
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 { PlatformService } from '../api/platform'
@ -226,6 +227,7 @@ export class VaultFileProvider extends FileProvider {
constructor (
private vault: VaultService,
private platform: PlatformService,
private selector: SelectorService,
private zone: NgZone,
) {
super()
@ -236,6 +238,32 @@ export class VaultFileProvider extends FileProvider {
}
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()
if (!transfers.length) {
throw new Error('Nothing selected')

View File

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
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 { TerminalService } from './services/terminal.service'
@ -10,7 +10,7 @@ import { TerminalService } from './services/terminal.service'
export class ButtonProvider extends ToolbarButtonProvider {
constructor (
electron: ElectronService,
private app: AppService,
private selector: SelectorService,
private config: ConfigService,
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[] {

View File

@ -3,6 +3,7 @@ import colors from 'ansi-colors'
import { Spinner } from 'cli-spinner'
import { Component, Injector } from '@angular/core'
import { first } from 'rxjs/operators'
import { SelectorService } from 'terminus-core'
import { BaseTerminalTabComponent } from 'terminus-terminal'
import { SerialService } from '../services/serial.service'
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
constructor (
injector: Injector,
private selector: SelectorService,
) {
super(injector)
this.serialService = injector.get(SerialService)
@ -122,7 +124,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
}
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,
})))
this.serialPort.update({ baudRate: rate })

View File

@ -1,6 +1,6 @@
import { Injectable, NgZone } from '@angular/core'
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 { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api'
import { SerialTabComponent } from '../components/serialTab.component'
@ -12,6 +12,7 @@ export class SerialService {
private zone: NgZone,
private notifications: NotificationsService,
private app: AppService,
private selector: SelectorService,
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> {
@ -170,7 +171,7 @@ export class SerialService {
}
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,
})))
return this.quickConnect(`${port.name}@${rate}`)

View File

@ -5,7 +5,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { Client } from 'ssh2'
import { exec } from 'child_process'
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 { ALGORITHM_BLACKLIST, ForwardedPort, SSHConnection, SSHSession } from '../api'
import { PromptModalComponent } from '../components/promptModal.component'
@ -26,6 +26,7 @@ export class SSHService {
private passwordStorage: PasswordStorageService,
private notifications: NotificationsService,
private app: AppService,
private selector: SelectorService,
private config: ConfigService,
hostApp: HostAppService,
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> {