mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-29 21:28:52 +00:00
perf: 优化确认的 dialog
This commit is contained in:
@@ -1,12 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="mfaDialogVisible">
|
||||
<UserConfirmDialog
|
||||
:url="url"
|
||||
@UserConfirmCancel="exit"
|
||||
@UserConfirmDone="getAuthInfo"
|
||||
/>
|
||||
</div>
|
||||
<UserConfirmDialog :handler="getAuthInfo" @onConfirmDone="showSecretDialog" />
|
||||
<Dialog
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
@@ -147,11 +141,12 @@ export default {
|
||||
})
|
||||
},
|
||||
getAuthInfo() {
|
||||
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
|
||||
this.secretInfo = resp
|
||||
this.sshKeyFingerprint = resp?.spec_info?.ssh_key_fingerprint || '-'
|
||||
this.showSecret = true
|
||||
})
|
||||
return this.$axios.get(this.url, { disableFlashErrorMsg: true })
|
||||
},
|
||||
showSecretDialog(res) {
|
||||
this.secretInfo = res
|
||||
this.sshKeyFingerprint = res?.spec_info?.ssh_key_fingerprint || '-'
|
||||
this.showSecret = true
|
||||
},
|
||||
exit() {
|
||||
this.$emit('update:visible', false)
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
:width="'36%'"
|
||||
class="dialog-content"
|
||||
v-bind="$attrs"
|
||||
width="600px"
|
||||
@confirm="visible = false"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<div v-if="ConfirmType === 'relogin'">
|
||||
<div v-if="confirmTypeRequired === 'relogin'">
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-alert
|
||||
:closable="false"
|
||||
:title="$tc('auth.ReLoginTitle')"
|
||||
center
|
||||
style="margin-bottom: 20px;"
|
||||
@@ -24,12 +23,7 @@
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-button
|
||||
size="mini"
|
||||
style="width: 100%; line-height:20px;"
|
||||
type="primary"
|
||||
@click="logOut"
|
||||
>
|
||||
<el-button class="confirm-btn" size="mini" type="primary" @click="logout">
|
||||
{{ this.$t('auth.ReLogin') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
@@ -39,14 +33,13 @@
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24" :span="24" class="add">
|
||||
<el-select
|
||||
v-model="Select"
|
||||
:disabled="ConfirmType === 'password'"
|
||||
v-model="subTypeSelected"
|
||||
style="width: 100%; margin-bottom: 20px;"
|
||||
@change="helpText(Select)"
|
||||
@change="handleSubTypeChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, i) of Content"
|
||||
:key="i"
|
||||
v-for="item of subTypeChoices"
|
||||
:key="item.name"
|
||||
:disabled="item.disabled"
|
||||
:label="item.display_name"
|
||||
:value="item.name"
|
||||
@@ -56,28 +49,23 @@
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24" style="display: flex; margin-bottom: 20px;">
|
||||
<el-input v-model="SecretKey" :placeholder="HelpText" :show-password="showPassword" />
|
||||
<span v-if="Select === 'sms'" style="margin: -1px 0 0 20px;">
|
||||
<el-input v-model="secretValue" :placeholder="inputPlaceholder" :show-password="showPassword" />
|
||||
<span v-if="subTypeSelected === 'sms'" style="margin: -1px 0 0 20px;">
|
||||
<el-button
|
||||
:disabled="smsBtndisabled"
|
||||
:disabled="smsBtnDisabled"
|
||||
size="mini"
|
||||
style="line-height:20px; float: right;"
|
||||
type="primary"
|
||||
@click="sendChallengeCode"
|
||||
@click="sendSMSCode"
|
||||
>
|
||||
{{ smsBtnText }}
|
||||
</el-button>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-row :gutter="24" style="margin: 10px auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-button
|
||||
size="mini"
|
||||
style="width: 100%; line-height:20px;"
|
||||
type="primary"
|
||||
@click="userConfirm"
|
||||
>
|
||||
<el-button class="confirm-btn" size="mini" type="primary" @click="handleConfirm">
|
||||
{{ this.$t('common.Confirm') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
@@ -96,125 +84,125 @@ export default {
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
default: ''
|
||||
},
|
||||
handler: {
|
||||
type: Function,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
title: this.$t('common.CurrentUserVerify'),
|
||||
smsWidth: 0,
|
||||
Select: '',
|
||||
Level: null,
|
||||
HelpText: '',
|
||||
smsBtnText: '',
|
||||
smsBtndisabled: false,
|
||||
ConfirmType: '',
|
||||
Content: null,
|
||||
SecretKey: '',
|
||||
subTypeSelected: '',
|
||||
inputPlaceholder: '',
|
||||
smsBtnText: this.$t('common.SendVerificationCode'),
|
||||
smsBtnDisabled: false,
|
||||
confirmTypeRequired: '',
|
||||
subTypeChoices: [],
|
||||
secretValue: '',
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
showPassword() {
|
||||
if (this.ConfirmType === 'password') {
|
||||
return true
|
||||
return this.confirmTypeRequired === 'password'
|
||||
},
|
||||
iHandler() {
|
||||
if (this.handler === null) {
|
||||
return () => this.$axios.get(this.url, { disableFlashErrorMsg: true })
|
||||
}
|
||||
return false
|
||||
return this.handler
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
if (!val) {
|
||||
this.$emit('UserConfirmCancel', true)
|
||||
this.$emit('onConfirmCancel', true)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.smsBtnText = this.$t('common.SendVerificationCode')
|
||||
this.$axios.get(`${this.url}`, { disableFlashErrorMsg: true }).then(
|
||||
() => { this.$emit('UserConfirmDone', true) }).catch((err) => {
|
||||
const confirm_type = err.response.data.code
|
||||
this.$axios.get('/api/v1/authentication/confirm/', { params: { confirm_type: confirm_type }}).then((data) => {
|
||||
this.ConfirmType = data.confirm_type
|
||||
this.Content = data.content
|
||||
if (this.ConfirmType === 'relogin') {
|
||||
this.$axios.post(
|
||||
`/api/v1/authentication/confirm/`,
|
||||
{
|
||||
confirm_type: this.ConfirmType,
|
||||
secret_key: ''
|
||||
},
|
||||
{ disableFlashErrorMsg: true },
|
||||
).then(() => { this.$emit('UserConfirmDone', true) }).catch(() => {
|
||||
this.title = this.$t('auth.NeedReLogin')
|
||||
this.visible = true
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.ConfirmType === 'mfa') {
|
||||
this.Select = this.Content.filter(item => !item.disabled)[0].name
|
||||
if (this.Select === 'sms') {
|
||||
this.smsWidth = 6
|
||||
}
|
||||
this.HelpText = this.Content.filter(item => !item.disabled)[0].placeholder
|
||||
} else if (this.ConfirmType === 'password') {
|
||||
this.Select = this.$t('setting.password')
|
||||
this.HelpText = this.$t('common.PasswordRequireForSecurity')
|
||||
this.Content = [{ 'name': 'password' }]
|
||||
}
|
||||
this.title = this.$t('common.CurrentUserVerify')
|
||||
this.visible = true
|
||||
}).catch(() => {
|
||||
this.$emit('AuthMFAError', true)
|
||||
})
|
||||
})
|
||||
this.performConfirm()
|
||||
},
|
||||
methods: {
|
||||
helpText(val) {
|
||||
this.HelpText = this.Content.filter(item => item.name === val)[0]?.placeholder
|
||||
if (val === 'sms') {
|
||||
this.smsWidth = 6
|
||||
} else {
|
||||
this.smsWidth = 0
|
||||
}
|
||||
handleSubTypeChange(val) {
|
||||
this.inputPlaceholder = this.subTypeChoices.filter(item => item.name === val)[0]?.placeholder
|
||||
this.smsWidth = val === 'sms' ? 6 : 0
|
||||
},
|
||||
logOut() {
|
||||
performConfirm() {
|
||||
this.iHandler().then((res) => {
|
||||
this.$emit('onConfirmDone', res)
|
||||
}).catch((err) => {
|
||||
const confirmType = err.response.data?.code
|
||||
const confirmUrl = '/api/v1/authentication/confirm/'
|
||||
this.$axios.get(confirmUrl, { params: { confirm_type: confirmType }}).then((data) => {
|
||||
this.subTypeChoices = data.content
|
||||
this.confirmTypeRequired = data.confirm_type
|
||||
|
||||
if (this.confirmTypeRequired === 'relogin') {
|
||||
const data = {
|
||||
confirm_type: this.confirmTypeRequired,
|
||||
secret_key: ''
|
||||
}
|
||||
this.$axios.post(confirmUrl, data, { disableFlashErrorMsg: true }).then(() => {
|
||||
this.afterConfirm()
|
||||
}).catch(() => {
|
||||
this.title = this.$t('auth.NeedReLogin')
|
||||
})
|
||||
return
|
||||
}
|
||||
const defaultSubType = this.subTypeChoices.filter(item => !item.disabled)[0]
|
||||
this.subTypeSelected = defaultSubType.name
|
||||
this.inputPlaceholder = defaultSubType.placeholder
|
||||
this.visible = true
|
||||
}).catch(() => {
|
||||
this.$emit('AuthMFAError', true)
|
||||
})
|
||||
})
|
||||
},
|
||||
logout() {
|
||||
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
|
||||
},
|
||||
sendChallengeCode() {
|
||||
this.$axios.post(
|
||||
`/api/v1/authentication/mfa/select/`, {
|
||||
type: 'sms'
|
||||
}
|
||||
).then(res => {
|
||||
this.$message.success(this.$t('common.VerificationCodeSent'))
|
||||
sendSMSCode() {
|
||||
this.$axios.post(`/api/v1/authentication/mfa/select/`, { type: 'sms' }).then(res => {
|
||||
this.$message.success(this.$tc('common.VerificationCodeSent'))
|
||||
let time = 60
|
||||
const interval = setInterval(() => {
|
||||
const originText = this.smsBtnText
|
||||
this.smsBtnText = this.$t('common.Pending') + `: ${time}`
|
||||
this.smsBtndisabled = true
|
||||
this.smsBtnDisabled = true
|
||||
time -= 1
|
||||
|
||||
if (time === 0) {
|
||||
this.smsBtnText = this.$t('common.SendVerificationCode')
|
||||
this.smsBtndisabled = false
|
||||
this.smsBtnText = originText
|
||||
this.smsBtnDisabled = false
|
||||
clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
},
|
||||
userConfirm() {
|
||||
if (this.Select === 'otp' && this.SecretKey.length !== 6) {
|
||||
return this.$message.error(this.$t('common.MFAErrorMsg'))
|
||||
afterConfirm() {
|
||||
this.iHandler().then(res => {
|
||||
this.$emit('onConfirmDone', res)
|
||||
}).catch((e) => {
|
||||
this.$emit('onHandlerError', e)
|
||||
}).finally(() => {
|
||||
this.visible = false
|
||||
})
|
||||
},
|
||||
handleConfirm() {
|
||||
if (this.subTypeSelected === 'otp' && this.secretValue.length !== 6) {
|
||||
return this.$message.error(this.$tc('common.MFAErrorMsg'))
|
||||
}
|
||||
this.$axios.post(
|
||||
`/api/v1/authentication/confirm/`, {
|
||||
confirm_type: this.ConfirmType,
|
||||
mfa_type: this.ConfirmType === 'password' ? undefined : this.Select,
|
||||
secret_key: this.SecretKey
|
||||
}
|
||||
).then(res => {
|
||||
this.$emit('UserConfirmDone', true)
|
||||
const data = {
|
||||
confirm_type: this.confirmTypeRequired,
|
||||
mfa_type: this.confirmTypeRequired === 'mfa' ? this.subTypeSelected : '',
|
||||
secret_key: this.secretValue
|
||||
}
|
||||
this.$axios.post(`/api/v1/authentication/confirm/`, data).then(res => {
|
||||
this.afterConfirm()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -228,5 +216,16 @@ export default {
|
||||
|
||||
.dialog-content >>> .el-dialog {
|
||||
padding: 8px;
|
||||
|
||||
.el-dialog__body {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<div>
|
||||
<div v-if="mfaDialogShow">
|
||||
<UserConfirmDialog
|
||||
:url="url"
|
||||
:url="confirmUrl"
|
||||
@AuthMFAError="handleAuthMFAError"
|
||||
@UserConfirmCancel="handleExportCancel"
|
||||
@UserConfirmDone="showExportDialog"
|
||||
@onConfirmCancel="handleExportCancel"
|
||||
@onConfirmDone="showExportDialog"
|
||||
/>
|
||||
</div>
|
||||
<Dialog
|
||||
@@ -112,7 +112,8 @@ export default {
|
||||
exportTypeOption: 'csv',
|
||||
meta: {},
|
||||
mfaVerified: false,
|
||||
mfaDialogShow: false
|
||||
mfaDialogShow: false,
|
||||
confirmUrl: '/api/v1/accounts/account-secrets/?limit=1'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -136,7 +137,6 @@ export default {
|
||||
delete query[key]
|
||||
}
|
||||
}
|
||||
|
||||
return query
|
||||
},
|
||||
tableHasQuery() {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<script>
|
||||
import BaseFormatter from './base.vue'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'DateFormatter',
|
||||
extends: BaseFormatter,
|
||||
@@ -13,7 +14,7 @@ export default {
|
||||
if (this.cellValue) {
|
||||
value = toSafeLocalDateStr(this.cellValue)
|
||||
} else {
|
||||
value = ''
|
||||
value = '-'
|
||||
}
|
||||
// const locale = this.$i18n.locale
|
||||
// const value = dt.toLocaleString(locale, { hourCycle: 'h23' })
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"": "",
|
||||
"accounts": {
|
||||
"AutoPush": "自动推送",
|
||||
"GeneralAccounts": "普通账号",
|
||||
@@ -1679,7 +1678,7 @@
|
||||
"LDAPUser": "LDAP 用户",
|
||||
"helpText": {
|
||||
"TempPassword": "临时密码有效期为 300 秒,使用后立刻失效",
|
||||
"ApiKeyList": "使用 Api key 签名请求头进行认证,每个请求的头部是不一样的, 相对于 Token 方式,更加安全,请查阅文档使用",
|
||||
"ApiKeyList": "使用 Api key 签名请求头进行认证,每个请求的头部是不一样的, 相对于 Token 方式,更加安全,请查阅文档使用;<br>为降低泄露风险,Secret 仅在生成时可以查看, 每个用户最多支持创建 10 个",
|
||||
"ConnectionTokenList": "连接令牌是将身份验证和连接资产结合起来使用的一种认证信息,支持用户一键登录到资产,目前支持的组件包括:KoKo、Lion、Magnus、Razor 等",
|
||||
"authLdapSearchFilter": "可能的选项是(cn或uid或sAMAccountName=%(user)s)",
|
||||
"authLdapSearchOu": "使用|分隔各OU",
|
||||
@@ -1695,7 +1694,7 @@
|
||||
"securityLoginLimitTime": "提示:(单位:分)当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录",
|
||||
"securityMaxIdleTime": "提示:如果超过该配置没有操作,连接会被断开 (单位:分)",
|
||||
"securityPasswordExpirationTime": "提示:(单位:天)如果用户在此期间没有更新密码,用户密码将过期失效; 密码过期提醒邮件将在密码过期前5天内由系统(每天)自动发送给用户",
|
||||
"siteUrl": "eg: http://jumpserver.abc.com:8080",
|
||||
"siteUrl": "eg: https://jumpserver.example.com:8080",
|
||||
"terminalHeartbeatInterval": "单位: 秒",
|
||||
"terminalSessionKeepDuration": "单位:天。 会话、录像、命令记录超过该时长将会被删除(仅影响数据库存储, oss等不受影响)",
|
||||
"terminalTelnetRegex": "登录telnet服务器成功后的提示正则表达式,如: Last\\s*login|success|成功",
|
||||
@@ -1873,6 +1872,10 @@
|
||||
"TestNodeAssetConnectivity": "测试资产节点可连接性",
|
||||
"UpdateNodeAssetHardwareInfo": "更新节点资产硬件信息"
|
||||
},
|
||||
"profile": {
|
||||
"CreateAccessKey": "创建访问密钥",
|
||||
"ApiKeyWarning": "为降低 AccessKey 泄露的风险,只在创建时提供 Secret,后续不可再进行查询,请妥善保存。"
|
||||
},
|
||||
"users": {
|
||||
"LunaSettingUpdate": "Luna 配置设置",
|
||||
"KokoSettingUpdate": "Koko 配置设置",
|
||||
|
||||
@@ -1,38 +1,80 @@
|
||||
<template>
|
||||
<GenericListPage
|
||||
ref="GenericListTable"
|
||||
:header-actions="headerActions"
|
||||
:help-message="helpMessage"
|
||||
:table-config="tableConfig"
|
||||
/>
|
||||
<div>
|
||||
<GenericListPage
|
||||
ref="GenericListTable"
|
||||
:header-actions="headerActions"
|
||||
:help-message="helpMessage"
|
||||
:table-config="tableConfig"
|
||||
/>
|
||||
<UserConfirmDialog
|
||||
v-if="mfaDialogVisible"
|
||||
:handler="createAccessKey"
|
||||
@close="mfaDialogVisible = false"
|
||||
@onConfirmDone="showAccessKeyDialog"
|
||||
/>
|
||||
<Dialog
|
||||
:show-cancel="false"
|
||||
:title="$tc('profile.CreateAccessKey')"
|
||||
:visible.sync="visible"
|
||||
width="700px"
|
||||
@confirm="visible = false"
|
||||
>
|
||||
<el-alert type="warning">
|
||||
{{ warningText }}
|
||||
<div class="secret">
|
||||
<div class="row">
|
||||
<span class="col">ID:</span>
|
||||
<span class="value">{{ key.id }}</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col">Secret:</span>
|
||||
<span class="value">{{ key.secret }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-alert>
|
||||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
import { DateFormatter, ShowKeyCopyFormatter } from '@/components/Table/TableFormatters'
|
||||
import { DateFormatter } from '@/components/Table/TableFormatters'
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import UserConfirmDialog from '@/components/Apps/UserConfirmDialog/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserConfirmDialog,
|
||||
Dialog,
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
const ajaxUrl = '/api/v1/authentication/access-keys/'
|
||||
const vm = this
|
||||
return {
|
||||
mfaUrl: '',
|
||||
mfaDialogVisible: false,
|
||||
createAccessKey: () => vm.$axios.post(ajaxUrl),
|
||||
helpMessage: this.$t('setting.helpText.ApiKeyList'),
|
||||
warningText: this.$t('profile.ApiKeyWarning'),
|
||||
visible: false,
|
||||
key: { id: '', secret: '' },
|
||||
tableConfig: {
|
||||
hasSelection: true,
|
||||
url: ajaxUrl,
|
||||
columns: ['id', 'secret', 'is_active', 'date_created', 'date_last_used', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['id', 'actions'],
|
||||
default: ['id', 'secret', 'is_active', 'date_created', 'actions']
|
||||
min: ['id', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
id: {
|
||||
label: 'Access Key'
|
||||
label: 'ID'
|
||||
},
|
||||
secret: {
|
||||
label: 'Secret Key',
|
||||
formatter: ShowKeyCopyFormatter
|
||||
label: 'Secret',
|
||||
formatter: () => {
|
||||
return '********'
|
||||
}
|
||||
},
|
||||
date_created: {
|
||||
label: this.$t('common.DateCreated'),
|
||||
@@ -65,7 +107,7 @@ export default {
|
||||
this.getRefsListTable.reloadTable()
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$tc('common.updateErrorMsg' + ' ' + error))
|
||||
this.$message.error(this.$t('common.updateErrorMsg') + ' ' + error)
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
@@ -75,9 +117,7 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRightActions: true,
|
||||
hasRefresh: true,
|
||||
hasMoreActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasBulkDelete: false,
|
||||
@@ -89,12 +129,10 @@ export default {
|
||||
type: 'primary',
|
||||
can: () => this.$hasPerm('authentication.add_accesskey'),
|
||||
callback: function() {
|
||||
this.$axios.post(ajaxUrl).then(res => {
|
||||
this.getRefsListTable.reloadTable()
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$tc('common.updateErrorMsg' + ' ' + error))
|
||||
})
|
||||
this.mfaDialogVisible = false
|
||||
setTimeout(() => {
|
||||
this.mfaDialogVisible = true
|
||||
}, 100)
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
@@ -105,9 +143,36 @@ export default {
|
||||
getRefsListTable() {
|
||||
return this.$refs.GenericListTable.$refs.ListTable.$refs.ListTable || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showAccessKeyDialog(res) {
|
||||
this.key = res
|
||||
this.visible = true
|
||||
setTimeout(() => {
|
||||
this.mfaDialogVisible = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.secret {
|
||||
color: #2b2f3a;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.col {
|
||||
width: 100px;
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
v-if="showPasswordDialog"
|
||||
:url="confirmUrl"
|
||||
:visible.sync="showPasswordDialog"
|
||||
@UserConfirmCancel="exit"
|
||||
@UserConfirmDone="verifyDone"
|
||||
@onConfirmCancel="exit"
|
||||
@onConfirmDone="verifyDone"
|
||||
/>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
@@ -346,7 +346,7 @@ export default {
|
||||
verifyDone() {
|
||||
const url = this.bindOrUNBindUrl
|
||||
if (!this.object[`${this.currentEdit}_id`]) {
|
||||
window.location.href = url
|
||||
window.open(url, 'Bind', 'width=800,height=600')
|
||||
} else {
|
||||
this.$axios.post(url).then(res => {
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
|
||||
Reference in New Issue
Block a user