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 9e1aea878b75f22dbcd97eab1d57f0ecb0460248 Author: Harikrishna Patnala <[email protected]> AuthorDate: Thu Nov 24 12:57:51 2022 +0530 Added Disable 2FA on form closure --- ui/src/views/AutogenView.vue | 8 +- ui/src/views/dashboard/VerifyTwoFa.vue | 172 +++++++++++++++++++++++++++++ ui/src/views/iam/RegisterTwoFactorAuth.vue | 21 ++-- 3 files changed, 191 insertions(+), 10 deletions(-) diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 85c90e6c3a6..5450191dc8b 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -117,7 +117,7 @@ :maskClosable="false" :cancelText="$t('label.cancel')" style="top: 20px;" - @cancel="closeAction" + @cancel="cancelAction" :confirmLoading="actionLoading" :footer="null" centered @@ -161,7 +161,7 @@ :ok-button-props="getOkProps()" :cancel-button-props="getCancelProps()" :confirmLoading="actionLoading" - @cancel="closeAction" + @cancel="cancelAction" centered > <template #title> @@ -992,6 +992,10 @@ export default { this.showAction = false this.currentAction = {} }, + cancelAction () { + eventBus.emit('action-closing', { action: this.currentAction }) + this.closeAction() + }, onRowSelectionChange (selection) { this.selectedRowKeys = selection if (selection?.length > 0) { diff --git a/ui/src/views/dashboard/VerifyTwoFa.vue b/ui/src/views/dashboard/VerifyTwoFa.vue new file mode 100644 index 00000000000..acbd87170a5 --- /dev/null +++ b/ui/src/views/dashboard/VerifyTwoFa.vue @@ -0,0 +1,172 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +<template> + <a-form> + <img + v-if="$config.banner" + :style="{ + width: $config.theme['@banner-width'], + height: $config.theme['@banner-height'] + }" + :src="$config.banner" + class="user-layout-logo" + alt="logo"> + <h1 style="text-align: center; font-size: 24px; color: gray"> {{ $t('label.two.factor.authentication') }} </h1> + <br /> + <br /> + <a-form + :ref="formRef" + :model="form" + :rules="rules" + @finish="handleSubmit" + layout="vertical"> + <a-form-item name="code" ref="code"> + <a-input + class="center-align" + style="width: 400px" + v-model:value="form.code" + placeholder="xxxxxxx" /> + </a-form-item> + <div :span="24" class="center-align top-padding"> + <a-button + :loading="loading" + ref="submit" + type="primary" + class="center-align" + @click="handleSubmit">{{ $t('label.verify') }} + </a-button> + </div> + <p style="text-align: center" v-html="$t('message.two.fa.auth')"></p> + </a-form> + </a-form> +</template> +<script> + +import { api } from '@/api' +import { ref, reactive, toRaw } from 'vue' + +export default { + name: 'TwoFa', + data () { + return { + twoFAresponse: false + } + }, + created () { + this.initForm() + }, + methods: { + initForm () { + this.formRef = ref() + this.form = reactive({}) + this.rules = reactive({ + code: [{ required: true, message: this.$t('message.error.authentication.code') }] + }) + }, + handleSubmit () { + this.formRef.value.validate().then(() => { + const values = toRaw(this.form) + api('validateUserTwoFactorAuthenticationCode', { '2facode': values.code }).then(response => { + this.twoFAresponse = true + if (this.twoFAresponse) { + this.$notification.destroy() + this.$store.commit('SET_COUNT_NOTIFY', 0) + this.$store.commit('SET_LOGIN_FLAG', true) + this.$router.push({ path: '/dashboard' }).catch(() => {}) + + this.$message.success({ + content: `${this.$t('label.action.enable.two.factor.authentication')}`, + duration: 2 + }) + this.$emit('refresh-data') + } + console.log(response) + }).catch(error => { + this.$notification.error({ + message: this.$t('message.request.failed'), + description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message + }) + }) + }) + } + } +} +</script> +<style lang="less" scoped> + .center-align { + display: block; + margin-left: auto; + margin-right: auto; + } + .top-padding { + padding-top: 35px; + } + .note { + text-align: center; + color: grey; + padding-top: 10px; + } + + .user-layout { + height: 100%; + + &-container { + padding: 3rem 0; + width: 100%; + + @media (min-height:600px) { + padding: 0; + position: relative; + top: 50%; + transform: translateY(-50%); + margin-top: -50px; + } + } + + &-logo { + border-style: none; + margin: 0 auto 2rem; + display: block; + + .mobile & { + max-width: 300px; + margin-bottom: 1rem; + } + } + + &-footer { + display: flex; + flex-direction: column; + position: absolute; + bottom: 20px; + text-align: center; + width: 100%; + + @media (max-height: 600px) { + position: relative; + margin-top: 50px; + } + + label { + width: 368px; + font-weight: 500; + margin: 0 auto; + } + } + } +</style> diff --git a/ui/src/views/iam/RegisterTwoFactorAuth.vue b/ui/src/views/iam/RegisterTwoFactorAuth.vue index c99bab05ff3..122c484eec7 100644 --- a/ui/src/views/iam/RegisterTwoFactorAuth.vue +++ b/ui/src/views/iam/RegisterTwoFactorAuth.vue @@ -20,7 +20,6 @@ <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 @@ -42,7 +41,7 @@ <a-button ref="submit" type="primary" @click="setup2FAProvider">{{ $t('label.setup') }}</a-button> </div> </div> - <div v-if="show2FAdetails"> + <div v-if="twoFAenabled"> <div v-if="selectedProvider !== 'staticpin'"> <br /> <p v-html="$t('message.two.fa.register.account')"></p> @@ -89,6 +88,7 @@ import { api } from '@/api' import VueQrious from 'vue-qrious' +import eventBus from '@/config/eventBus' export default { name: 'RegisterTwoFactorAuth', props: { @@ -107,8 +107,8 @@ export default { pin: '', code: '', showPin: false, - show2FAdetails: false, twoFAenabled: false, + twoFAverified: false, providers: [], selectedProvider: null } @@ -116,6 +116,13 @@ export default { mounted () { this.list2FAProviders() }, + created () { + eventBus.on('action-closing', (args) => { + if (args.action.api === 'setupUserTwoFactorAuthentication' && this.twoFAenabled && !this.twoFAverified) { + this.disable2FAProvider() + } + }) + }, methods: { onDataUrlChange (dataUrl) { this.dataUrl = dataUrl @@ -136,8 +143,8 @@ export default { if (this.selectedProvider === 'staticpin') { this.showPin = true } - this.show2FAdetails = true this.twoFAenabled = true + this.twoFAverified = false }).catch(error => { this.$notification.error({ message: this.$t('message.request.failed'), @@ -149,8 +156,8 @@ export default { disable2FAProvider () { api('setupUserTwoFactorAuthentication', { enable: false }).then(response => { this.showPin = false - this.show2FAdetails = false this.twoFAenabled = false + this.twoFAverified = false }).catch(error => { this.$notification.error({ message: this.$t('message.request.failed'), @@ -169,6 +176,7 @@ export default { content: `${this.$t('label.action.enable.two.factor.authentication')}`, duration: 2 }) + this.twoFAverified = true this.$emit('refresh-data') }).catch(error => { this.$notification.error({ @@ -186,9 +194,6 @@ export default { }, onCloseModal () { this.showPin = false - }, - onCloseModalDisable2FA () { - this.disable2FAProvider() } } }
