Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Tabby
提交
67bbbd7f
T
Tabby
项目概览
后端镜像
/
Tabby
通知
37
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Tabby
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
67bbbd7f
编写于
7月 10, 2021
作者:
E
Eugene Pankov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
allow renaming and replacing files in the vault - fixes #4110
上级
0008b2f0
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
109 addition
and
8 deletion
+109
-8
app/src/global.scss
app/src/global.scss
+2
-1
tabby-core/src/api/index.ts
tabby-core/src/api/index.ts
+1
-1
tabby-core/src/services/vault.service.ts
tabby-core/src/services/vault.service.ts
+27
-2
tabby-local/src/tabContextMenu.ts
tabby-local/src/tabContextMenu.ts
+1
-1
tabby-settings/src/components/vaultSettingsTab.component.pug
tabby-settings/src/components/vaultSettingsTab.component.pug
+29
-2
tabby-settings/src/components/vaultSettingsTab.component.ts
tabby-settings/src/components/vaultSettingsTab.component.ts
+49
-1
未找到文件。
app/src/global.scss
浏览文件 @
67bbbd7f
...
...
@@ -115,7 +115,8 @@ ngb-typeahead-window {
.hover-reveal-parent
:hover
&
,
*
:hover
>
&
,
&
:hover
{
&
:hover
,
&
.show
{
opacity
:
1
;
}
}
...
...
tabby-core/src/api/index.ts
浏览文件 @
67bbbd7f
...
...
@@ -31,6 +31,6 @@ export { ProfilesService } from '../services/profiles.service'
export
{
SelectorService
}
from
'
../services/selector.service
'
export
{
TabsService
,
NewTabParameters
,
TabComponentType
}
from
'
../services/tabs.service
'
export
{
UpdaterService
}
from
'
../services/updater.service
'
export
{
VaultService
,
Vault
,
VaultSecret
,
VAULT_SECRET_TYPE_FILE
}
from
'
../services/vault.service
'
export
{
VaultService
,
Vault
,
VaultSecret
,
V
aultFileSecret
,
V
AULT_SECRET_TYPE_FILE
}
from
'
../services/vault.service
'
export
{
FileProvidersService
}
from
'
../services/fileProviders.service
'
export
*
from
'
../utils
'
tabby-core/src/services/vault.service.ts
浏览文件 @
67bbbd7f
...
...
@@ -30,6 +30,13 @@ export interface VaultSecret {
value
:
string
}
export
interface
VaultFileSecret
extends
VaultSecret
{
key
:
{
id
:
string
description
:
string
}
}
export
interface
Vault
{
config
:
any
secrets
:
VaultSecret
[]
...
...
@@ -121,6 +128,10 @@ export class VaultService {
return
!!
_rememberedPassphrase
}
forgetPassphrase
():
void
{
_rememberedPassphrase
=
null
}
async
decrypt
(
storage
:
StoredVault
,
passphrase
?:
string
):
Promise
<
Vault
>
{
if
(
!
passphrase
)
{
passphrase
=
await
this
.
getPassphrase
()
...
...
@@ -128,7 +139,7 @@ export class VaultService {
try
{
return
await
wrapPromise
(
this
.
zone
,
decryptVault
(
storage
,
passphrase
))
}
catch
(
e
)
{
_rememberedPassphrase
=
null
this
.
forgetPassphrase
()
if
(
e
.
toString
().
includes
(
'
BAD_DECRYPT
'
))
{
this
.
notifications
.
error
(
'
Incorrect passphrase
'
)
}
...
...
@@ -193,6 +204,20 @@ export class VaultService {
await
this
.
save
(
vault
)
}
async
updateSecret
(
secret
:
VaultSecret
,
update
:
VaultSecret
):
Promise
<
void
>
{
await
this
.
ready$
.
toPromise
()
const
vault
=
await
this
.
load
()
if
(
!
vault
)
{
return
}
const
target
=
vault
.
secrets
.
find
(
s
=>
s
.
type
===
secret
.
type
&&
this
.
keyMatches
(
secret
.
key
,
s
))
if
(
!
target
)
{
return
}
Object
.
assign
(
target
,
update
)
await
this
.
save
(
vault
)
}
async
removeSecret
(
type
:
string
,
key
:
Record
<
string
,
any
>
):
Promise
<
void
>
{
await
this
.
ready$
.
toPromise
()
const
vault
=
await
this
.
load
()
...
...
@@ -274,7 +299,7 @@ export class VaultFileProvider extends FileProvider {
type
:
VAULT_SECRET_TYPE_FILE
,
key
:
{
id
,
description
,
description
:
`
${
description
}
(
${
transfer
.
getName
()}
)`
,
},
value
:
(
await
transfer
.
readAll
()).
toString
(
'
base64
'
),
})
...
...
tabby-local/src/tabContextMenu.ts
浏览文件 @
67bbbd7f
...
...
@@ -27,7 +27,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
click
:
async
()
=>
{
const
modal
=
this
.
ngbModal
.
open
(
PromptModalComponent
)
modal
.
componentInstance
.
prompt
=
'
New profile name
'
const
name
=
(
await
modal
.
result
)?.
nam
e
const
name
=
(
await
modal
.
result
)?.
valu
e
if
(
!
name
)
{
return
}
...
...
tabby-settings/src/components/vaultSettingsTab.component.pug
浏览文件 @
67bbbd7f
...
...
@@ -27,8 +27,35 @@ div(*ngIf='vault.isEnabled()')
.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
.hover-reveal(ngbDropdown)
button.btn.btn-link(ngbDropdownToggle)
i.fas.fa-ellipsis-v
div(ngbDropdownMenu)
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',
(click)='renameFile(secret)'
)
i.fas.fa-fw.fa-pencil-alt
span Rename
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',
(click)='replaceFileContent(secret)'
)
i.fas.fa-fw.fa-file-import
span Replace
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',
(click)='exportFile(secret)'
)
i.fas.fa-fw.fa-file-export
span Export
button(ngbDropdownItem, (click)='removeSecret(secret)')
i.fas.fa-fw.fa-trash
span Delete
h3.mt-5 Options
.form-line
...
...
tabby-settings/src/components/vaultSettingsTab.component.ts
浏览文件 @
67bbbd7f
/* 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
,
ConfigService
,
VAULT_SECRET_TYPE_FILE
}
from
'
tabby-core
'
import
{
BaseComponent
,
VaultService
,
VaultSecret
,
Vault
,
PlatformService
,
ConfigService
,
VAULT_SECRET_TYPE_FILE
,
PromptModalComponent
,
VaultFileSecret
}
from
'
tabby-core
'
import
{
SetVaultPassphraseModalComponent
}
from
'
./setVaultPassphraseModal.component
'
...
...
@@ -12,6 +12,7 @@ import { SetVaultPassphraseModalComponent } from './setVaultPassphraseModal.comp
})
export
class
VaultSettingsTabComponent
extends
BaseComponent
{
vaultContents
:
Vault
|
null
=
null
VAULT_SECRET_TYPE_FILE
=
VAULT_SECRET_TYPE_FILE
constructor
(
public
vault
:
VaultService
,
...
...
@@ -91,4 +92,51 @@ export class VaultSettingsTabComponent extends BaseComponent {
this
.
vaultContents
.
secrets
=
this
.
vaultContents
.
secrets
.
filter
(
x
=>
x
!==
secret
)
this
.
vault
.
removeSecret
(
secret
.
type
,
secret
.
key
)
}
async
replaceFileContent
(
secret
:
VaultFileSecret
)
{
const
transfers
=
await
this
.
platform
.
startUpload
()
if
(
!
transfers
.
length
)
{
return
}
await
this
.
vault
.
updateSecret
(
secret
,
{
...
secret
,
value
:
(
await
transfers
[
0
].
readAll
()).
toString
(
'
base64
'
),
})
this
.
loadVault
()
}
async
renameFile
(
secret
:
VaultFileSecret
)
{
const
modal
=
this
.
ngbModal
.
open
(
PromptModalComponent
)
modal
.
componentInstance
.
prompt
=
'
New name
'
modal
.
componentInstance
.
value
=
secret
.
key
.
description
const
description
=
(
await
modal
.
result
)?.
value
if
(
!
description
)
{
return
}
await
this
.
vault
.
updateSecret
(
secret
,
{
...
secret
,
key
:
{
...
secret
.
key
,
description
,
},
})
this
.
loadVault
()
}
async
exportFile
(
secret
:
VaultFileSecret
)
{
this
.
vault
.
forgetPassphrase
()
secret
=
(
await
this
.
vault
.
getSecret
(
secret
.
type
,
secret
.
key
))
as
VaultFileSecret
const
content
=
Buffer
.
from
(
secret
.
value
,
'
base64
'
)
const
download
=
await
this
.
platform
.
startDownload
(
secret
.
key
.
description
,
0o600
,
content
.
length
)
if
(
download
)
{
await
download
.
write
(
content
)
download
.
close
()
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录