Compare commits

...
Author SHA1 Message Date
王贺 0be45b6a55 Modify the install script 2025-06-10 17:18:51 +08:00
CityFun c922615183 feat: fix issue with build frontend failed (#8994) 2025-06-10 16:57:45 +08:00
CityFun 8b2990fca4 feat: change 1panel v1 docs url (#8993) 2025-06-10 16:22:04 +08:00
longjuan 37b5cd743a feat: add name attrs to login inputs for password managers to recognize (#8953) 2025-06-10 16:21:59 +08:00
玲珑芯ExquisiteCore 3b1324db08 feat: Move current status to first position in MySQL settings and set… (#8882)
* feat: Move current status to first position in MySQL and Redis settings and set as default tab
2025-06-10 16:21:53 +08:00
Alan f56bbb7dc1 ini filetype support (#8628) 2025-06-10 16:21:43 +08:00
CityFun cff649ae95 fix: Fix issue with update website config (#8610) 2025-06-10 16:21:38 +08:00
Wankko Ree cb87ca4361 fix: the docker image which no tag but used be pruned (#8529) 2025-06-10 16:21:32 +08:00
igophper 165d2b1290 fix(cronjob): prevent unnecessary log updates and clean log formatting (#8481)
Refs #8425
2025-06-10 16:21:25 +08:00
igophper 189555e16c fix(editor): reset edit state after not saving content (#8474)
Refs #8461
2025-06-10 16:21:12 +08:00
ChengPlay 2d8250926f Fix issue with errors when reverse proxy source text includes comments. (#8444)
Refs https://github.com/1Panel-dev/1Panel/issues/8442
2025-06-10 16:20:52 +08:00
ChengPlay 47e343712e feat: change commandPlaceHolder translate (#8391) 2025-06-10 16:20:33 +08:00
ssongliu 11ffb4f2be fix: Fix the mysql root account permission switchover exception (#8378) 2025-06-10 16:20:21 +08:00
zhengkunwang e7670f96de feat: update mcp proxy_pass (#8374) 2025-04-10 16:45:24 +08:00
23 changed files with 90 additions and 58 deletions
+2 -2
View File
@@ -430,7 +430,7 @@ func addProxy(server *model.McpServer) {
if !ok {
return
}
location.UpdateDirective("proxy_pass", []string{fmt.Sprintf("http://127.0.1:%d%s", server.Port, server.SsePath)})
location.UpdateDirective("proxy_pass", []string{fmt.Sprintf("http://127.0.0.1:%d%s", server.Port, server.SsePath)})
location.ChangePath("^~", server.SsePath)
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
global.LOG.Errorf("write config failed, err: %v", buserr.WithErr(constant.ErrUpdateBuWebsite, err))
@@ -486,7 +486,7 @@ func addMCPProxy(websiteID uint) error {
err = errors.New("error")
return err
}
location.UpdateDirective("proxy_pass", []string{fmt.Sprintf("http://127.0.1:%d%s", server.Port, server.SsePath)})
location.UpdateDirective("proxy_pass", []string{fmt.Sprintf("http://127.0.0.1:%d%s", server.Port, server.SsePath)})
location.ChangePath("^~", server.SsePath)
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
+18 -5
View File
@@ -427,7 +427,9 @@ func (w WebsiteService) UpdateWebsite(req request.WebsiteUpdate) error {
}
}
website.PrimaryDomain = req.PrimaryDomain
website.WebsiteGroupID = req.WebsiteGroupID
if req.WebsiteGroupID > 0 {
website.WebsiteGroupID = req.WebsiteGroupID
}
website.Remark = req.Remark
website.IPV6 = req.IPV6
@@ -1768,11 +1770,22 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
}
directives := config.GetDirectives()
location, ok := directives[0].(*components.Location)
if !ok {
err = errors.New("error")
return
var (
location *components.Location
ok bool
)
for _, directive := range directives {
if directive.GetName() == "location" {
location, ok = directive.(*components.Location)
if ok {
break
}
}
}
if location == nil {
return nil, buserr.New("ErrConfigParse")
}
proxyConfig.ProxyPass = location.ProxyPass
proxyConfig.Cache = location.Cache
if location.CacheTime > 0 {
+12 -13
View File
@@ -188,19 +188,18 @@ func (r *Local) ChangeAccess(info AccessChangeInfo) error {
info.Name = "*"
info.Password = r.Password
}
if info.Permission == info.OldPermission {
return nil
}
if err := r.Delete(DeleteInfo{
Version: info.Version,
Username: info.Username,
Permission: info.OldPermission,
ForceDelete: true,
Timeout: 300}); err != nil {
return err
}
if info.Username == "root" {
return nil
if info.Permission != info.OldPermission {
if err := r.Delete(DeleteInfo{
Version: info.Version,
Username: info.Username,
Permission: info.OldPermission,
ForceDelete: true,
Timeout: 300}); err != nil {
return err
}
if info.Username == "root" {
return nil
}
}
if err := r.CreateUser(CreateInfo{
Name: info.Name,
+12 -13
View File
@@ -199,19 +199,18 @@ func (r *Remote) ChangeAccess(info AccessChangeInfo) error {
info.Name = "*"
info.Password = r.Password
}
if info.Permission == info.OldPermission {
return nil
}
if err := r.Delete(DeleteInfo{
Version: info.Version,
Username: info.Username,
Permission: info.OldPermission,
ForceDelete: true,
Timeout: 300}); err != nil {
return err
}
if info.Username == "root" {
return nil
if info.Permission != info.OldPermission {
if err := r.Delete(DeleteInfo{
Version: info.Version,
Username: info.Username,
Permission: info.OldPermission,
ForceDelete: true,
Timeout: 300}); err != nil {
return err
}
if info.Username == "root" {
return nil
}
}
if err := r.CreateUser(CreateInfo{
Name: info.Name,
+3 -3
View File
@@ -6,15 +6,15 @@ command -v wget >/dev/null || {
}
if [ ! -f "1pctl" ]; then
wget https://github.com/1Panel-dev/installer/raw/main/1pctl
wget https://github.com/1Panel-dev/installer/raw/dev/1pctl
fi
if [ ! -f "1panel.service" ]; then
wget https://github.com/1Panel-dev/installer/raw/main/1panel.service
wget https://github.com/1Panel-dev/installer/raw/dev/1panel.service
fi
if [ ! -f "install.sh" ]; then
wget https://github.com/1Panel-dev/installer/raw/main/install.sh
wget https://github.com/1Panel-dev/installer/raw/dev/install.sh
fi
if [ ! -f "GeoIP.mmdb" ]; then
+1
View File
@@ -7,6 +7,7 @@ location ^~ /test {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_http_version 1.1;
add_header X-Cache $upstream_cache_status;
add_header Cache-Control no-cache;
+4
View File
@@ -95,6 +95,10 @@ export const Languages = [
label: 'css',
value: ['css'],
},
{
label: 'ini',
value: ['ini'],
},
];
export const Rewrites = [
+1 -1
View File
@@ -2621,7 +2621,7 @@ const message = {
domain: 'Default Access Address',
domainHelper: 'For example: 192.168.1.1 or example.com',
bindDomain: 'Bind Website',
commandPlaceHolder: 'Currently only supports npx startup commands',
commandPlaceHolder: 'Currently only supports npx and binary startup commands',
importMcpJson: 'Import MCP Server Configuration',
importMcpJsonError: 'mcpServers structure is incorrect',
bindDomainHelper:
+1 -1
View File
@@ -2591,7 +2591,7 @@ const message = {
domain: 'デフォルトアクセスアドレス',
domainHelper: '例: 192.168.1.1 または example.com',
bindDomain: 'ウェブサイトをバインド',
commandPlaceHolder: '現在、npx スタートアップコマンドのみをサポートしています',
commandPlaceHolder: '現在、npx およびバイナリスタートアップコマンドのみをサポートしています',
importMcpJson: 'MCP サーバー設定をインポート',
importMcpJsonError: 'mcpServers 構造が正しくありません',
bindDomainHelper:
+1 -1
View File
@@ -2550,7 +2550,7 @@ const message = {
domain: 'デフォルトアクセスアドレス',
domainHelper: '例: 192.168.1.1 または example.com',
bindDomain: 'ウェブサイトをバインド',
commandPlaceHolder: '현재 npx 시작 명령만 지원합니다',
commandPlaceHolder: '현재 npx 및 바이너리 시작 명령만 지원합니다',
importMcpJson: 'MCP サーバー設定をインポート',
importMcpJsonError: 'mcpServers 構造が正しくありません',
bindDomainHelper:
+1 -1
View File
@@ -2649,7 +2649,7 @@ const message = {
domain: 'Alamat Akses Lalai',
domainHelper: 'Contoh: 192.168.1.1 atau example.com',
bindDomain: 'Sematkan Laman Web',
commandPlaceHolder: 'Kini hanya menyokong perintah pelancaran npx',
commandPlaceHolder: 'Kini hanya menyokong perintah pelancaran npx dan binari',
importMcpJson: 'Import Konfigurasi Pelayan MCP',
importMcpJsonError: 'Struktur mcpServers tidak betul',
bindDomainHelper:
+1 -1
View File
@@ -2647,7 +2647,7 @@ const message = {
domain: 'Endereço de Acesso Padrão',
domainHelper: 'Por exemplo: 192.168.1.1 ou example.com',
bindDomain: 'Vincular Site',
commandPlaceHolder: 'Atualmente, apenas comandos de inicialização npx são suportados',
commandPlaceHolder: 'Atualmente, apenas comandos de inicialização npx e binários são suportados',
importMcpJson: 'Importar Configuração do Servidor MCP',
importMcpJsonError: 'A estrutura mcpServers está incorreta',
bindDomainHelper:
+1 -1
View File
@@ -2643,7 +2643,7 @@ const message = {
domain: 'Адрес доступа по умолчанию',
domainHelper: 'Например: 192.168.1.1 или example.com',
bindDomain: 'Привязать сайт',
commandPlaceHolder: 'В настоящее время поддерживаются только команды запуска npx',
commandPlaceHolder: 'В настоящее время поддерживаются только команды запуска npx и двоичных файлов',
importMcpJson: 'Импортировать конфигурацию сервера MCP',
importMcpJsonError: 'Структура mcpServers некорректна',
bindDomainHelper:
+1 -1
View File
@@ -2456,7 +2456,7 @@ const message = {
domain: '默認訪問地址',
domainHelper: '例如:192.168.1.1 或者 example.com',
bindDomain: '綁定網站',
commandPlaceHolder: '當前僅支持 npx 啟動命令',
commandPlaceHolder: '當前僅支持 npx 和 二進制啟動的命令',
importMcpJson: '導入 MCP Server配置',
importMcpJsonError: 'mcpServers 結構不正確',
bindDomainHelper: '綁定網站之後會修改所有已安裝 MCP Server 的訪問地址,並關閉端口的外部訪問',
+1 -1
View File
@@ -2458,7 +2458,7 @@ const message = {
domain: '默认访问地址',
domainHelper: '例如:192.168.1.1 或者 example.com',
bindDomain: '绑定网站',
commandPlaceHolder: '当前仅支持 npx 启动命令',
commandPlaceHolder: '当前仅支持 npx 和 二进制启动的命令',
importMcpJson: '导入 MCP Server 配置',
importMcpJsonError: 'mcpServers 结构不正确',
bindDomainHelper: '绑定网站之后会修改所有已安装 MCP Server 的访问地址,并关闭端口的外部访问',
+1 -1
View File
@@ -49,7 +49,7 @@ const GlobalStore = defineStore({
state.themeConfig.theme === 'dark' ||
(state.themeConfig.theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches),
isDarkGoldTheme: (state) => state.themeConfig.primary === '#F0BE96' && state.isProductPro,
docsUrl: (state) => (state.isIntl ? 'https://docs.1panel.pro' : 'https://1panel.cn/docs'),
docsUrl: (state) => (state.isIntl ? 'https://docs.1panel.pro' : 'https://1panel.cn/docs/v1'),
},
actions: {
setOpenMenuTabs(openMenuTabs: boolean) {
@@ -70,9 +70,10 @@ const acceptParams = async (): Promise<void> => {
unUsedList.value = [];
for (const item of list) {
if (
!item.tags ||
item.tags.length === 0 ||
(item.tags.length === 1 && item.tags[0].indexOf('<none>') !== -1 && !item.isUsed)
(!item.tags ||
item.tags.length === 0 ||
(item.tags.length === 1 && item.tags[0].indexOf('<none>') !== -1)) &&
!item.isUsed
) {
unTagList.value.push(item);
}
+5 -1
View File
@@ -395,6 +395,7 @@ const search = async () => {
if (!currentRecord.value) {
currentRecord.value = records.value[0];
} else {
let oldRecordID = currentRecord.value.id;
let beDelete = true;
for (const item of records.value) {
if (item.id === currentRecord.value.id) {
@@ -406,6 +407,9 @@ const search = async () => {
if (beDelete) {
currentRecord.value = records.value[0];
}
if (oldRecordID === currentRecord.value.id && currentRecord.value.status !== 'Waiting') {
return;
}
}
if (currentRecord.value?.records) {
loadRecord(currentRecord.value);
@@ -419,7 +423,7 @@ const forDetail = async (row: Cronjob.Record) => {
const loadRecord = async (row: Cronjob.Record) => {
if (row.records) {
const res = await getRecordLog(row.id);
let log = res.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '');
let log = res.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '').replace(/\r/g, '');
if (currentRecordDetail.value === log) {
return;
}
@@ -74,6 +74,8 @@ const changeVisible = ref(false);
type FormInstance = InstanceType<typeof ElForm>;
const changeFormRef = ref<FormInstance>();
const title = ref();
const oldPrivilege = ref();
const oldPrivilegeIPs = ref();
const changeForm = reactive({
id: 0,
from: '',
@@ -124,6 +126,8 @@ const acceptParams = (params: DialogProps): void => {
changeForm.privilegeIPs = params.privilegeIPs;
changeForm.value = params.value;
changeVisible.value = true;
oldPrivilege.value = params.privilege;
oldPrivilegeIPs.value = params.privilegeIPs;
};
const emit = defineEmits<{ (e: 'search'): void }>();
@@ -167,6 +171,10 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
}
return;
}
if (changeForm.privilege === oldPrivilege.value && changeForm.privilegeIPs === oldPrivilegeIPs.value) {
changeVisible.value = false;
return;
}
if (changeForm.privilege !== 'ip') {
param.value = changeForm.privilege;
} else {
@@ -4,9 +4,6 @@
<template #title>
<back-button name="MySQL" :header="props.database + ' ' + $t('commons.button.set')">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf">
{{ $t('database.confChange') }}
</el-button>
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
@@ -15,6 +12,9 @@
>
{{ $t('database.currentStatus') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf">
{{ $t('database.confChange') }}
</el-button>
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
@@ -159,7 +159,7 @@ const globalStore = GlobalStore();
const loading = ref(false);
const extensions = [javascript(), oneDark];
const activeName = ref('conf');
const activeName = ref('status');
const baseInfo = reactive({
name: '',
@@ -2,9 +2,6 @@
<div v-show="settingShow" v-loading="loading">
<LayoutContent :title="database + ' ' + $t('commons.button.set')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }}
</el-button>
<el-button
type="primary"
:disabled="redisStatus !== 'Running'"
@@ -13,6 +10,9 @@
>
{{ $t('database.currentStatus') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }}
</el-button>
<el-button
type="primary"
:disabled="redisStatus !== 'Running'"
@@ -170,7 +170,7 @@ const rules = reactive({
maxmemory: [Rules.number, checkNumberRange(0, 999999)],
});
const activeName = ref('conf');
const activeName = ref('status');
const statusRef = ref();
const persistenceRef = ref();
@@ -217,7 +217,7 @@ const acceptParams = (prop: DialogProps): void => {
redisStatus.value = prop.status;
database.value = prop.database;
settingShow.value = true;
loadConfFile();
changeTab('status');
};
const portRef = ref();
@@ -328,6 +328,7 @@ const handleClose = () => {
saveContent();
})
.finally(() => {
isEdit.value = false;
closeEditor();
});
} else {
@@ -72,6 +72,7 @@
</div>
<el-form-item prop="name" class="no-border">
<el-input
name="username"
v-model.trim="loginForm.name"
:placeholder="$t('commons.login.username')"
class="form-input"
@@ -85,6 +86,7 @@
</el-form-item>
<el-form-item prop="password" class="no-border">
<el-input
name="password"
type="password"
clearable
v-model.trim="loginForm.password"