mirror of
https://gitee.com/fit2cloud-feizhiyun/1Panel.git
synced 2024-12-02 03:48:02 +08:00
fix: 密码放到面板设置界面
This commit is contained in:
parent
eb2bfb80cf
commit
97c4410227
@ -131,7 +131,7 @@ const getTitle = (key: string) => {
|
||||
case 'nginx':
|
||||
return i18n.global.t('website.website');
|
||||
case 'mysql':
|
||||
return 'Mysql ' + i18n.global.t('menu.database');
|
||||
return 'MySQL ' + i18n.global.t('menu.database');
|
||||
case 'redis':
|
||||
return 'Redis ' + i18n.global.t('menu.database');
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ export default {
|
||||
backupList: 'Backup list',
|
||||
backList: 'Return',
|
||||
loadBackup: 'Import the backup',
|
||||
setting: 'Mysql Settings',
|
||||
setting: 'MySQL Settings',
|
||||
remoteAccess: 'Remote access',
|
||||
changePassword: 'Password change',
|
||||
changePasswordHelper:
|
||||
|
@ -19,7 +19,7 @@ const databaseRouter = {
|
||||
children: [
|
||||
{
|
||||
path: 'mysql',
|
||||
name: 'Mysql',
|
||||
name: 'MySQL',
|
||||
component: () => import('@/views/database/mysql/index.vue'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
|
@ -61,7 +61,7 @@ const toPage = (key: string) => {
|
||||
router.push({ name: 'Website' });
|
||||
}
|
||||
if (key === 'database') {
|
||||
router.push({ name: 'Mysql' });
|
||||
router.push({ name: 'MySQL' });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ import RouterButton from '@/components/router-button/index.vue';
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: 'Mysql',
|
||||
label: 'MySQL',
|
||||
path: '/databases/mysql',
|
||||
},
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<LayoutContent :title="'Mysql ' + $t('menu.database')">
|
||||
<LayoutContent :title="'MySQL ' + $t('menu.database')">
|
||||
<template #app>
|
||||
<AppStatus
|
||||
:app-key="'mysql'"
|
||||
@ -112,7 +112,7 @@
|
||||
v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist && !loading"
|
||||
class="mask-prompt"
|
||||
>
|
||||
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['Mysql']) }}</span>
|
||||
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['MySQL']) }}</span>
|
||||
</el-card>
|
||||
|
||||
<Setting ref="settingRef" style="margin-top: 20px" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div v-show="onSetting">
|
||||
<LayoutContent :title="'Mysql ' + $t('database.setting')" :reload="true">
|
||||
<LayoutContent :title="'MySQL ' + $t('database.setting')" :reload="true">
|
||||
<template #buttons>
|
||||
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
|
||||
{{ $t('database.confChange') }}
|
||||
|
@ -19,6 +19,16 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.passwd')" :rules="Rules.requiredInput" prop="password">
|
||||
<el-input type="password" clearable disabled v-model="form.password">
|
||||
<template #append>
|
||||
<el-button icon="Setting" @click="onChangePassword">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.theme')" :rules="Rules.requiredSelect" prop="theme">
|
||||
<el-radio-group
|
||||
@change="onSave(panelFormRef, 'Theme', form.theme)"
|
||||
@ -96,6 +106,7 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
<Password ref="passwordRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -109,6 +120,7 @@ import { GlobalStore } from '@/store';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useTheme } from '@/hooks/use-theme';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import Password from '@/views/setting/panel/password/index.vue';
|
||||
|
||||
const loading = ref(false);
|
||||
const i18n = useI18n();
|
||||
@ -120,6 +132,7 @@ type FormInstance = InstanceType<typeof ElForm>;
|
||||
|
||||
const form = reactive({
|
||||
userName: '',
|
||||
password: '',
|
||||
email: '',
|
||||
sessionTimeout: 0,
|
||||
localTime: '',
|
||||
@ -134,9 +147,12 @@ const TIME_COUNT = ref(10);
|
||||
const count = ref();
|
||||
const show = ref();
|
||||
|
||||
const passwordRef = ref();
|
||||
|
||||
const search = async () => {
|
||||
const res = await getSettingInfo();
|
||||
form.userName = res.data.userName;
|
||||
form.password = '******';
|
||||
form.sessionTimeout = Number(res.data.sessionTimeout);
|
||||
form.localTime = res.data.localTime;
|
||||
form.panelName = res.data.panelName;
|
||||
@ -146,6 +162,10 @@ const search = async () => {
|
||||
};
|
||||
const panelFormRef = ref<FormInstance>();
|
||||
|
||||
const onChangePassword = () => {
|
||||
passwordRef.value.acceptParams({ complexityVerification: form.complexityVerification });
|
||||
};
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined, key: string, val: any) => {
|
||||
if (!formEl) return;
|
||||
const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback);
|
||||
|
134
frontend/src/views/setting/panel/password/index.vue
Normal file
134
frontend/src/views/setting/panel/password/index.vue
Normal file
@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-drawer v-model="passwordVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('setting.changePassword')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form ref="passFormRef" label-position="top" :model="passForm" :rules="passRules">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('setting.oldPassword')" prop="oldPassword">
|
||||
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="complexityVerification === 'disable'"
|
||||
:label="$t('setting.newPassword')"
|
||||
prop="newPassword"
|
||||
>
|
||||
<el-input type="password" show-password clearable v-model="passForm.newPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="complexityVerification === 'enable'"
|
||||
:label="$t('setting.newPassword')"
|
||||
prop="newPasswordComplexity"
|
||||
>
|
||||
<el-input
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
v-model="passForm.newPasswordComplexity"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.retryPassword')" prop="retryPassword">
|
||||
<el-input type="password" show-password clearable v-model="passForm.retryPassword" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="passwordVisiable = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="submitChangePassword(passFormRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { updatePassword } from '@/api/modules/setting';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const passFormRef = ref<FormInstance>();
|
||||
const passRules = reactive({
|
||||
oldPassword: [Rules.requiredInput],
|
||||
newPassword: [
|
||||
Rules.requiredInput,
|
||||
{ min: 6, message: i18n.global.t('commons.rule.commonPassword'), trigger: 'blur' },
|
||||
],
|
||||
newPasswordComplexity: [Rules.requiredInput, Rules.password],
|
||||
retryPassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
|
||||
});
|
||||
const loading = ref(false);
|
||||
const passwordVisiable = ref<boolean>(false);
|
||||
const passForm = reactive({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
newPasswordComplexity: '',
|
||||
retryPassword: '',
|
||||
});
|
||||
const complexityVerification = ref();
|
||||
|
||||
interface DialogProps {
|
||||
complexityVerification: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
complexityVerification.value = params.complexityVerification;
|
||||
passForm.oldPassword = '';
|
||||
passForm.newPassword = '';
|
||||
passForm.newPasswordComplexity = '';
|
||||
passForm.retryPassword = '';
|
||||
passwordVisiable.value = true;
|
||||
};
|
||||
|
||||
function checkPassword(rule: any, value: any, callback: any) {
|
||||
let password = complexityVerification.value === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
|
||||
if (password !== passForm.retryPassword) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.rePassword')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
const submitChangePassword = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let password =
|
||||
complexityVerification.value === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
|
||||
if (password === passForm.oldPassword) {
|
||||
MsgError(i18n.global.t('setting.duplicatePassword'));
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
passwordVisiable.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
router.push({ name: 'login', params: { code: '' } });
|
||||
globalStore.setLogStatus(false);
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
const handleClose = () => {
|
||||
passwordVisiable.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -6,16 +6,6 @@
|
||||
<el-row>
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item :label="$t('setting.passwd')" :rules="Rules.requiredInput" prop="password">
|
||||
<el-input type="password" clearable disabled v-model="form.password">
|
||||
<template #append>
|
||||
<el-button icon="Setting" @click="onChangePassword">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.panelPort')" :rules="Rules.port" prop="serverPort">
|
||||
<el-input clearable v-model.number="form.serverPort">
|
||||
<template #append>
|
||||
@ -118,14 +108,11 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
<el-dialog
|
||||
v-model="timeoutVisiable"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('setting.expirationTime')"
|
||||
width="30%"
|
||||
>
|
||||
<el-form ref="timeoutFormRef" label-width="80px" label-position="left" :model="timeoutForm">
|
||||
<el-drawer v-model="timeoutVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('setting.expirationTime')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form ref="timeoutFormRef" label-position="top" :model="timeoutForm">
|
||||
<el-form-item :label="$t('setting.days')" prop="days" :rules="Rules.number">
|
||||
<el-input clearable v-model.number="timeoutForm.days" />
|
||||
<span class="input-help">{{ $t('setting.expirationHelper') }}</span>
|
||||
@ -139,54 +126,7 @@
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="passwordVisiable"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('setting.changePassword')"
|
||||
width="30%"
|
||||
>
|
||||
<el-form
|
||||
v-loading="dialogLoading"
|
||||
ref="passFormRef"
|
||||
label-width="80px"
|
||||
label-position="left"
|
||||
:model="passForm"
|
||||
:rules="passRules"
|
||||
>
|
||||
<el-form-item :label="$t('setting.oldPassword')" prop="oldPassword">
|
||||
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.complexityVerification === 'disable'"
|
||||
:label="$t('setting.newPassword')"
|
||||
prop="newPassword"
|
||||
>
|
||||
<el-input type="password" show-password clearable v-model="passForm.newPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.complexityVerification === 'enable'"
|
||||
:label="$t('setting.newPassword')"
|
||||
prop="newPasswordComplexity"
|
||||
>
|
||||
<el-input type="password" show-password clearable v-model="passForm.newPasswordComplexity" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.retryPassword')" prop="retryPassword">
|
||||
<el-input type="password" show-password clearable v-model="passForm.retryPassword" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="dialogLoading" @click="passwordVisiable = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="dialogLoading" type="primary" @click="submitChangePassword(passFormRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -195,37 +135,15 @@ import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElForm, ElMessageBox } from 'element-plus';
|
||||
import { Setting } from '@/api/interface/setting';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { updatePassword, updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting';
|
||||
import i18n from '@/lang';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { dateFormatSimple } from '@/utils/util';
|
||||
import { GlobalStore } from '@/store';
|
||||
import router from '@/routers';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const loading = ref(false);
|
||||
const globalStore = GlobalStore();
|
||||
const passFormRef = ref<FormInstance>();
|
||||
const passRules = reactive({
|
||||
oldPassword: [Rules.requiredInput],
|
||||
newPassword: [
|
||||
Rules.requiredInput,
|
||||
{ min: 6, message: i18n.global.t('commons.rule.commonPassword'), trigger: 'blur' },
|
||||
],
|
||||
newPasswordComplexity: [Rules.requiredInput, Rules.password],
|
||||
retryPassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
|
||||
});
|
||||
const dialogLoading = ref(false);
|
||||
const passwordVisiable = ref<boolean>(false);
|
||||
const passForm = reactive({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
newPasswordComplexity: '',
|
||||
retryPassword: '',
|
||||
});
|
||||
|
||||
const form = reactive({
|
||||
password: '',
|
||||
serverPort: 9999,
|
||||
securityEntrance: '',
|
||||
expirationDays: 0,
|
||||
@ -243,7 +161,6 @@ const timeoutForm = reactive({
|
||||
|
||||
const search = async () => {
|
||||
const res = await getSettingInfo();
|
||||
form.password = '******';
|
||||
form.serverPort = Number(res.data.serverPort);
|
||||
form.securityEntrance = res.data.securityEntrance;
|
||||
form.expirationDays = Number(res.data.expirationDays);
|
||||
@ -292,14 +209,6 @@ function callback(error: any) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function checkPassword(rule: any, value: any, callback: any) {
|
||||
let password = form.complexityVerification === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
|
||||
if (password !== passForm.retryPassword) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.rePassword')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
const onSavePort = async (formEl: FormInstance | undefined, key: string, val: any) => {
|
||||
if (!formEl) return;
|
||||
const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback);
|
||||
@ -328,40 +237,6 @@ const onSavePort = async (formEl: FormInstance | undefined, key: string, val: an
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onChangePassword = async () => {
|
||||
passForm.oldPassword = '';
|
||||
passForm.newPassword = '';
|
||||
passForm.newPasswordComplexity = '';
|
||||
passForm.retryPassword = '';
|
||||
passwordVisiable.value = true;
|
||||
};
|
||||
|
||||
const submitChangePassword = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let password =
|
||||
form.complexityVerification === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
|
||||
if (password === passForm.oldPassword) {
|
||||
MsgError(i18n.global.t('setting.duplicatePassword'));
|
||||
return;
|
||||
}
|
||||
dialogLoading.value = true;
|
||||
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password })
|
||||
.then(() => {
|
||||
dialogLoading.value = false;
|
||||
passwordVisiable.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
router.push({ name: 'login', params: { code: '' } });
|
||||
globalStore.setLogStatus(false);
|
||||
})
|
||||
.catch(() => {
|
||||
dialogLoading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleMFA = async () => {
|
||||
console.log('dawdwda');
|
||||
if (form.mfaStatus === 'enable') {
|
||||
@ -384,6 +259,10 @@ const handleMFA = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
timeoutVisiable.value = false;
|
||||
};
|
||||
|
||||
const onBind = async () => {
|
||||
loading.value = true;
|
||||
await bindMFA({ code: mfaCode.value, secret: otp.secret })
|
||||
|
2
go.mod
2
go.mod
@ -5,6 +5,7 @@ go 1.18
|
||||
require (
|
||||
gitee.com/openeuler/go-gitee v0.0.0-20220530104019-3af895bc380c
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
|
||||
github.com/antihax/optional v1.0.0
|
||||
github.com/aws/aws-sdk-go v1.44.99
|
||||
github.com/compose-spec/compose-go v1.6.0
|
||||
github.com/creack/pty v1.1.18
|
||||
@ -63,7 +64,6 @@ require (
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/antihax/optional v1.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
|
Loading…
Reference in New Issue
Block a user