perf: confirm 优化

This commit is contained in:
feng626
2022-06-20 17:05:00 +08:00
committed by Jiangjie.Bai
parent bb91fbb327
commit f5c7abcbd8
7 changed files with 186 additions and 48 deletions

View File

@@ -1,6 +1,7 @@
<template>
<div>
<UserConfirmDialog
:url="url"
@UserConfirmDone="getAuthInfo"
@UserConfirmCancel="exit"
/>
@@ -57,13 +58,13 @@ export default {
return {
dialogTitle: this.$t('common.ViewSecret'),
authInfo: {},
showAuthInfo: false
showAuthInfo: false,
url: `/api/v1/assets/account-secrets/${this.account.id}/`
}
},
methods: {
getAuthInfo() {
const url = `/api/v1/assets/account-secrets/${this.account.id}/`
this.$axios.get(url, { disableFlashErrorMsg: true }).then(resp => {
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
this.authInfo = resp
this.showAuthInfo = true
})

View File

@@ -1,6 +1,7 @@
<template>
<div>
<UserConfirmDialog
:url="url"
@UserConfirmDone="getAuthInfo"
@UserConfirmCancel="exit"
/>
@@ -54,13 +55,13 @@ export default {
return {
dialogTitle: this.$t('common.ViewSecret'),
authInfo: {},
showAuthInfo: false
showAuthInfo: false,
url: `/api/v1/applications/account-secrets/${this.account.id}/`
}
},
methods: {
getAuthInfo() {
const url = `/api/v1/applications/account-secrets/${this.account.id}/`
this.$axios.get(url, { disableFlashErrorMsg: true }).then(resp => {
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
this.authInfo = resp
this.showAuthInfo = true
})

View File

@@ -1,28 +1,88 @@
<template>
<Dialog
:title="$t('common.CurrentUserVerify')"
:width="'50'"
:title="title"
:width="'36%'"
:show-confirm="false"
:show-cancel="false"
:visible.sync="visible"
:destroy-on-close="true"
v-bind="$attrs"
class="dialog-content"
v-on="$listeners"
>
<el-row :gutter="20">
<el-col :md="4" :sm="24">
<div style="line-height: 34px;text-align: center">{{ Label }}</div>
<div v-if="ConfirmType === 'relogin'">
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24">
<el-alert
:title="this.$t('auth.ReLoginTitle')"
type="info"
center
:closable="false"
style="margin-bottom: 20px;"
/>
</el-col>
<el-col :md="14" :sm="24">
<el-input v-model="SecretKey" :show-password="showPassword" />
<span class="help-tips help-block">{{ HelpText }}</span>
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24">
<el-button
size="mini"
type="primary"
style="width: 100%; line-height:20px;"
@click="logOut"
>
{{ this.$t('auth.ReLogin') }}
</el-button>
</el-col>
<el-col :md="4" :sm="24">
<el-button size="mini" type="primary" style="line-height:20px " @click="userConfirm">
</el-row>
</div>
<div v-else>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :span="24" :md="24" :sm="24" class="add">
<el-select
v-model="Select"
:disabled="ConfirmType === 'password'"
style="width: 100%; margin-bottom: 20px;"
@change="helpText(Select)"
>
<el-option
v-for="(item, i) of Content"
:key="i"
:label="item.display_name"
:value="item.name"
:disabled="item.disabled"
/>
</el-select>
</el-col>
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24 - smsWidth" :sm="24">
<el-input v-model="SecretKey" :show-password="showPassword" :placeholder="HelpText" style="margin-bottom: 20px;" />
</el-col>
<el-col v-if="Select === 'sms'" :md="smsWidth" :sm="24">
<el-button
size="mini"
type="primary"
style="line-height:20px; float: right;"
:disabled="smsBtndisabled"
@click="sendChallengeCode"
>
{{ smsBtnText }}
</el-button>
</el-col>
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24">
<el-button
size="mini"
type="primary"
style="width: 100%; line-height:20px;"
@click="userConfirm"
>
{{ this.$t('common.Confirm') }}
</el-button>
</el-col>
</el-row>
</div>
</Dialog>
</template>
<script>
@@ -33,11 +93,23 @@ export default {
components: {
Dialog
},
props: {
url: {
type: String,
default: () => ''
}
},
data() {
return {
Label: '',
title: '',
smsWidth: 0,
Select: '',
Level: null,
HelpText: '',
smsBtnText: '',
smsBtndisabled: false,
ConfirmType: '',
Content: null,
SecretKey: '',
visible: false
}
@@ -59,37 +131,72 @@ export default {
}
},
mounted() {
this.$axios.get('/api/v1/authentication/confirm/', { disableFlashErrorMsg: true }).then(() => {
this.$emit('UserConfirmDone', true)
}).catch(err => {
this.$log.debug('Verify otp code error: ', err)
const backends = err.response.data.backends
backends.sort((a, b) => b.level - a.level)
this.ConfirmType = backends[0].name
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.visible = false
return this.$message.error(this.$t('auth.ReLoginErr'))
this.title = this.$t('auth.NeedReLogin')
this.visible = true
return
}
if (this.ConfirmType === 'mfa') {
this.Label = 'MFA'
this.HelpText = this.$t('common.MFARequireForSecurity')
this.visible = true
this.Select = this.Content.filter(item => !item.disabled)[0].name
this.HelpText = this.Content.filter(item => !item.disabled)[0].placeholder
} else if (this.ConfirmType === 'password') {
this.Label = this.$t('setting.password')
this.Select = this.$t('setting.password')
this.HelpText = this.$t('common.PasswordRequireForSecurity')
this.visible = true
this.Content = [{ 'name': 'password' }]
}
this.title = this.$t('common.CurrentUserVerify')
this.visible = true
})
})
},
methods: {
helpText(val) {
this.HelpText = this.Content.filter(item => item.name === val)[0]?.placeholder
if (val === 'sms') {
this.smsWidth = 6
} else {
this.smsWidth = 0
}
},
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'))
let time = 60
const interval = setInterval(() => {
this.smsBtnText = this.$t('common.Pending') + `: ${time}`
this.smsBtndisabled = true
time -= 1
if (time === 0) {
this.smsBtnText = this.$t('common.SendVerificationCode')
this.smsBtndisabled = false
clearInterval(interval)
}
}, 1000)
})
},
userConfirm() {
if (this.ConfirmType === 'mfa' && this.SecretKey.length !== 6) {
return this.$message.error(this.$tc('common.MFAErrorMsg'))
if (this.Select === 'otp' && this.SecretKey.length !== 6) {
return this.$message.error(this.$t('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 => {
@@ -100,6 +207,12 @@ export default {
}
</script>
<style scoped>
<style lang="scss" scoped>
.dialog-content >>> .el-dialog__footer{
padding: 0;
}
.dialog-content >>> .el-dialog{
padding: 8px;
}
</style>

View File

@@ -247,9 +247,13 @@
"auth": {
"LoginRequiredMsg": "You account has logout, Please login again",
"ReLogin": "Re-Login",
"ReLoginTitle": "The current three-party login user (cas/saml) is not bound to MFA and does not support password verification. Please login again",
"NeedReLogin": "Need Re-Login",
"ReLoginErr": "Login time has exceeded 5 minutes, please login again"
},
"common": {
"VerificationCodeSent": "The verification code has been sent",
"SendVerificationCode": "Send verification code",
"ChangeViewHelpText": "Click to change view",
"Component": "component",
"PrivateCloud": "Private cloud",

View File

@@ -252,9 +252,13 @@
"auth": {
"LoginRequiredMsg": "アカウントが終了しました。ログインし直してください",
"ReLogin": "再ログイン",
"ReLoginTitle": "現在、サードパーティのログインユーザーCAS/SAMLは、MFAをバインドしておらず、パスワードチェックをサポートしていません。再ログインしてください。",
"NeedReLogin": "再ログインが必要です",
"ReLoginErr": "ログイン時間が 5 分を超えました。もう一度ログインしてください"
},
"common": {
"VerificationCodeSent": "検証コードが送信されました",
"SendVerificationCode": "認証コードの送信",
"ChangeViewHelpText": "クリックしてさまざまなビューにアクセス",
"Component": "コンポーネント",
"PrivateCloud": "プライベートクラウド",

View File

@@ -252,9 +252,13 @@
"auth": {
"LoginRequiredMsg": "账号已退出,请重新登录",
"ReLogin": "重新登录",
"ReLoginTitle": "当前三方登录用户CAS/SAML未绑定 MFA 且不支持密码校验,请重新登录。",
"NeedReLogin": "需要重新登录",
"ReLoginErr": "登录时长已超过 5 分钟,请重新登录"
},
"common": {
"VerificationCodeSent": "验证码已发送",
"SendVerificationCode": "发送验证码",
"ChangeViewHelpText": "点击切换不同视图",
"Component": "组件",
"PrivateCloud": "私有云",

View File

@@ -2,6 +2,7 @@
<Page v-bind="$attrs">
<UserConfirmDialog
v-if="showPasswordDialog"
:url="confirmUrl"
:visible.sync="showPasswordDialog"
@UserConfirmDone="verifyDone"
@UserConfirmCancel="exit"
@@ -284,6 +285,15 @@ export default {
key: this.$t('users.Comment')
}
]
},
confirmUrl() {
let url = ''
if (!this.object[`is_${this.currentEdit}_bound`]) {
url = `/core/auth/${this.currentEdit}/qr/bind/?redirect_url=${this.$route.fullPath}`
} else {
url = `/api/v1/authentication/${this.currentEdit}/qr/unbind/`
}
return url
}
},
methods: {
@@ -309,10 +319,11 @@ export default {
return backendList
},
verifyDone() {
const url = this.confirmUrl
if (!this.object[`is_${this.currentEdit}_bound`]) {
window.location.href = `/core/auth/${this.currentEdit}/qr/bind/?redirect_url=${this.$route.fullPath}`
window.location.href = url
} else {
this.$axios.post(`/api/v1/authentication/${this.currentEdit}/qr/unbind/`).then(res => {
this.$axios.post(url).then(res => {
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$store.dispatch('users/getProfile')
})