You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ha...@apache.org on 2022/11/24 03:43:42 UTC
[cloudstack] 01/03: Some improvements of messages in UI
This is an automated email from the ASF dual-hosted git repository.
harikrishna pushed a commit to branch 2FA
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 1fbf35312717b8e72e5f6626bfe8e30095581e81
Author: Harikrishna Patnala <ha...@gmail.com>
AuthorDate: Thu Nov 24 00:14:56 2022 +0530
Some improvements of messages in UI
---
ui/public/locales/en.json | 21 ++--
ui/src/config/section/user.js | 2 +-
ui/src/views/iam/RegisterTwoFactorAuth.vue | 171 +++++++++++++++++------------
3 files changed, 115 insertions(+), 79 deletions(-)
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 3031569654e..7f085b22490 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -137,8 +137,7 @@
"label.action.reboot.systemvm": "Reboot system VM",
"label.action.recover.volume": "Recover volume",
"label.action.recurring.snapshot": "Recurring snapshots",
-"label.action.register.2FA.user.auth": "Register user Two Factor Authentication",
-"label.action.disable.2FA.user.auth": "Disable user Two Factor Authentication",
+"label.action.disable.2FA.user.auth": "Disable User Two Factor Authentication",
"label.action.register.iso": "Register ISO",
"label.action.register.template": "Register template from URL",
"label.action.release.ip": "Release IP",
@@ -153,6 +152,7 @@
"label.action.router.health.checks": "Get health checks result",
"label.action.run.diagnostics": "Run diagnostics",
"label.action.secure.host": "Provision host security keys",
+"label.action.setup.2FA.user.auth": "Setup User Two Factor Authentication",
"label.action.start.instance": "Start instance",
"label.action.start.router": "Start router",
"label.action.start.systemvm": "Start system VM",
@@ -678,7 +678,8 @@
"label.endipv6": "IPv6 end IP",
"label.endpoint": "Endpoint",
"label.endport": "End port",
-"label.enter.code": "Enter authentication code to verify",
+"label.enter.code": "Enter 2FA code to verify",
+"label.enter.static.pin": "Enter static pin to verify",
"label.enter.token": "Enter token",
"label.error": "Error",
"label.error.caught": "Error caught",
@@ -1738,7 +1739,8 @@
"label.transportzoneuuid": "Transport zone UUID",
"label.try.again": "Try again",
"label.tuesday": "Tuesday",
-"label.two.factor.secret": "Your Two-factor secret",
+"label.two.factor.authentication.secret.key": "Your Two factor authentication secret key",
+"label.two.factor.authentication.static.pin": "Your Two factor authentication static pin",
"label.two.factor.authentication": "Two Factor Authentication",
"label.type": "Type",
"label.type.id": "Type ID",
@@ -1947,7 +1949,7 @@
"message.action.destroy.instance.with.backups": "Please confirm that you want to destroy the instance. There may be backups associated with the instance which will not be deleted.",
"message.action.destroy.systemvm": "Please confirm that you want to destroy the System VM.",
"message.action.destroy.volume": "Please confirm that you want to destroy the volume.",
-"message.action.disable.2FA.user.auth": "Please confirm that you want to disable user Two factor authentication.",
+"message.action.disable.2FA.user.auth": "Please confirm that you want to disable user two factor authentication.",
"message.action.disable.cluster": "Please confirm that you want to disable this cluster.",
"message.action.disable.physical.network": "Please confirm that you want to disable this physical network.",
"message.action.disable.pod": "Please confirm that you want to disable this pod.",
@@ -2586,10 +2588,11 @@
"message.template.type.change.warning": "WARNING: Changing the template type to SYSTEM will disable further changes to the template.",
"message.tooltip.reserved.system.netmask": "The network prefix that defines the pod subnet. Uses CIDR notation.",
"message.traffic.type.to.basic.zone": "traffic type to basic zone",
-"message.two.fa.auth": "Open the two-factor authentication app on your mobile device to view your authentication code",
-"message.two.fa.auth.register.account": "Open the two-factor authentication application and scan the QR code add the user account",
-"message.two.fa.static.pin.part1": "If you can't scan the QR code, ",
-"message.two.fa.static.pin.part2": "Click here to view the secret code",
+"message.two.fa.auth": "Open the two factor authentication application on your device to view your authentication code",
+"message.two.fa.register.account": "1. Open the authenticator application on your device <br>2. Scan the below QR code to add the user <br>3. If you cannot scan the QR code, enter the setup key manually <br>4. Verification of the 2FA code is mandatory to complete the 2FA setup",
+"message.two.fa.staticpin": "1. Use the generated static pin as 2FA code for two factor authentication<br>2. Verification of the 2FA code is mandatory to complete the 2FA setup",
+"message.two.fa.view.setup.key": "Click here to view the setup key",
+"message.two.fa.view.static.pin": "Click here to view the static pin",
"message.update.ipaddress.processing": "Updating IP Address...",
"message.update.resource.count": "Please confirm that you want to update resource counts for this account.",
"message.update.resource.count.domain": "Please confirm that you want to update resource counts for this domain.",
diff --git a/ui/src/config/section/user.js b/ui/src/config/section/user.js
index c7fe2a7606d..5936f387dd6 100644
--- a/ui/src/config/section/user.js
+++ b/ui/src/config/section/user.js
@@ -109,7 +109,7 @@ export default {
{
api: 'setupUserTwoFactorAuthentication',
icon: 'scan-outlined',
- label: 'label.action.register.2FA.user.auth',
+ label: 'label.action.setup.2FA.user.auth',
dataView: true,
popup: true,
show: (record, store) => {
diff --git a/ui/src/views/iam/RegisterTwoFactorAuth.vue b/ui/src/views/iam/RegisterTwoFactorAuth.vue
index 388e7fa3173..5887789256e 100644
--- a/ui/src/views/iam/RegisterTwoFactorAuth.vue
+++ b/ui/src/views/iam/RegisterTwoFactorAuth.vue
@@ -17,67 +17,72 @@
<template>
<div style="width:500px;height=500px">
- <h3> {{ $t('label.select.2fa.provider') }} </h3>
- <a-form
- :rules="rules"
- layout="vertical">
- <div class="form-layout" v-ctrl-enter="submitPin">
- <a-select
- v-model:value="selectedProvider"
- optionFilterProp="label"
- :filterOption="(input, option) => {
- return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
- }"
- style="width: 100%"
- @change="val => { handleSelectChange(val) }">
- <a-select-option
- v-for="(opt) in providers"
- :key="opt.name"
- :disabled="opt.enabled === false">
- {{ opt.name }}
- </a-select-option>
- </a-select>
- </div>
- <div v-if="show2FAdetails">
- <div v-if="selectedProvider === 'google'">
- <br />
- <div> {{ $t('message.two.fa.auth.register.account') }} </div>
- <vue-qrious
- class="center-align"
- :value="googleUrl"
- @change="onDataUrlChange"
- />
- </div>
- <div v-else-if="selectedProvider === 'staticpin'">
- <div> <a @click="setup2FAProvider"> {{ $t('message.two.fa.static.pin.part2') }}</a></div>
- </div>
- <div v-else-if="selectedProvider !== null && selectedProvider !== 'staticpin'">
- <div> {{ $t('message.two.fa.static.pin.part1') }} <a @click="setup2FAProvider"> {{ $t('message.two.fa.static.pin.part2') }}</a></div>
- </div>
- <div v-if="selectedProvider">
- <br />
- <h3> {{ $t('label.enter.code') }} </h3>
- <a-form @finish="submitPin" v-ctrl-enter="submitPin" class="container">
- <a-input v-model:value="code" />
- <div :span="24">
- <a-button ref="submit" type="primary" @click="submitPin">{{ $t('label.ok') }}</a-button>
- </div>
- </a-form>
+ <h3> {{ $t('label.select.2fa.provider') }} </h3>
+ <a-form
+ :rules="rules"
+ @close="onCloseModalDisable2FA()"
+ layout="vertical">
+ <div class="form-layout form-align" v-ctrl-enter="submitPin">
+ <a-select
+ v-model:value="selectedProvider"
+ optionFilterProp="label"
+ :filterOption="(input, option) => {
+ return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
+ }"
+ style="width: 100%"
+ @change="val => { handleSelectChange(val) }">
+ <a-select-option
+ v-for="(opt) in providers"
+ :key="opt.name"
+ :disabled="opt.enabled === false">
+ {{ opt.name }}
+ </a-select-option>
+ </a-select>
+ <div :span="24" v-if="selectedProvider">
+ <a-button ref="submit" type="primary" @click="setup2FAProvider">{{ $t('label.setup') }}</a-button>
+ </div>
</div>
+ <div v-if="show2FAdetails">
+ <div v-if="selectedProvider !== 'staticpin'">
+ <br />
+ <p v-html="$t('message.two.fa.register.account')"></p>
+ <vue-qrious
+ class="center-align"
+ :value="googleUrl"
+ @change="onDataUrlChange"
+ />
+ <div style="text-align: center"> <a @click="showConfiguredPin"> {{ $t('message.two.fa.view.setup.key') }}</a></div>
+ </div>
+ <div v-if="selectedProvider === 'staticpin'">
+ <br>
+ <p v-html="$t('message.two.fa.staticpin')"></p>
+ <br>
+ <div> <a @click="showConfiguredPin"> {{ $t('message.two.fa.view.static.pin') }}</a></div>
+ </div>
+ <div v-if="selectedProvider">
+ <br />
+ <h3> {{ $t('label.enter.code') }} </h3>
+ <a-form @finish="submitPin" v-ctrl-enter="submitPin" class="container">
+ <a-input v-model:value="code" />
+ <div :span="24">
+ <a-button ref="submit" type="primary" @click="submitPin">{{ $t('label.ok') }}</a-button>
+ </div>
+ </a-form>
+ </div>
- <a-modal
- v-if="showPin"
- :visible="showPin"
- :title="$t('label.two.factor.secret')"
- :closable="true"
- :footer="null"
- @cancel="onCloseModal"
- centered
- width="450px">
- <div> {{ pin }} </div>
- </a-modal>
- </div>
- </a-form>
+ <a-modal
+ v-if="showPin"
+ :visible="showPin"
+ :title="$t(selectedProvider === 'staticpin'? 'label.two.factor.authentication.static.pin' : 'label.two.factor.authentication.secret.key')"
+ :closable="true"
+ :footer="null"
+ @cancel="onCloseModal"
+ centered
+ width="450px">
+ <div> {{ pin }} </div>
+ </a-modal>
+ </div>
+ </a-form>
</div>
</template>
<script>
@@ -103,6 +108,7 @@ export default {
code: '',
showPin: false,
show2FAdetails: false,
+ twoFAenabled: false,
providers: [],
selectedProvider: null
}
@@ -116,18 +122,35 @@ export default {
},
handleSelectChange (val) {
this.selectedProvider = val
- this.setup2FAProvider()
},
setup2FAProvider () {
- api('setupUserTwoFactorAuthentication', { provider: this.selectedProvider }).then(response => {
- console.log(response)
- this.pin = response.setupusertwofactorauthenticationresponse.setup2fa.secretcode
- if (this.selectedProvider === 'google') {
- this.username = response.setupusertwofactorauthenticationresponse.setup2fa.username
- this.googleUrl = 'otpauth://totp/CloudStack:' + this.username + '?secret=' + this.pin + '&issuer=CloudStack'
- }
- this.showPin = true
- this.show2FAdetails = true
+ if (!this.twoFAenabled) {
+ api('setupUserTwoFactorAuthentication', { provider: this.selectedProvider }).then(response => {
+ console.log(response)
+ this.pin = response.setupusertwofactorauthenticationresponse.setup2fa.secretcode
+ if (this.selectedProvider === 'google') {
+ this.username = response.setupusertwofactorauthenticationresponse.setup2fa.username
+ this.googleUrl = 'otpauth://totp/CloudStack:' + this.username + '?secret=' + this.pin + '&issuer=CloudStack'
+ this.showPin = false
+ }
+ if (this.selectedProvider === 'staticpin') {
+ this.showPin = true
+ }
+ this.show2FAdetails = true
+ this.twoFAenabled = true
+ }).catch(error => {
+ this.$notification.error({
+ message: this.$t('message.request.failed'),
+ description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
+ })
+ })
+ }
+ },
+ disable2FAProvider () {
+ api('setupUserTwoFactorAuthentication', { enable: false }).then(response => {
+ this.showPin = false
+ this.show2FAdetails = false
+ this.twoFAenabled = false
}).catch(error => {
this.$notification.error({
message: this.$t('message.request.failed'),
@@ -158,8 +181,14 @@ export default {
closeAction () {
this.$emit('close-action')
},
+ showConfiguredPin () {
+ this.showPin = true
+ },
onCloseModal () {
this.showPin = false
+ },
+ onCloseModalDisable2FA () {
+ this.disable2FAProvider()
}
}
}
@@ -171,6 +200,10 @@ export default {
margin-left: auto;
margin-right: auto;
}
+ .form-align {
+ display: flex;
+ flex-direction: row;
+ }
.container {
display: flex;
}