mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-27 20:49:03 +08:00
fix: 处理数据库遮罩问题 (#5215)
This commit is contained in:
parent
c62232e648
commit
e5bcb07cf6
@ -73,6 +73,7 @@ type AppInstalledDTO struct {
|
||||
}
|
||||
|
||||
type DatabaseConn struct {
|
||||
Status string `json:"status"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
ContainerName string `json:"containerName"`
|
||||
|
@ -3,6 +3,7 @@ package repo
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
@ -160,6 +161,7 @@ func (a *AppInstallRepo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOp
|
||||
type RootInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
Port int64 `json:"port"`
|
||||
HttpsPort int64 `json:"httpsPort"`
|
||||
UserName string `json:"userName"`
|
||||
@ -234,5 +236,6 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
info.Key = app.Key
|
||||
appInstall.App = app
|
||||
info.AppPath = appInstall.GetAppPath()
|
||||
info.Status = appInstall.Status
|
||||
return &info, nil
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ func (a *AppInstallService) LoadConnInfo(req dto.OperationWithNameAndType) (resp
|
||||
if err != nil {
|
||||
return data, nil
|
||||
}
|
||||
data.Status = app.Status
|
||||
data.Username = app.UserName
|
||||
data.Password = app.Password
|
||||
data.ServiceName = app.ServiceName
|
||||
|
@ -70,6 +70,9 @@ func (u *DatabaseService) Get(name string) (dto.DatabaseInfo, error) {
|
||||
|
||||
func (u *DatabaseService) List(dbType string) ([]dto.DatabaseOption, error) {
|
||||
dbs, err := databaseRepo.GetList(databaseRepo.WithTypeList(dbType))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datas []dto.DatabaseOption
|
||||
for _, db := range dbs {
|
||||
var item dto.DatabaseOption
|
||||
|
@ -363,6 +363,17 @@ func (u *MysqlService) ChangePassword(req dto.ChangeDBInfo) error {
|
||||
if err := updateInstallInfoInDB(req.Type, req.Database, "password", req.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.From == "local" {
|
||||
remote, err := databaseRepo.Get(commonRepo.WithByName(req.Database))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pass, err := encrypt.StringEncrypt(req.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database password failed, err: %v", err)
|
||||
}
|
||||
_ = databaseRepo.Update(remote.ID, map[string]interface{}{"password": pass})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -414,5 +414,16 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error {
|
||||
if err := updateInstallInfoInDB(req.Type, req.Database, "password", req.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.From == "local" {
|
||||
remote, err := databaseRepo.Get(commonRepo.WithByName(req.Database))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pass, err := encrypt.StringEncrypt(req.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database password failed, err: %v", err)
|
||||
}
|
||||
_ = databaseRepo.Update(remote.ID, map[string]interface{}{"password": pass})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
@ -87,9 +88,17 @@ func (u *RedisService) ChangePassword(req dto.ChangeRedisPass) error {
|
||||
if err := updateInstallInfoInDB("redis", req.Database, "password", req.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := updateInstallInfoInDB("redis-commander", "", "password", req.Value); err != nil {
|
||||
remote, err := databaseRepo.Get(commonRepo.WithByName(req.Database))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if remote.From == "local" {
|
||||
pass, err := encrypt.StringEncrypt(req.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database password failed, err: %v", err)
|
||||
}
|
||||
_ = databaseRepo.Update(remote.ID, map[string]interface{}{"password": pass})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ export namespace App {
|
||||
}
|
||||
|
||||
export interface DatabaseConnInfo {
|
||||
status: string;
|
||||
username: string;
|
||||
password: string;
|
||||
privilege: boolean;
|
||||
|
@ -185,6 +185,7 @@ const onCheck = async () => {
|
||||
.then((res) => {
|
||||
data.value = res.data;
|
||||
em('isExist', res.data);
|
||||
em('update:maskShow', res.data.status !== 'Running');
|
||||
operateReq.installId = res.data.appInstallId;
|
||||
httpPort.value = res.data.httpPort;
|
||||
httpsPort.value = res.data.httpsPort;
|
||||
|
@ -68,7 +68,11 @@
|
||||
|
||||
<div v-if="form.from === 'local'">
|
||||
<el-form-item :label="$t('database.remoteAccess')" prop="privilege">
|
||||
<el-switch v-model="form.privilege" @change="onSaveAccess" />
|
||||
<el-switch
|
||||
v-model="form.privilege"
|
||||
:disabled="form.status !== 'Running'"
|
||||
@change="onSaveAccess"
|
||||
/>
|
||||
<span class="input-help">{{ $t('database.remoteConnHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
@ -109,7 +113,7 @@
|
||||
<el-button :disabled="loading" @click="dialogVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
<el-button :disabled="loading || form.status !== 'Running'" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@ -134,6 +138,7 @@ const loading = ref(false);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const form = reactive({
|
||||
status: '',
|
||||
systemIP: '',
|
||||
password: '',
|
||||
serviceName: '',
|
||||
@ -201,6 +206,7 @@ const loadSystemIP = async () => {
|
||||
const loadPassword = async () => {
|
||||
if (form.from === 'local') {
|
||||
const res = await GetAppConnInfo(form.type, form.database);
|
||||
form.status = res.data.status;
|
||||
form.password = res.data.password || '';
|
||||
form.port = res.data.port || 3306;
|
||||
form.serviceName = res.data.serviceName || '';
|
||||
|
@ -70,12 +70,7 @@
|
||||
>
|
||||
{{ $t('database.create') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentDB && (currentDB.from !== 'local' || mysqlStatus === 'Running')"
|
||||
@click="onChangeConn"
|
||||
type="primary"
|
||||
plain
|
||||
>
|
||||
<el-button v-if="currentDB" @click="onChangeConn" type="primary" plain>
|
||||
{{ $t('database.databaseConnInfo') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
@ -114,7 +109,7 @@
|
||||
<template #main v-if="currentDB">
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
:class="{ mask: maskShow && currentDB.from !== 'local' }"
|
||||
:class="{ mask: maskShow }"
|
||||
@sort-change="search"
|
||||
@search="search"
|
||||
:data="data"
|
||||
@ -394,6 +389,7 @@ const changeDatabase = async () => {
|
||||
}
|
||||
for (const item of dbOptionsRemote.value) {
|
||||
if (item.database == currentDBName.value) {
|
||||
maskShow.value = false;
|
||||
currentDB.value = item;
|
||||
break;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@
|
||||
<el-button :disabled="loading" @click="dialogVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
<el-button :disabled="loading || form.status !== 'Running'" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@ -137,6 +137,7 @@ const loading = ref(false);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const form = reactive({
|
||||
status: '',
|
||||
systemIP: '',
|
||||
password: '',
|
||||
containerName: '',
|
||||
@ -202,6 +203,7 @@ const loadSystemIP = async () => {
|
||||
const loadPassword = async () => {
|
||||
if (form.from === 'local') {
|
||||
const res = await GetAppConnInfo(form.type, form.database);
|
||||
form.status = res.data.status;
|
||||
form.username = res.data.username || '';
|
||||
form.password = res.data.password || '';
|
||||
form.port = res.data.port || 5432;
|
||||
|
@ -62,12 +62,7 @@
|
||||
>
|
||||
{{ $t('database.create') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentDB && (currentDB.from !== 'local' || postgresqlStatus === 'Running')"
|
||||
@click="onChangeConn"
|
||||
type="primary"
|
||||
plain
|
||||
>
|
||||
<el-button v-if="currentDB" @click="onChangeConn" type="primary" plain>
|
||||
{{ $t('database.databaseConnInfo') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
@ -90,7 +85,7 @@
|
||||
</template>
|
||||
<template #main v-if="currentDB">
|
||||
<ComplexTable
|
||||
:class="{ mask: maskShow && currentDB.from !== 'local' }"
|
||||
:class="{ mask: maskShow }"
|
||||
:pagination-config="paginationConfig"
|
||||
@sort-change="search"
|
||||
@search="search"
|
||||
@ -364,6 +359,7 @@ const changeDatabase = async () => {
|
||||
}
|
||||
for (const item of dbOptionsRemote.value) {
|
||||
if (item.database == currentDBName.value) {
|
||||
maskShow.value = false;
|
||||
currentDB.value = item;
|
||||
break;
|
||||
}
|
||||
|
@ -12,12 +12,21 @@
|
||||
<el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('database.containerConn')">
|
||||
<el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'">
|
||||
<el-card class="mini-border-card">
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item :label="$t('database.connAddress')">
|
||||
{{ form.containerName }}
|
||||
<CopyButton :content="form.containerName" type="icon" />
|
||||
<el-tooltip
|
||||
v-if="loadRedisInfo(true).length > 48"
|
||||
:content="loadRedisInfo(true)"
|
||||
placement="top"
|
||||
>
|
||||
{{ loadRedisInfo(true).substring(0, 48) }}...
|
||||
</el-tooltip>
|
||||
<span else>
|
||||
{{ loadRedisInfo(true) }}
|
||||
</span>
|
||||
<CopyButton :content="loadRedisInfo(true)" type="icon" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('database.connPort')">
|
||||
6379
|
||||
@ -33,8 +42,17 @@
|
||||
<el-card class="mini-border-card">
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item :label="$t('database.connAddress')">
|
||||
{{ form.systemIP }}
|
||||
<CopyButton :content="form.systemIP" type="icon" />
|
||||
<el-tooltip
|
||||
v-if="loadRedisInfo(false).length > 48"
|
||||
:content="loadRedisInfo(false)"
|
||||
placement="top"
|
||||
>
|
||||
{{ loadRedisInfo(false).substring(0, 48) }}...
|
||||
</el-tooltip>
|
||||
<span else>
|
||||
{{ loadRedisInfo(false) }}
|
||||
</span>
|
||||
<CopyButton :content="loadRedisInfo(false)" type="icon" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('database.connPort')">
|
||||
{{ form.port }}
|
||||
@ -48,7 +66,12 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-divider border-style="dashed" />
|
||||
<el-form-item :label="$t('commons.login.password')" :rules="Rules.paramComplexity" prop="password">
|
||||
<el-form-item
|
||||
:label="$t('commons.login.password')"
|
||||
v-if="form.from === 'local'"
|
||||
:rules="Rules.paramComplexity"
|
||||
prop="password"
|
||||
>
|
||||
<el-input type="password" show-password clearable v-model="form.password">
|
||||
<template #append>
|
||||
<CopyButton :content="form.password" />
|
||||
@ -58,6 +81,13 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<div v-if="form.from !== 'local'">
|
||||
<el-form-item :label="$t('commons.login.password')">
|
||||
<el-tag>{{ form.password }}</el-tag>
|
||||
<CopyButton :content="form.password" type="icon" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@ -69,7 +99,7 @@
|
||||
<el-button :disabled="loading" @click="dialogVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
<el-button :disabled="loading || form.status !== 'Running'" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@ -82,7 +112,7 @@ import { reactive, ref } from 'vue';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { changeRedisPassword } from '@/api/modules/database';
|
||||
import { changeRedisPassword, getDatabase } from '@/api/modules/database';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { GetAppConnInfo } from '@/api/modules/app';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
@ -94,11 +124,16 @@ const loading = ref(false);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const form = reactive({
|
||||
database: '',
|
||||
password: '',
|
||||
containerName: '',
|
||||
status: '',
|
||||
systemIP: '',
|
||||
password: '',
|
||||
serviceName: '',
|
||||
containerName: '',
|
||||
port: 0,
|
||||
|
||||
from: '',
|
||||
database: '',
|
||||
remoteIP: '',
|
||||
});
|
||||
|
||||
const confirmDialogRef = ref();
|
||||
@ -109,11 +144,13 @@ type FormInstance = InstanceType<typeof ElForm>;
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
from: string;
|
||||
database: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.database = params.database;
|
||||
form.password = '';
|
||||
form.from = params.from;
|
||||
form.database = params.database;
|
||||
loadPassword();
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
@ -126,14 +163,36 @@ const random = async () => {
|
||||
};
|
||||
|
||||
const loadPassword = async () => {
|
||||
if (form.from === 'local') {
|
||||
const res = await GetAppConnInfo('redis', form.database);
|
||||
form.containerName = res.data.containerName;
|
||||
form.status = res.data.status;
|
||||
form.password = res.data.password || '';
|
||||
form.port = res.data.port || 3306;
|
||||
form.serviceName = res.data.serviceName || '';
|
||||
form.containerName = res.data.containerName || '';
|
||||
loadSystemIP();
|
||||
return;
|
||||
}
|
||||
const res = await getDatabase(form.database);
|
||||
form.password = res.data.password || '';
|
||||
form.port = res.data.port || 3306;
|
||||
form.password = res.data.password;
|
||||
form.port = res.data.port;
|
||||
const settingInfoRes = await getSettingInfo();
|
||||
form.systemIP = settingInfoRes.data.systemIP || i18n.global.t('database.localIP');
|
||||
form.remoteIP = res.data.address;
|
||||
};
|
||||
|
||||
const loadSystemIP = async () => {
|
||||
const res = await getSettingInfo();
|
||||
form.systemIP = res.data.systemIP || i18n.global.t('database.localIP');
|
||||
};
|
||||
|
||||
function loadRedisInfo(isContainer: boolean) {
|
||||
if (isContainer) {
|
||||
return form.from === 'local' ? form.containerName : form.systemIP;
|
||||
} else {
|
||||
return form.from === 'local' ? form.systemIP : form.remoteIP;
|
||||
}
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
loading.value = true;
|
||||
emit('closeTerminal');
|
@ -51,15 +51,13 @@
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</template>
|
||||
<template #toolbar v-if="!isOnSetting && currentDB">
|
||||
<div :class="{ mask: redisStatus != 'Running' && currentDB.from === 'local' }">
|
||||
<el-button type="primary" plain @click="onChangePassword">
|
||||
<template #toolbar v-if="!isOnSetting">
|
||||
<el-button v-if="currentDB" type="primary" plain @click="onLoadConn">
|
||||
{{ $t('database.databaseConnInfo') }}
|
||||
</el-button>
|
||||
<el-button @click="goRemoteDB" type="primary" plain>
|
||||
{{ $t('database.remoteDB') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
@ -71,13 +69,10 @@
|
||||
v-show="redisStatus === 'Running' && terminalShow"
|
||||
/>
|
||||
<el-empty
|
||||
:class="{ mask: maskShow }"
|
||||
v-if="redisStatus !== 'Running' || (currentDB.from === 'remote' && !redisCliExist)"
|
||||
:style="{ height: `calc(100vh - ${loadHeight()})`, 'background-color': '#000' }"
|
||||
:description="
|
||||
currentDB.from === 'remote'
|
||||
? $t('commons.service.serviceNotStarted', ['Redis'])
|
||||
: $t('database.redisCliHelper')
|
||||
"
|
||||
:description="loadErrMsg()"
|
||||
>
|
||||
<el-button v-if="currentDB.from === 'remote'" type="primary" @click="installCli">
|
||||
{{ $t('commons.button.enable') }}
|
||||
@ -94,8 +89,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card
|
||||
v-if="redisStatus != 'Running' && currentDB && !loading && maskShow && currentDB?.from === 'local'"
|
||||
class="mask-prompt"
|
||||
>
|
||||
<span>{{ $t('commons.service.serviceNotStarted', ['Redis']) }}</span>
|
||||
</el-card>
|
||||
|
||||
<Setting ref="settingRef" style="margin-top: 30px" />
|
||||
<Password ref="passwordRef" @check-exist="reOpenTerminal" @close-terminal="closeTerminal(true)" />
|
||||
<Conn ref="connRef" @check-exist="reOpenTerminal" @close-terminal="closeTerminal(true)" />
|
||||
<el-dialog
|
||||
v-model="commandVisible"
|
||||
:title="$t('app.checkTitle')"
|
||||
@ -121,7 +123,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Setting from '@/views/database/redis/setting/index.vue';
|
||||
import Password from '@/views/database/redis/password/index.vue';
|
||||
import Conn from '@/views/database/redis/conn/index.vue';
|
||||
import Terminal from '@/components/terminal/index.vue';
|
||||
import AppStatus from '@/components/app-status/index.vue';
|
||||
import QuickCmd from '@/views/database/redis/command/index.vue';
|
||||
@ -184,9 +186,13 @@ const goRemoteDB = async () => {
|
||||
router.push({ name: 'Redis-Remote' });
|
||||
};
|
||||
|
||||
const passwordRef = ref();
|
||||
const onChangePassword = async () => {
|
||||
passwordRef.value!.acceptParams({ database: currentDBName.value });
|
||||
const connRef = ref();
|
||||
const onLoadConn = async () => {
|
||||
connRef.value!.acceptParams({
|
||||
from: currentDB.value.from,
|
||||
type: currentDB.value.type,
|
||||
database: currentDBName.value,
|
||||
});
|
||||
};
|
||||
|
||||
const goRouter = async (target: string) => {
|
||||
@ -209,6 +215,7 @@ const changeDatabase = async () => {
|
||||
}
|
||||
for (const item of dbOptionsRemote.value) {
|
||||
if (item.database == currentDBName.value) {
|
||||
maskShow.value = false;
|
||||
currentDB.value = item;
|
||||
break;
|
||||
}
|
||||
@ -255,6 +262,11 @@ const loadDBOptions = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const loadErrMsg = () => {
|
||||
return currentDB.value.from === 'local'
|
||||
? i18n.global.t('commons.service.serviceNotStarted', ['Redis'])
|
||||
: i18n.global.t('database.redisCliHelper');
|
||||
};
|
||||
const reOpenTerminal = async () => {
|
||||
closeTerminal(false);
|
||||
initTerminal();
|
||||
|
Loading…
Reference in New Issue
Block a user