mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-05-13 19:58:05 +00:00

Some checks are pending
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
133 lines
No EOL
4.6 KiB
HTML
133 lines
No EOL
4.6 KiB
HTML
{{define "modals/twoFactorModal"}}
|
|
<a-modal id="two-factor-modal" v-model="twoFactorModal.visible" :title="twoFactorModal.title" :closable="true"
|
|
:class="themeSwitcher.currentTheme">
|
|
<template v-if="twoFactorModal.type === 'set'">
|
|
<p>{{ i18n "pages.settings.security.twoFactorModalSteps" }}</p>
|
|
<a-divider></a-divider>
|
|
<p>{{ i18n "pages.settings.security.twoFactorModalFirstStep" }}</p>
|
|
<div :style="{ display: 'flex', alignItems: 'center', flexDirection: 'column', gap: '12px' }">
|
|
<div class="qr-bg" :style="{ width: '180px', height: '180px' }">
|
|
<canvas @click="copy(twoFactorModal.token)" id="twofactor-qrcode" class="qr-cv"></canvas>
|
|
</div>
|
|
<span :style="{ fontSize: '12px', fontFamily: 'monospace' }">[[ twoFactorModal.token ]]</span>
|
|
</div>
|
|
<a-divider></a-divider>
|
|
<p>{{ i18n "pages.settings.security.twoFactorModalSecondStep" }}</p>
|
|
<a-input v-model.trim="twoFactorModal.enteredCode" :style="{ width: '100%' }"></a-input>
|
|
</template>
|
|
<template v-if="twoFactorModal.type === 'remove'">
|
|
<p>{{ i18n "pages.settings.security.twoFactorModalRemoveStep" }}</p>
|
|
<a-input v-model.trim="twoFactorModal.enteredCode" :style="{ width: '100%' }"></a-input>
|
|
</template>
|
|
<template slot="footer">
|
|
<a-button @click="twoFactorModal.cancel">
|
|
<span>{{ i18n "cancel" }}</span>
|
|
</a-button>
|
|
<a-button type="primary" :disabled="twoFactorModal.enteredCode.length < 6" @click="twoFactorModal.ok">
|
|
<span>{{ i18n "confirm" }}</span>
|
|
</a-button>
|
|
</template>
|
|
</a-modal>
|
|
|
|
<script>
|
|
const twoFactorModal = {
|
|
title: '',
|
|
fileName: '',
|
|
token: '',
|
|
enteredCode: '',
|
|
visible: false,
|
|
type: 'set',
|
|
confirm: null,
|
|
totpObject: null,
|
|
qrImage: "",
|
|
ok() {
|
|
if (twoFactorModal.totpObject.generate() === twoFactorModal.enteredCode) {
|
|
ObjectUtil.execute(twoFactorModal.confirm, true)
|
|
|
|
twoFactorModal.close()
|
|
|
|
switch (twoFactorModal.type) {
|
|
case 'set':
|
|
Vue.prototype.$message['success']('{{ i18n "pages.settings.security.twoFactorModalSetSuccess" }}')
|
|
break;
|
|
case 'remove':
|
|
Vue.prototype.$message['success']('{{ i18n "pages.settings.security.twoFactorModalDeleteSuccess" }}')
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
Vue.prototype.$message['error']('{{ i18n "pages.settings.security.twoFactorModalError" }}')
|
|
}
|
|
},
|
|
cancel() {
|
|
ObjectUtil.execute(twoFactorModal.confirm, false)
|
|
|
|
twoFactorModal.close()
|
|
},
|
|
show: function ({
|
|
title = '',
|
|
token = '',
|
|
type = 'set',
|
|
confirm = (success) => { }
|
|
}) {
|
|
this.title = title;
|
|
this.token = token;
|
|
this.visible = true;
|
|
this.confirm = confirm;
|
|
this.type = type;
|
|
|
|
this.totpObject = new OTPAuth.TOTP({
|
|
issuer: "3x-ui",
|
|
label: "Administrator",
|
|
algorithm: "SHA1",
|
|
digits: 6,
|
|
period: 30,
|
|
secret: twoFactorModal.token,
|
|
});
|
|
},
|
|
close: function () {
|
|
twoFactorModal.enteredCode = "";
|
|
twoFactorModal.visible = false;
|
|
},
|
|
};
|
|
|
|
const twoFactorModalApp = new Vue({
|
|
delimiters: ['[[', ']]'],
|
|
el: '#two-factor-modal',
|
|
data: {
|
|
twoFactorModal: twoFactorModal,
|
|
},
|
|
updated() {
|
|
if (
|
|
this.twoFactorModal.visible &&
|
|
this.twoFactorModal.type === 'set' &&
|
|
document.getElementById('twofactor-qrcode')
|
|
) {
|
|
this.setQrCode('twofactor-qrcode', this.twoFactorModal.totpObject.toString());
|
|
}
|
|
},
|
|
methods: {
|
|
setQrCode(elementId, content) {
|
|
new QRious({
|
|
element: document.getElementById(elementId),
|
|
size: 200,
|
|
value: content,
|
|
background: 'white',
|
|
backgroundAlpha: 0,
|
|
foreground: 'black',
|
|
padding: 2,
|
|
level: 'L'
|
|
});
|
|
},
|
|
copy(content) {
|
|
ClipboardManager
|
|
.copyText(content)
|
|
.then(() => {
|
|
app.$message.success('{{ i18n "copied" }}')
|
|
})
|
|
},
|
|
}
|
|
});
|
|
</script>
|
|
{{end}} |