mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
fix: mfa 二次验证 bug 修复
This commit is contained in:
parent
68db3cf389
commit
23bb379afe
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/jwt"
|
"github.com/1Panel-dev/1Panel/backend/utils/jwt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/mfa"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
@ -68,11 +69,7 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if mfa.Value == "enable" {
|
if mfa.Value == "enable" {
|
||||||
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
|
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value, MfaSecret: mfaSecret.Value}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return u.generateSession(c, info.Name, info.AuthMethod)
|
return u.generateSession(c, info.Name, info.AuthMethod)
|
||||||
@ -91,7 +88,16 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLogi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, constant.ErrAuth
|
return nil, constant.ErrAuth
|
||||||
}
|
}
|
||||||
if info.Password != pass && nameSetting.Value == info.Name {
|
if info.Password != pass && nameSetting.Value != info.Name {
|
||||||
|
return nil, constant.ErrAuth
|
||||||
|
}
|
||||||
|
|
||||||
|
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
success := mfa.ValidCode(info.Code, mfaSecret.Value)
|
||||||
|
if !success {
|
||||||
return nil, constant.ErrAuth
|
return nil, constant.ErrAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ export default {
|
|||||||
rePassword: 'Confirm Password',
|
rePassword: 'Confirm Password',
|
||||||
welcome: 'Welcome back, please enter your username and password to log in!',
|
welcome: 'Welcome back, please enter your username and password to log in!',
|
||||||
errorAuthInfo: 'The user name or password you entered is incorrect, please re-enter!',
|
errorAuthInfo: 'The user name or password you entered is incorrect, please re-enter!',
|
||||||
|
errorMfaInfo: 'Incorrect authentication information, please try again!',
|
||||||
captchaHelper: 'Please enter the verification code',
|
captchaHelper: 'Please enter the verification code',
|
||||||
errorCaptcha: 'Verification code error!',
|
errorCaptcha: 'Verification code error!',
|
||||||
safeEntrance: 'Please use the correct entry to log in to the panel',
|
safeEntrance: 'Please use the correct entry to log in to the panel',
|
||||||
|
@ -110,6 +110,7 @@ export default {
|
|||||||
rePassword: '确认密码',
|
rePassword: '确认密码',
|
||||||
welcome: '欢迎回来,请输入用户名和密码登录!',
|
welcome: '欢迎回来,请输入用户名和密码登录!',
|
||||||
errorAuthInfo: '您输入的用户名或密码不正确,请重新输入!',
|
errorAuthInfo: '您输入的用户名或密码不正确,请重新输入!',
|
||||||
|
errorMfaInfo: '错误的验证信息,请重试!',
|
||||||
captchaHelper: '请输入验证码',
|
captchaHelper: '请输入验证码',
|
||||||
errorCaptcha: '验证码错误!',
|
errorCaptcha: '验证码错误!',
|
||||||
safeEntrance: '请使用正确的入口登录面板',
|
safeEntrance: '请使用正确的入口登录面板',
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
theme="cobalt"
|
theme="cobalt"
|
||||||
:styleActiveLine="true"
|
:styleActiveLine="true"
|
||||||
:extensions="extensions"
|
:extensions="extensions"
|
||||||
|
@ready="handleReady"
|
||||||
v-model="redisConf"
|
v-model="redisConf"
|
||||||
/>
|
/>
|
||||||
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
|
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
|
||||||
@ -127,7 +128,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { reactive, ref } from 'vue';
|
import { nextTick, reactive, ref, shallowRef } from 'vue';
|
||||||
import { Codemirror } from 'vue-codemirror';
|
import { Codemirror } from 'vue-codemirror';
|
||||||
import { javascript } from '@codemirror/lang-javascript';
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
import LayoutContent from '@/layout/layout-content.vue';
|
import LayoutContent from '@/layout/layout-content.vue';
|
||||||
@ -147,6 +148,11 @@ const extensions = [javascript(), oneDark];
|
|||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const view = shallowRef();
|
||||||
|
const handleReady = (payload) => {
|
||||||
|
view.value = payload.view;
|
||||||
|
};
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
port: 6379,
|
port: 6379,
|
||||||
@ -332,8 +338,22 @@ const loadform = async () => {
|
|||||||
const loadConfFile = async () => {
|
const loadConfFile = async () => {
|
||||||
const pathRes = await loadBaseDir();
|
const pathRes = await loadBaseDir();
|
||||||
let path = `${pathRes.data}/apps/redis/${redisName.value}/conf/redis.conf`;
|
let path = `${pathRes.data}/apps/redis/${redisName.value}/conf/redis.conf`;
|
||||||
const res = await LoadFile({ path: path });
|
loading.value = true;
|
||||||
redisConf.value = res.data;
|
await LoadFile({ path: path })
|
||||||
|
.then((res) => {
|
||||||
|
loading.value = false;
|
||||||
|
redisConf.value = res.data;
|
||||||
|
nextTick(() => {
|
||||||
|
const state = view.value.state;
|
||||||
|
view.value.dispatch({
|
||||||
|
selection: { anchor: state.doc.length, head: state.doc.length },
|
||||||
|
scrollIntoView: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
@ -98,7 +98,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<span class="networkOption">
|
<span class="networkOption" v-if="networkChoose === 'all'">
|
||||||
|
{{ $t('commons.table.all') }}
|
||||||
|
</span>
|
||||||
|
<span v-else class="networkOption">
|
||||||
{{ networkChoose }}
|
{{ networkChoose }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -17,7 +17,13 @@
|
|||||||
@search="search"
|
@search="search"
|
||||||
>
|
>
|
||||||
<el-table-column type="selection" fix />
|
<el-table-column type="selection" fix />
|
||||||
<el-table-column :label="$t('commons.table.name')" min-width="100" prop="name" fix />
|
<el-table-column
|
||||||
|
:label="$t('commons.table.name')"
|
||||||
|
show-overflow-tooltip=""
|
||||||
|
min-width="100"
|
||||||
|
prop="name"
|
||||||
|
fix
|
||||||
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:label="$t('terminal.command')"
|
:label="$t('terminal.command')"
|
||||||
min-width="300"
|
min-width="300"
|
||||||
@ -109,7 +115,9 @@ let commandInfo = reactive<Command.CommandOperate>({
|
|||||||
const cmdVisiable = ref<boolean>(false);
|
const cmdVisiable = ref<boolean>(false);
|
||||||
|
|
||||||
const onCreate = async () => {
|
const onCreate = async () => {
|
||||||
restcommandForm();
|
commandInfo.id = 0;
|
||||||
|
commandInfo.name = '';
|
||||||
|
commandInfo.command = '';
|
||||||
operate.value = 'create';
|
operate.value = 'create';
|
||||||
cmdVisiable.value = true;
|
cmdVisiable.value = true;
|
||||||
};
|
};
|
||||||
@ -156,11 +164,6 @@ const batchDelete = async (row: Command.CommandInfo | null) => {
|
|||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
function restcommandForm() {
|
|
||||||
if (commandInfoRef.value) {
|
|
||||||
commandInfoRef.value.resetFields();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.edit'),
|
label: i18n.global.t('commons.button.edit'),
|
||||||
|
@ -75,7 +75,7 @@ import { addHost, testByInfo } from '@/api/modules/host';
|
|||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
|
||||||
const dialogVisiable = ref();
|
const dialogVisiable = ref();
|
||||||
type FormInstance = InstanceType<typeof ElForm>;
|
type FormInstance = InstanceType<typeof ElForm>;
|
||||||
@ -143,7 +143,7 @@ const submitAddHost = (formEl: FormInstance | undefined, ops: string) => {
|
|||||||
if (res.data) {
|
if (res.data) {
|
||||||
MsgSuccess(i18n.global.t('terminal.connTestOk'));
|
MsgSuccess(i18n.global.t('terminal.connTestOk'));
|
||||||
} else {
|
} else {
|
||||||
MsgSuccess(i18n.global.t('terminal.connTestFailed'));
|
MsgError(i18n.global.t('terminal.connTestFailed'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -84,6 +84,9 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
<span v-if="errMfaInfo" class="input-error" style="line-height: 14px">
|
||||||
|
{{ $t('commons.login.errorMfaInfo') }}
|
||||||
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button class="login-button" type="primary" size="default" round @click="mfaLogin()">
|
<el-button class="login-button" type="primary" size="default" round @click="mfaLogin()">
|
||||||
@ -176,6 +179,7 @@ const menuStore = MenuStore();
|
|||||||
|
|
||||||
const errAuthInfo = ref(false);
|
const errAuthInfo = ref(false);
|
||||||
const errCaptcha = ref(false);
|
const errCaptcha = ref(false);
|
||||||
|
const errMfaInfo = ref(false);
|
||||||
|
|
||||||
const isFirst = ref();
|
const isFirst = ref();
|
||||||
|
|
||||||
@ -265,6 +269,7 @@ const login = (formEl: FormInstance | undefined) => {
|
|||||||
}
|
}
|
||||||
if (res.data.mfaStatus === 'enable') {
|
if (res.data.mfaStatus === 'enable') {
|
||||||
mfaShow.value = true;
|
mfaShow.value = true;
|
||||||
|
errMfaInfo.value = false;
|
||||||
mfaLoginForm.secret = res.data.mfaSecret;
|
mfaLoginForm.secret = res.data.mfaSecret;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -284,7 +289,11 @@ const mfaLogin = async () => {
|
|||||||
if (mfaLoginForm.code) {
|
if (mfaLoginForm.code) {
|
||||||
mfaLoginForm.name = loginForm.name;
|
mfaLoginForm.name = loginForm.name;
|
||||||
mfaLoginForm.password = loginForm.password;
|
mfaLoginForm.password = loginForm.password;
|
||||||
await mfaLoginApi(mfaLoginForm);
|
const res = await mfaLoginApi(mfaLoginForm);
|
||||||
|
if (res.code === 406) {
|
||||||
|
errMfaInfo.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
globalStore.setLogStatus(true);
|
globalStore.setLogStatus(true);
|
||||||
menuStore.setMenuList([]);
|
menuStore.setMenuList([]);
|
||||||
MsgSuccess(i18n.global.t('commons.msg.loginSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.loginSuccess'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user