mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-17 21:08:25 +08:00
fix: 修改部分字段校验 (#1881)
This commit is contained in:
parent
ce258cf157
commit
f4d5b5437e
9 changed files with 144 additions and 75 deletions
|
|
@ -117,7 +117,7 @@ type MysqlConfUpdateByFile struct {
|
||||||
|
|
||||||
type ChangeDBInfo struct {
|
type ChangeDBInfo struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
From string `json:"from" validate:"required"`
|
From string `json:"from"`
|
||||||
Value string `json:"value" validate:"required"`
|
Value string `json:"value" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ type ImageRepoUpdate struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
DownloadUrl string `json:"downloadUrl"`
|
DownloadUrl string `json:"downloadUrl"`
|
||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username" validate:"max=256"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password" validate:"max=256"`
|
||||||
Auth bool `json:"auth"`
|
Auth bool `json:"auth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ type RemoteDBSearch struct {
|
||||||
type RemoteDBInfo struct {
|
type RemoteDBInfo struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name" validate:"max=256"`
|
||||||
From string `json:"from"`
|
From string `json:"from"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ const message = {
|
||||||
appName: 'Support English, numbers, - and _, length 2-30, and cannot start and end with -_',
|
appName: 'Support English, numbers, - and _, length 2-30, and cannot start and end with -_',
|
||||||
containerName:
|
containerName:
|
||||||
'Supports letters, numbers, underscores, hyphens and dots, cannot end with hyphen- or dot.1-127',
|
'Supports letters, numbers, underscores, hyphens and dots, cannot end with hyphen- or dot.1-127',
|
||||||
|
mirror: 'Support image accelerator addresses that start with http(s)://, English uppercase and lowercase letters, numbers, periods, and hyphens, and there should be no empty lines.',
|
||||||
disableFunction: 'Only support letters ,underscores,and,',
|
disableFunction: 'Only support letters ,underscores,and,',
|
||||||
leechExts: 'Only support letters, numbers and,',
|
leechExts: 'Only support letters, numbers and,',
|
||||||
paramSimple: 'Support lowercase letters and numbers, length 1-128',
|
paramSimple: 'Support lowercase letters and numbers, length 1-128',
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ const message = {
|
||||||
nginxDoc: '僅支持英文大小寫,數字,和.',
|
nginxDoc: '僅支持英文大小寫,數字,和.',
|
||||||
appName: '支持英文、數字、-和_,長度2-30,並且不能以-_開頭和結尾',
|
appName: '支持英文、數字、-和_,長度2-30,並且不能以-_開頭和結尾',
|
||||||
containerName: '支持字母、數字、下劃線、連字符和點,不能以連字符-或點.結尾,長度1-127',
|
containerName: '支持字母、數字、下劃線、連字符和點,不能以連字符-或點.結尾,長度1-127',
|
||||||
|
mirror: '支持以 http(s):// 開頭,英文大小寫,數字,. 和 - 的鏡像加速地址,且不能有空行',
|
||||||
disableFunction: '僅支持字母、下劃線和,',
|
disableFunction: '僅支持字母、下劃線和,',
|
||||||
leechExts: '僅支持字母數字和,',
|
leechExts: '僅支持字母數字和,',
|
||||||
paramSimple: '支持小寫字母和數字,長度 1-128',
|
paramSimple: '支持小寫字母和數字,長度 1-128',
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ const message = {
|
||||||
nginxDoc: '仅支持英文大小写,数字,和.',
|
nginxDoc: '仅支持英文大小写,数字,和.',
|
||||||
appName: '支持英文、数字、-和_,长度2-30,并且不能以-_开头和结尾',
|
appName: '支持英文、数字、-和_,长度2-30,并且不能以-_开头和结尾',
|
||||||
containerName: '支持字母、数字、下划线、连字符和点,不能以连字符-或点.结尾,长度1-127',
|
containerName: '支持字母、数字、下划线、连字符和点,不能以连字符-或点.结尾,长度1-127',
|
||||||
|
mirror: '支持以 http(s):// 开头,英文大小写,数字,. 和 - 的镜像加速地址,且不能有空行',
|
||||||
disableFunction: '仅支持字母、下划线和,',
|
disableFunction: '仅支持字母、下划线和,',
|
||||||
leechExts: '仅支持字母数字和,',
|
leechExts: '仅支持字母数字和,',
|
||||||
paramSimple: '支持小写字母和数字,长度1-128',
|
paramSimple: '支持小写字母和数字,长度1-128',
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,22 @@
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.mirrors')" :back="handleClose" />
|
<DrawerHeader :header="$t('container.mirrors')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
<el-form label-position="top" @submit.prevent v-loading="loading">
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
label-position="top"
|
||||||
|
:model="form"
|
||||||
|
@submit.prevent
|
||||||
|
:rules="rules"
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
<el-col :span="22">
|
<el-col :span="22">
|
||||||
<el-form-item :label="$t('container.mirrors')">
|
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:placeholder="$t('container.mirrorHelper')"
|
:placeholder="$t('container.mirrorHelper')"
|
||||||
:autosize="{ minRows: 8, maxRows: 10 }"
|
:autosize="{ minRows: 8, maxRows: 10 }"
|
||||||
v-model="mirrors"
|
v-model="form.mirrors"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -21,7 +28,7 @@
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
<el-button :disabled="loading" type="primary" @click="onSave">
|
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||||
{{ $t('commons.button.confirm') }}
|
{{ $t('commons.button.confirm') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -32,41 +39,66 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||||
import { updateDaemonJson } from '@/api/modules/container';
|
import { updateDaemonJson } from '@/api/modules/container';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
||||||
const confirmDialogRef = ref();
|
const confirmDialogRef = ref();
|
||||||
|
|
||||||
const mirrors = ref();
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
mirrors: string;
|
mirrors: string;
|
||||||
}
|
}
|
||||||
const drawerVisiable = ref();
|
const drawerVisiable = ref();
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
mirrors: '',
|
||||||
|
});
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const rules = reactive({
|
||||||
|
mirrors: [{ validator: checkMirrors, trigger: 'blur' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkMirrors(rule: any, value: any, callback: any) {
|
||||||
|
if (form.mirrors !== '') {
|
||||||
|
const reg = /^https?:\/\/[a-zA-Z0-9.-]+$/;
|
||||||
|
let mirrors = form.mirrors.split('\n');
|
||||||
|
for (const item of mirrors) {
|
||||||
|
if (!reg.test(item)) {
|
||||||
|
return callback(new Error(i18n.global.t('commons.rule.mirror')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
const acceptParams = (params: DialogProps): void => {
|
const acceptParams = (params: DialogProps): void => {
|
||||||
mirrors.value = params.mirrors || params.mirrors.replaceAll(',', '\n');
|
form.mirrors = params.mirrors || params.mirrors.replaceAll(',', '\n');
|
||||||
drawerVisiable.value = true;
|
drawerVisiable.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSave = async () => {
|
const onSave = async (formEl: FormInstance | undefined) => {
|
||||||
let params = {
|
if (!formEl) return;
|
||||||
header: i18n.global.t('database.confChange'),
|
formEl.validate(async (valid) => {
|
||||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
if (!valid) return;
|
||||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
let params = {
|
||||||
};
|
header: i18n.global.t('database.confChange'),
|
||||||
confirmDialogRef.value!.acceptParams(params);
|
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||||
|
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||||
|
};
|
||||||
|
confirmDialogRef.value!.acceptParams(params);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await updateDaemonJson('Mirrors', mirrors.value.replaceAll('\n', ','))
|
await updateDaemonJson('Mirrors', form.mirrors.replaceAll('\n', ','))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
emit('search');
|
emit('search');
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,22 @@
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.registries')" :back="handleClose" />
|
<DrawerHeader :header="$t('container.registries')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
<el-form label-position="top" @submit.prevent v-loading="loading">
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
label-position="top"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
@submit.prevent
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
<el-col :span="22">
|
<el-col :span="22">
|
||||||
<el-form-item :label="$t('container.registries')">
|
<el-form-item :label="$t('container.registries')" prop="registries">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:placeholder="$t('container.registrieHelper')"
|
:placeholder="$t('container.registrieHelper')"
|
||||||
:autosize="{ minRows: 8, maxRows: 10 }"
|
:autosize="{ minRows: 8, maxRows: 10 }"
|
||||||
v-model="registries"
|
v-model="form.registries"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -32,26 +39,47 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||||
import { updateDaemonJson } from '@/api/modules/container';
|
import { updateDaemonJson } from '@/api/modules/container';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
||||||
const confirmDialogRef = ref();
|
const confirmDialogRef = ref();
|
||||||
|
|
||||||
const registries = ref();
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
registries: string;
|
registries: string;
|
||||||
}
|
}
|
||||||
const drawerVisiable = ref();
|
const drawerVisiable = ref();
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
registries: '',
|
||||||
|
});
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const rules = reactive({
|
||||||
|
registries: [{ validator: checkRegistries, trigger: 'blur' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkRegistries(rule: any, value: any, callback: any) {
|
||||||
|
if (form.registries !== '') {
|
||||||
|
const reg = /^[a-zA-Z0-9]{1}[a-z:A-Z0-9_/.-]{0,150}$/;
|
||||||
|
let regis = form.registries.split('\n');
|
||||||
|
for (const item of regis) {
|
||||||
|
if (!reg.test(item)) {
|
||||||
|
return callback(new Error(i18n.global.t('commons.rule.imageName')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
const acceptParams = (params: DialogProps): void => {
|
const acceptParams = (params: DialogProps): void => {
|
||||||
registries.value = params.registries || params.registries.replaceAll(',', '\n');
|
form.registries = params.registries || params.registries.replaceAll(',', '\n');
|
||||||
drawerVisiable.value = true;
|
drawerVisiable.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -66,7 +94,7 @@ const onSave = async () => {
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await updateDaemonJson('Registries', registries.value.replaceAll('\n', ','))
|
await updateDaemonJson('Registries', form.registries.replaceAll('\n', ','))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
|
||||||
|
|
@ -4,56 +4,46 @@
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :resource="changeForm.mysqlName" :back="handleClose" />
|
<DrawerHeader :header="title" :resource="changeForm.mysqlName" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
<el-form>
|
<el-form v-loading="loading" ref="changeFormRef" :model="changeForm" :rules="rules" label-position="top">
|
||||||
<el-form v-loading="loading" ref="changeFormRef" :model="changeForm" label-position="top">
|
<el-row type="flex" justify="center">
|
||||||
<el-row type="flex" justify="center">
|
<el-col :span="22">
|
||||||
<el-col :span="22">
|
<div v-if="changeForm.operation === 'password'">
|
||||||
<div v-if="changeForm.operation === 'password'">
|
<el-form-item :label="$t('commons.login.username')" prop="userName">
|
||||||
<el-form-item :label="$t('commons.login.username')" prop="userName">
|
<el-input disabled v-model="changeForm.userName"></el-input>
|
||||||
<el-input disabled v-model="changeForm.userName"></el-input>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item :label="$t('commons.login.password')" prop="password">
|
||||||
<el-form-item
|
<el-input
|
||||||
:label="$t('commons.login.password')"
|
type="password"
|
||||||
prop="password"
|
clearable
|
||||||
:rules="Rules.paramComplexity"
|
show-password
|
||||||
>
|
v-model="changeForm.password"
|
||||||
<el-input
|
></el-input>
|
||||||
type="password"
|
</el-form-item>
|
||||||
clearable
|
</div>
|
||||||
show-password
|
<div v-if="changeForm.operation === 'privilege'">
|
||||||
v-model="changeForm.password"
|
<el-form-item :label="$t('database.permission')" prop="privilege">
|
||||||
></el-input>
|
<el-select style="width: 100%" v-model="changeForm.privilege">
|
||||||
</el-form-item>
|
<el-option value="%" :label="$t('database.permissionAll')" />
|
||||||
</div>
|
<el-option
|
||||||
<div v-if="changeForm.operation === 'privilege'">
|
v-if="changeForm.from !== 'local'"
|
||||||
<el-form-item :label="$t('database.permission')" prop="privilege">
|
value="localhost"
|
||||||
<el-select style="width: 100%" v-model="changeForm.privilege">
|
:label="$t('terminal.localhost')"
|
||||||
<el-option value="%" :label="$t('database.permissionAll')" />
|
|
||||||
<el-option
|
|
||||||
v-if="changeForm.from !== 'local'"
|
|
||||||
value="localhost"
|
|
||||||
:label="$t('terminal.localhost')"
|
|
||||||
/>
|
|
||||||
<el-option value="ip" :label="$t('database.permissionForIP')" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="changeForm.privilege === 'ip'"
|
|
||||||
prop="privilegeIPs"
|
|
||||||
:rules="Rules.requiredInput"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
clearable
|
|
||||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
|
||||||
type="textarea"
|
|
||||||
v-model="changeForm.privilegeIPs"
|
|
||||||
/>
|
/>
|
||||||
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
|
<el-option value="ip" :label="$t('database.permissionForIP')" />
|
||||||
</el-form-item>
|
</el-select>
|
||||||
</div>
|
</el-form-item>
|
||||||
</el-col>
|
<el-form-item v-if="changeForm.privilege === 'ip'" prop="privilegeIPs">
|
||||||
</el-row>
|
<el-input
|
||||||
</el-form>
|
clearable
|
||||||
|
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
type="textarea"
|
||||||
|
v-model="changeForm.privilegeIPs"
|
||||||
|
/>
|
||||||
|
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
|
|
@ -78,6 +68,7 @@ import { deleteCheckMysqlDB, updateMysqlAccess, updateMysqlPassword } from '@/ap
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { checkIp } from '@/utils/util';
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const changeVisiable = ref(false);
|
const changeVisiable = ref(false);
|
||||||
|
|
@ -97,6 +88,21 @@ const changeForm = reactive({
|
||||||
});
|
});
|
||||||
const confirmDialogRef = ref();
|
const confirmDialogRef = ref();
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
password: [Rules.paramComplexity],
|
||||||
|
privilegeIPs: [{ validator: checkIPs, trigger: 'blur', required: true }],
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkIPs(rule: any, value: any, callback: any) {
|
||||||
|
let ips = changeForm.privilegeIPs.split(',');
|
||||||
|
for (const item of ips) {
|
||||||
|
if (checkIp(item)) {
|
||||||
|
return callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
id: number;
|
id: number;
|
||||||
from: string;
|
from: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue