mirror of
https://github.com/jumpserver/lina.git
synced 2025-08-18 06:47:39 +00:00
Merge pull request #2121 from jumpserver/pr@v3@feat_account_password_history
feat: 资产账号增加查看历史密码
This commit is contained in:
commit
4effc3c3b4
@ -99,7 +99,7 @@ export default {
|
|||||||
},
|
},
|
||||||
push_now: {
|
push_now: {
|
||||||
hidden: () => {
|
hidden: () => {
|
||||||
return !this.platform.automation['push_account_enabled']
|
return !this.platform.automation?.['push_account_enabled']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -112,7 +112,7 @@ export default {
|
|||||||
afterGetRemoteMeta(meta) {
|
afterGetRemoteMeta(meta) {
|
||||||
const choices = meta.secret_type.choices
|
const choices = meta.secret_type.choices
|
||||||
const secretTypes = []
|
const secretTypes = []
|
||||||
this.platform.protocols.forEach(p => {
|
this.platform.protocols?.forEach(p => {
|
||||||
secretTypes.push(...p['secret_types'])
|
secretTypes.push(...p['secret_types'])
|
||||||
})
|
})
|
||||||
if (!this.form.secret_type) {
|
if (!this.form.secret_type) {
|
||||||
|
@ -72,8 +72,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getPlatform() {
|
async getPlatform() {
|
||||||
this.platform = await this.$axios.get(`/api/v1/assets/platforms/${this.asset.platform.id}/`)
|
this.platform = await this.$axios.get(`/api/v1/assets/platforms/${this.asset?.platform?.id}/`)
|
||||||
console.log('Platform: ', this.platform)
|
|
||||||
},
|
},
|
||||||
addAccount(form) {
|
addAccount(form) {
|
||||||
const data = { asset: this.asset.id, ...form }
|
const data = { asset: this.asset.id, ...form }
|
||||||
|
75
src/components/AccountListTable/PasswordHistoryDialog.vue
Normal file
75
src/components/AccountListTable/PasswordHistoryDialog.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<GenericListTableDialog :visible.sync="iVisible" v-bind="config" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GenericListTableDialog } from '@/layout/components'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
GenericListTableDialog
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
account: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
config: {
|
||||||
|
title: this.$t('accounts.HistoryPassword'),
|
||||||
|
visible: false,
|
||||||
|
width: '60%',
|
||||||
|
tableConfig: {
|
||||||
|
url: `/api/v1/assets/accounts-historys?id=${this.account.id}`,
|
||||||
|
columns: [
|
||||||
|
'name', 'version', 'password', 'date_created'
|
||||||
|
],
|
||||||
|
columnsShow: {
|
||||||
|
min: ['name'],
|
||||||
|
default: [
|
||||||
|
'name', 'version', 'password', 'date_created'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
columnsMeta: {
|
||||||
|
name: {
|
||||||
|
showOverflowTooltip: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headerActions: {
|
||||||
|
hasImport: false,
|
||||||
|
hasExport: false,
|
||||||
|
hasLeftActions: false,
|
||||||
|
hasColumnSetting: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iVisible: {
|
||||||
|
get() {
|
||||||
|
return this.visible
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:visible', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -17,17 +17,26 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<el-form label-position="right" label-width="80px" :model="authInfo">
|
<el-form label-position="right" label-width="80px" :model="authInfo">
|
||||||
<el-form-item :label="this.$tc('assets.Name')">
|
<el-form-item :label="this.$t('assets.Name')">
|
||||||
<el-input v-model="account['name']" readonly />
|
<el-input v-model="account.asset.name" readonly />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="this.$tc('assets.Username')">
|
<el-form-item :label="this.$tc('assets.Username')">
|
||||||
<el-input v-model="account['username']" readonly />
|
<el-input v-model="account['username']" readonly />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="account['secret_type'] === 'password'" :label="this.$tc('assets.Password')">
|
<el-form-item v-if="secretTypePassword" :label="this.$t('assets.Password')">
|
||||||
<el-input v-model="authInfo.secret" type="password" show-password />
|
<ShowKeyCopyFormatter v-model="authInfo.secret" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-else :label="this.$tc('assets.Key')">
|
<el-form-item v-else :label="this.$t('users.SSHKey')">
|
||||||
<el-input v-model="authInfo.secret" type="textarea" :rows="10" />
|
<el-input v-model="authInfo['private_key']" class="item-textarea" type="textarea" show-password readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="this.$t('common.DateCreated')">
|
||||||
|
<span>{{ $moment(authInfo.date_created, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="this.$t('common.DateUpdated')">
|
||||||
|
<span>{{ $moment(authInfo.date_updated, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="this.$t('accounts.PasswordRecord')">
|
||||||
|
<span>{{ authInfo.version }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -38,11 +47,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import Dialog from '@/components/Dialog'
|
import Dialog from '@/components/Dialog'
|
||||||
import UserConfirmDialog from '@/components/UserConfirmDialog'
|
import UserConfirmDialog from '@/components/UserConfirmDialog'
|
||||||
|
import { ShowKeyCopyFormatter } from '@/components/TableFormatters'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ShowSecretInfo',
|
name: 'ShowSecretInfo',
|
||||||
components: {
|
components: {
|
||||||
Dialog,
|
Dialog,
|
||||||
UserConfirmDialog
|
UserConfirmDialog,
|
||||||
|
ShowKeyCopyFormatter
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
account: {
|
account: {
|
||||||
@ -62,6 +74,11 @@ export default {
|
|||||||
url: `/api/v1/assets/account-secrets/${this.account.id}/`
|
url: `/api/v1/assets/account-secrets/${this.account.id}/`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
secretTypePassword() {
|
||||||
|
return this.authInfo.secret_type === 'password'
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getAuthInfo() {
|
getAuthInfo() {
|
||||||
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
|
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
|
||||||
@ -76,8 +93,23 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.item-textarea >>> .el-textarea__inner {
|
.item-textarea >>> .el-textarea__inner {
|
||||||
height: 110px;
|
height: 110px;
|
||||||
}
|
}
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
.title {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
:account="account"
|
:account="account"
|
||||||
@add="addAccountSuccess"
|
@add="addAccountSuccess"
|
||||||
/>
|
/>
|
||||||
|
<PasswordHistoryDialog
|
||||||
|
v-if="showPasswordHistoryDialog"
|
||||||
|
:account="account"
|
||||||
|
:visible.sync="showPasswordHistoryDialog"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -27,12 +32,14 @@ import AddAccount from './AddAccount'
|
|||||||
import { connectivityMeta } from './const'
|
import { connectivityMeta } from './const'
|
||||||
import { openTaskPage } from '@/utils/jms'
|
import { openTaskPage } from '@/utils/jms'
|
||||||
import { hasUUID } from '@/utils/common'
|
import { hasUUID } from '@/utils/common'
|
||||||
|
import PasswordHistoryDialog from './PasswordHistoryDialog'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AccountListTable',
|
name: 'AccountListTable',
|
||||||
components: {
|
components: {
|
||||||
ListTable,
|
ListTable,
|
||||||
UpdateSecretInfo,
|
UpdateSecretInfo,
|
||||||
|
PasswordHistoryDialog,
|
||||||
ViewSecret,
|
ViewSecret,
|
||||||
AddAccount
|
AddAccount
|
||||||
},
|
},
|
||||||
@ -71,6 +78,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
const vm = this
|
const vm = this
|
||||||
return {
|
return {
|
||||||
|
showPasswordHistoryDialog: false,
|
||||||
showViewSecretDialog: false,
|
showViewSecretDialog: false,
|
||||||
showUpdateSecretDialog: false,
|
showUpdateSecretDialog: false,
|
||||||
showAddDialog: false,
|
showAddDialog: false,
|
||||||
@ -176,6 +184,17 @@ export default {
|
|||||||
vm.showAddDialog = true
|
vm.showAddDialog = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$t('accounts.HistoryPassword'),
|
||||||
|
can: this.$hasPerm('assets.change_assetaccountsecret') && !this.$store.getters.currentOrgIsRoot,
|
||||||
|
callback: ({ row }) => {
|
||||||
|
vm.account = row
|
||||||
|
vm.showPasswordHistoryDialog = false
|
||||||
|
setTimeout(() => {
|
||||||
|
vm.showPasswordHistoryDialog = true
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<span>{{ currentValue }}</span>
|
<span>{{ currentValue }}</span>
|
||||||
<span class="right">
|
<span class="right">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
v-if="hasShow"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
placement="top"
|
placement="top"
|
||||||
:content="this.$t('common.View')"
|
:content="this.$t('common.View')"
|
||||||
@ -10,6 +11,7 @@
|
|||||||
<i class="el-icon-view" @click="onShow()" />
|
<i class="el-icon-view" @click="onShow()" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
v-if="hasCopy"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
placement="top"
|
placement="top"
|
||||||
:content="this.$t('common.Copy')"
|
:content="this.$t('common.Copy')"
|
||||||
@ -21,15 +23,24 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BaseFormatter from './base'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ShowKeyCopyFormatter',
|
name: 'ShowKeyCopyFormatter',
|
||||||
extends: BaseFormatter,
|
props: {
|
||||||
proops: {
|
value: {
|
||||||
cellValue: {
|
|
||||||
type: String,
|
type: String,
|
||||||
default: () => ''
|
default: () => ''
|
||||||
|
},
|
||||||
|
cellValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
hasShow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
hasCopy: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -37,18 +48,24 @@ export default {
|
|||||||
currentValue: this.switchShowValue()
|
currentValue: this.switchShowValue()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
iValue() {
|
||||||
|
return this.value || this.cellValue
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
switchShowValue() {
|
switchShowValue() {
|
||||||
return '******' + this.cellValue.replace(/[\w-]/g, '')
|
const value = this.value || this.cellValue
|
||||||
|
return '******' + value.replace(/[\s\S]/g, '')
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
const { currentValue, cellValue, switchShowValue } = this
|
const { currentValue, switchShowValue } = this
|
||||||
this.currentValue = currentValue === cellValue ? switchShowValue() : cellValue
|
this.currentValue = currentValue === this.iValue ? switchShowValue() : this.iValue
|
||||||
},
|
},
|
||||||
onCopy: _.throttle(function() {
|
onCopy: _.throttle(function() {
|
||||||
const inputDom = document.createElement('input')
|
const inputDom = document.createElement('input')
|
||||||
inputDom.id = 'creatInputDom'
|
inputDom.id = 'createInputDom'
|
||||||
inputDom.value = this.cellValue
|
inputDom.value = this.iValue
|
||||||
document.body.appendChild(inputDom)
|
document.body.appendChild(inputDom)
|
||||||
inputDom.select()
|
inputDom.select()
|
||||||
document?.execCommand('copy')
|
document?.execCommand('copy')
|
||||||
@ -74,7 +91,7 @@ export default {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
.el-icon-view, .el-icon-copy-document {
|
.el-icon-view, .el-icon-copy-document {
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #1c84c6;
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"": "",
|
"": "",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
|
"HistoryPassword": "History password",
|
||||||
|
"PasswordRecord": "Password record",
|
||||||
"AccountHistableHelpMessage": "Record the historical version of the current account",
|
"AccountHistableHelpMessage": "Record the historical version of the current account",
|
||||||
"PleaseClickLeftAssetToViewAssetAccount": "Asset account list, please click on the assets on the left to view",
|
"PleaseClickLeftAssetToViewAssetAccount": "Asset account list, please click on the assets on the left to view",
|
||||||
"PleaseClickLeftApplicationToViewApplicationAccount": "Application account list, please click on the application on the left to view",
|
"PleaseClickLeftApplicationToViewApplicationAccount": "Application account list, please click on the application on the left to view",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"": "",
|
"": "",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
|
"HistoryPassword": "履歴パスワード",
|
||||||
|
"PasswordRecord": "パスワードレコード",
|
||||||
"AccountHistableHelpMessage": "現在のアカウントの履歴バージョンを記録する",
|
"AccountHistableHelpMessage": "現在のアカウントの履歴バージョンを記録する",
|
||||||
"PleaseClickLeftAssetToViewAssetAccount": "資産のアカウントのリスト、左側の資産をクリックして表示します",
|
"PleaseClickLeftAssetToViewAssetAccount": "資産のアカウントのリスト、左側の資産をクリックして表示します",
|
||||||
"PleaseClickLeftApplicationToViewApplicationAccount": "アカウントのリストを適用して、左側のアプリケーションをクリックして表示します",
|
"PleaseClickLeftApplicationToViewApplicationAccount": "アカウントのリストを適用して、左側のアプリケーションをクリックして表示します",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"": "",
|
"": "",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
|
"HistoryPassword": "历史密码",
|
||||||
|
"PasswordRecord": "密码记录",
|
||||||
"AccountHistableHelpMessage": "记录当前账号的历史版本",
|
"AccountHistableHelpMessage": "记录当前账号的历史版本",
|
||||||
"PleaseClickLeftAssetToViewAssetAccount": "资产账号列表,点击左侧资产进行查看",
|
"PleaseClickLeftAssetToViewAssetAccount": "资产账号列表,点击左侧资产进行查看",
|
||||||
"PleaseClickLeftApplicationToViewApplicationAccount": "应用账号列表,点击左侧应用进行查看",
|
"PleaseClickLeftApplicationToViewApplicationAccount": "应用账号列表,点击左侧应用进行查看",
|
||||||
|
Loading…
Reference in New Issue
Block a user