mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-09 01:51:53 +00:00
added the vault
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
h3.modal-header.m-0.pb-0 Set master passphrase
|
||||
.modal-body
|
||||
.mb-2 You can change it later, but it's unrecoverable if forgotten.
|
||||
.input-group
|
||||
input.form-control.form-control-lg(
|
||||
[type]='showPassphrase ? "text" : "password"',
|
||||
autofocus,
|
||||
[(ngModel)]='passphrase',
|
||||
#input,
|
||||
placeholder='Master passphrase',
|
||||
(keyup.enter)='ok()',
|
||||
(keyup.esc)='cancel()',
|
||||
)
|
||||
.input-group-append
|
||||
button.btn.btn-secondary((click)='showPassphrase = !showPassphrase')
|
||||
i.fas.fa-eye
|
||||
|
||||
.modal-footer
|
||||
button.btn.btn-outline-primary((click)='ok()') Set passphrase
|
||||
button.btn.btn-outline-danger((click)='cancel()') Cancel
|
@@ -0,0 +1,29 @@
|
||||
import { Component, ViewChild, ElementRef } from '@angular/core'
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
/** @hidden */
|
||||
@Component({
|
||||
template: require('./setVaultPassphraseModal.component.pug'),
|
||||
})
|
||||
export class SetVaultPassphraseModalComponent {
|
||||
passphrase: string
|
||||
@ViewChild('input') input: ElementRef
|
||||
|
||||
constructor (
|
||||
private modalInstance: NgbActiveModal,
|
||||
) { }
|
||||
|
||||
ngOnInit (): void {
|
||||
setTimeout(() => {
|
||||
this.input.nativeElement.focus()
|
||||
})
|
||||
}
|
||||
|
||||
ok (): void {
|
||||
this.modalInstance.close(this.passphrase)
|
||||
}
|
||||
|
||||
cancel (): void {
|
||||
this.modalInstance.close(null)
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
.text-center(*ngIf='!vault.enabled')
|
||||
i.fas.fa-key.fa-3x.m-3
|
||||
h3.m-3 Vault is not configured
|
||||
.m-3 Vault is an always-encrypted container for secrets such as SSH passwords and private key passphrases.
|
||||
button.btn.btn-primary.m-2((click)='enableVault()') Set master passphrase
|
||||
|
||||
div(*ngIf='vault.enabled')
|
||||
.d-flex.align-items-center.mb-3
|
||||
h3.m-0 Vault
|
||||
.d-flex.ml-auto(ngbDropdown, *ngIf='vault.enabled')
|
||||
button.btn.btn-secondary(ngbDropdownToggle) Options
|
||||
div(ngbDropdownMenu)
|
||||
a(ngbDropdownItem, (click)='changePassphrase()')
|
||||
i.fas.fa-fw.fa-key
|
||||
span Change the master passphrase
|
||||
a(ngbDropdownItem, (click)='disableVault()')
|
||||
i.fas.fa-fw.fa-radiation-alt
|
||||
span Erase the vault
|
||||
|
||||
div(*ngIf='vaultContents')
|
||||
.text-center(*ngIf='!vaultContents.secrets.length')
|
||||
i.fas.fa-empty-set.fa-3x
|
||||
h3.m-3 Vault is empty
|
||||
|
||||
.list-group
|
||||
.list-group-item.d-flex.align-items-center.p-1.pl-3(*ngFor='let secret of vaultContents.secrets')
|
||||
i.fas.fa-key
|
||||
.mr-auto {{getSecretLabel(secret)}}
|
||||
button.btn.btn-link((click)='removeSecret(secret)')
|
||||
i.fas.fa-trash
|
||||
|
||||
.text-center(*ngIf='!vaultContents')
|
||||
i.fas.fa-key.fa-3x
|
||||
h3.m-3 Vault is locked
|
||||
button.btn.btn-primary.m-2((click)='loadVault()') Show vault contents
|
@@ -0,0 +1,80 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { Component } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { BaseComponent, VaultService, VaultSecret, Vault, PlatformService } from 'terminus-core'
|
||||
import { SetVaultPassphraseModalComponent } from './setVaultPassphraseModal.component'
|
||||
|
||||
|
||||
/** @hidden */
|
||||
@Component({
|
||||
selector: 'vault-settings-tab',
|
||||
template: require('./vaultSettingsTab.component.pug'),
|
||||
})
|
||||
export class VaultSettingsTabComponent extends BaseComponent {
|
||||
vaultContents: Vault|null = null
|
||||
|
||||
constructor (
|
||||
public vault: VaultService,
|
||||
private platform: PlatformService,
|
||||
private ngbModal: NgbModal,
|
||||
) {
|
||||
super()
|
||||
if (vault.isOpen()) {
|
||||
this.loadVault()
|
||||
}
|
||||
}
|
||||
|
||||
async loadVault (): Promise<void> {
|
||||
this.vaultContents = await this.vault.load()
|
||||
}
|
||||
|
||||
async enableVault () {
|
||||
const modal = this.ngbModal.open(SetVaultPassphraseModalComponent)
|
||||
const newPassphrase = await modal.result
|
||||
await this.vault.setEnabled(true, newPassphrase)
|
||||
this.vaultContents = await this.vault.load(newPassphrase)
|
||||
}
|
||||
|
||||
async disableVault () {
|
||||
if ((await this.platform.showMessageBox(
|
||||
{
|
||||
type: 'warning',
|
||||
message: 'Delete vault contents?',
|
||||
buttons: ['Keep', 'Delete'],
|
||||
defaultId: 1,
|
||||
}
|
||||
)).response === 1) {
|
||||
await this.vault.setEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
async changePassphrase () {
|
||||
if (!this.vaultContents) {
|
||||
this.vaultContents = await this.vault.load()
|
||||
}
|
||||
if (!this.vaultContents) {
|
||||
return
|
||||
}
|
||||
const modal = this.ngbModal.open(SetVaultPassphraseModalComponent)
|
||||
const newPassphrase = await modal.result
|
||||
this.vault.save(this.vaultContents, newPassphrase)
|
||||
}
|
||||
|
||||
getSecretLabel (secret: VaultSecret) {
|
||||
if (secret.type === 'ssh:password') {
|
||||
return `SSH password for ${secret.key.user}@${secret.key.host}:${secret.key.port}`
|
||||
}
|
||||
if (secret.type === 'ssh:key-passphrase') {
|
||||
return `Passphrase for a private key with hash ${secret.key.hash.substring(0, 8)}...`
|
||||
}
|
||||
return `Unknown secret of type ${secret.type} for ${JSON.stringify(secret.key)}`
|
||||
}
|
||||
|
||||
removeSecret (secret: VaultSecret) {
|
||||
if (!this.vaultContents) {
|
||||
return
|
||||
}
|
||||
this.vaultContents.secrets = this.vaultContents.secrets.filter(x => x !== secret)
|
||||
this.vault.removeSecret(secret.type, secret.key)
|
||||
}
|
||||
}
|
@@ -11,12 +11,14 @@ import { MultiHotkeyInputComponent } from './components/multiHotkeyInput.compone
|
||||
import { SettingsTabComponent } from './components/settingsTab.component'
|
||||
import { SettingsTabBodyComponent } from './components/settingsTabBody.component'
|
||||
import { WindowSettingsTabComponent } from './components/windowSettingsTab.component'
|
||||
import { VaultSettingsTabComponent } from './components/vaultSettingsTab.component'
|
||||
import { SetVaultPassphraseModalComponent } from './components/setVaultPassphraseModal.component'
|
||||
|
||||
import { SettingsTabProvider } from './api'
|
||||
import { ButtonProvider } from './buttonProvider'
|
||||
import { SettingsHotkeyProvider } from './hotkeys'
|
||||
import { SettingsConfigProvider } from './config'
|
||||
import { HotkeySettingsTabProvider, WindowSettingsTabProvider } from './settings'
|
||||
import { HotkeySettingsTabProvider, WindowSettingsTabProvider, VaultSettingsTabProvider } from './settings'
|
||||
|
||||
/** @hidden */
|
||||
@NgModule({
|
||||
@@ -32,11 +34,14 @@ import { HotkeySettingsTabProvider, WindowSettingsTabProvider } from './settings
|
||||
{ provide: HotkeyProvider, useClass: SettingsHotkeyProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: HotkeySettingsTabProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: WindowSettingsTabProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: VaultSettingsTabProvider, multi: true },
|
||||
],
|
||||
entryComponents: [
|
||||
HotkeyInputModalComponent,
|
||||
HotkeySettingsTabComponent,
|
||||
SettingsTabComponent,
|
||||
SetVaultPassphraseModalComponent,
|
||||
VaultSettingsTabComponent,
|
||||
WindowSettingsTabComponent,
|
||||
],
|
||||
declarations: [
|
||||
@@ -45,6 +50,8 @@ import { HotkeySettingsTabProvider, WindowSettingsTabProvider } from './settings
|
||||
MultiHotkeyInputComponent,
|
||||
SettingsTabComponent,
|
||||
SettingsTabBodyComponent,
|
||||
SetVaultPassphraseModalComponent,
|
||||
VaultSettingsTabComponent,
|
||||
WindowSettingsTabComponent,
|
||||
],
|
||||
})
|
||||
|
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'
|
||||
import { SettingsTabProvider } from './api'
|
||||
import { HotkeySettingsTabComponent } from './components/hotkeySettingsTab.component'
|
||||
import { WindowSettingsTabComponent } from './components/windowSettingsTab.component'
|
||||
import { VaultSettingsTabComponent } from './components/vaultSettingsTab.component'
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
@@ -27,3 +28,16 @@ export class WindowSettingsTabProvider extends SettingsTabProvider {
|
||||
return WindowSettingsTabComponent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
export class VaultSettingsTabProvider extends SettingsTabProvider {
|
||||
id = 'vault'
|
||||
icon = 'key'
|
||||
title = 'Vault'
|
||||
|
||||
getComponentType (): any {
|
||||
return VaultSettingsTabComponent
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user