This is an automated email from the ASF dual-hosted git repository.
pearl11594 pushed a commit to branch 2fa-ui
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/2fa-ui by this push:
new 936fe565c0c register 2fa for user
936fe565c0c is described below
commit 936fe565c0c25e3034ae3cd410ce8e21478d165e
Author: Pearl Dsilva <[email protected]>
AuthorDate: Tue Oct 18 16:25:46 2022 +0530
register 2fa for user
---
ui/package-lock.json | 20 +++++++
ui/package.json | 4 +-
ui/public/locales/en.json | 7 +++
ui/src/config/section/user.js | 9 +++
ui/src/core/lazy_lib/icons_use.js | 2 +
ui/src/store/modules/user.js | 3 +
ui/src/views/dashboard/TwoFa.vue | 3 +-
ui/src/views/iam/RegisterTwoFactorAuth.vue | 94 ++++++++++++++++++++++++++++++
8 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 8ae7034a544..6ae1e0367d5 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -18596,6 +18596,11 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
+ "qrious": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/qrious/-/qrious-4.0.2.tgz",
+ "integrity":
"sha512-xWPJIrK1zu5Ypn898fBp8RHkT/9ibquV2Kv24S/JY9VYEhMBMKur1gHVsOiNUh7PHP9uCgejjpZUHUIXXKoU/g=="
+ },
"qs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
@@ -22530,6 +22535,21 @@
"loader-utils": "^2.0.0"
}
},
+ "vue-qrious": {
+ "version": "3.1.0",
+ "resolved":
"https://registry.npmjs.org/vue-qrious/-/vue-qrious-3.1.0.tgz",
+ "integrity":
"sha512-qC5jw94b/VbUHFxYfumwqhSXKBJNEmaimhpwEmudqOiORMd5yPCFn/mPInnP5nWobvhvcV+S+U3Ger6w2dLyfQ==",
+ "requires": {
+ "tslib": "^2.4.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity":
"sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ }
+ }
+ },
"vue-router": {
"version": "4.0.14",
"resolved":
"https://registry.npmjs.org/vue-router/-/vue-router-4.0.14.tgz",
diff --git a/ui/package.json b/ui/package.json
index e27ec671fa1..31ad8bd9d3e 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -53,16 +53,18 @@
"moment": "^2.26.0",
"npm-check-updates": "^6.0.1",
"nprogress": "^0.2.0",
+ "qrious": "^4.0.2",
"vue": "^3.2.31",
"vue-chartjs": "^4.0.7",
"vue-clipboard2": "^0.3.1",
"vue-cropper": "^1.0.2",
"vue-i18n": "^9.1.6",
"vue-loader": "^16.2.0",
+ "vue-qrious": "^3.1.0",
"vue-router": "^4.0.14",
+ "vue-uuid": "^3.0.0",
"vue-web-storage": "^6.1.0",
"vue3-clipboard": "^1.0.0",
- "vue-uuid": "^3.0.0",
"vuedraggable": "^4.0.3",
"vuex": "^4.0.0-0"
},
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 06ba0e602ae..4a23ce4adc0 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -136,6 +136,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 for 2FA authentication",
"label.action.register.iso": "Register ISO",
"label.action.register.template": "Register template from URL",
"label.action.release.ip": "Release IP",
@@ -409,6 +410,7 @@
"label.compute.offerings": "Compute offerings",
"label.configuration": "Configuration",
"label.configure": "Configure",
+"label.configure.app": "Configure the App",
"label.configure.ldap": "Configure LDAP",
"label.configure.ovs": "Configure Ovs",
"label.configure.sticky.policy": "Configure sticky policy",
@@ -678,6 +680,7 @@
"label.endipv6": "IPv6 end IP",
"label.endpoint": "Endpoint",
"label.endport": "End port",
+"label.enter.code": "Enter 6-digit code",
"label.enter.token": "Enter token",
"label.error": "Error",
"label.error.caught": "Error caught",
@@ -1749,6 +1752,7 @@
"label.transportzoneuuid": "Transport zone UUID",
"label.try.again": "Try again",
"label.tuesday": "Tuesday",
+"label.two.factor.secret": "Your Two-factor secret",
"label.type": "Type",
"label.type.id": "Type ID",
"label.ucs": "UCS",
@@ -2601,6 +2605,9 @@
"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": "enter this text code",
"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 e17e998179e..5a298134839 100644
--- a/ui/src/config/section/user.js
+++ b/ui/src/config/section/user.js
@@ -106,6 +106,15 @@ export default {
},
component: shallowRef(defineAsyncComponent(() =>
import('@/views/iam/ConfigureSamlSsoAuth.vue')))
},
+ {
+ // update API name
+ api: 'updateUser',
+ icon: 'scan-outlined',
+ label: 'label.action.register.2FA.user.auth',
+ dataView: true,
+ popup: true,
+ component: shallowRef(defineAsyncComponent(() =>
import('@/views/iam/RegisterTwoFactorAuth.vue')))
+ },
{
api: 'deleteUser',
icon: 'delete-outlined',
diff --git a/ui/src/core/lazy_lib/icons_use.js
b/ui/src/core/lazy_lib/icons_use.js
index a5db66bf870..b1bcc86cdd0 100644
--- a/ui/src/core/lazy_lib/icons_use.js
+++ b/ui/src/core/lazy_lib/icons_use.js
@@ -138,6 +138,7 @@ import {
SaveOutlined,
ScheduleOutlined,
ScissorOutlined,
+ ScanOutlined,
SearchOutlined,
SettingOutlined,
ShareAltOutlined,
@@ -285,6 +286,7 @@ export default {
app.component('SafetyOutlined', SafetyOutlined)
app.component('SaveOutlined', SaveOutlined)
app.component('ScheduleOutlined', ScheduleOutlined)
+ app.component('ScanOutlined', ScanOutlined)
app.component('ScissorOutlined', ScissorOutlined)
app.component('SearchOutlined', SearchOutlined)
app.component('SettingOutlined', SettingOutlined)
diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js
index 859f5e01d0a..262ac7676aa 100644
--- a/ui/src/store/modules/user.js
+++ b/ui/src/store/modules/user.js
@@ -393,6 +393,9 @@ const user = {
},
SetDarkMode ({ commit }, darkMode) {
commit('SET_DARK_MODE', darkMode)
+ },
+ SetLoginFlag ({ commit }, loggedIn) {
+ commit('SET_LOGIN_FLAG', loggedIn)
}
}
}
diff --git a/ui/src/views/dashboard/TwoFa.vue b/ui/src/views/dashboard/TwoFa.vue
index 19924c03747..31fd375fe4e 100644
--- a/ui/src/views/dashboard/TwoFa.vue
+++ b/ui/src/views/dashboard/TwoFa.vue
@@ -78,7 +78,8 @@ export default {
})
},
handleSubmit () {
- // Add logic to set loginFlag to true
+ // Add logic to set loginFlag to true
+ this.$store.dispatch('SetLoginFlag', true)
}
}
}
diff --git a/ui/src/views/iam/RegisterTwoFactorAuth.vue
b/ui/src/views/iam/RegisterTwoFactorAuth.vue
new file mode 100644
index 00000000000..c9378772fb4
--- /dev/null
+++ b/ui/src/views/iam/RegisterTwoFactorAuth.vue
@@ -0,0 +1,94 @@
+// 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>
+ <h3> {{ $t('label.configure.app') }} </h3>
+ <div> {{ $t('message.two.fa.auth.register.account') }} </div>
+ <vue-qrious
+ class="center-align"
+ :value="resource.id"
+ @change="onDataUrlChange"
+ />
+ <br />
+ <div> {{ $t('message.two.fa.static.pin.part1') }} <a
@click="generateStaticPin"> {{ $t('message.two.fa.static.pin.part2')
}}</a></div>
+ <br />
+ <h3> {{ $t('label.enter.code') }} </h3>
+ <a-form @finish="submitPin" v-ctrl-enter="submitPin" class="container">
+ <a-input v-model:value="pin" />
+ <div :span="24">
+ <a-button ref="submit" type="primary" @click="submitPin">{{
$t('label.ok') }}</a-button>
+ </div>
+ </a-form>
+ <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>
+</template>
+<script>
+import VueQrious from 'vue-qrious'
+export default {
+ name: 'RegisterTwoFactorAuth',
+ props: {
+ resource: {
+ type: Object,
+ required: true
+ }
+ },
+ components: {
+ VueQrious
+ },
+ data () {
+ return {
+ dataUrl: '',
+ pin: '',
+ showPin: false
+ }
+ },
+ methods: {
+ onDataUrlChange (dataUrl) {
+ this.dataUrl = dataUrl
+ },
+ submitPin () {
+ // call api
+ },
+ generateStaticPin () {
+ this.pin = Math.floor(100000 + Math.random() * 900000)
+ this.showPin = true
+ },
+ onCloseModal () {
+ this.showPin = false
+ }
+ }
+}
+</script>
+<style scoped>
+ .center-align {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ }
+ .container {
+ display: flex;
+ }
+</style>