Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 103 additions & 2 deletions agent/app/service/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"encoding/hex"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/agent/xpack/xglobal"
"net/http"
"net/url"
"path"
Expand All @@ -28,6 +27,7 @@
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
"github.com/1Panel-dev/1Panel/agent/xpack/xglobal"
)

type AgentService struct{}
Expand Down Expand Up @@ -80,6 +80,7 @@
openclawCaddyPort = 8443
openclawCaddyDataPerm = 0777
openclawCaddyLoopbackAddress = "https://127.0.0.1:8443"
openclawHTTPSVersion = "2026.3.13"
openclawTrustedProxyLoopback = "127.0.0.1/32"
)

Expand Down Expand Up @@ -251,7 +252,7 @@
return nil, err
}
if agentType == constant.AppOpenclaw {
configPath = path.Join(appInstall.GetPath(), "data", "conf", "openclaw.json")

Check failure on line 255 in agent/app/service/agents.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of duplicating this literal "openclaw.json" 4 times.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZz01LBWGQUKvkf3Q_lt&open=AZz01LBWGQUKvkf3Q_lt&pullRequest=12175
}
agent := &model.Agent{
Name: req.Name,
Expand Down Expand Up @@ -1547,7 +1548,7 @@
return nil
}

func buildAgentItem(agent *model.Agent, appInstall *model.AppInstall, envMap map[string]interface{}) dto.AgentItem {

Check failure on line 1551 in agent/app/service/agents.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZz01LBWGQUKvkf3Q_lu&open=AZz01LBWGQUKvkf3Q_lu&pullRequest=12175
agentType := normalizeAgentType(agent.AgentType)
if appInstall != nil && appInstall.ID > 0 && appInstall.App.Key == constant.AppCopaw {
agentType = constant.AppCopaw
Expand Down Expand Up @@ -1576,7 +1577,11 @@
item.Container = appInstall.ContainerName
item.AppVersion = appInstall.Version
if agentType == constant.AppOpenclaw {
item.WebUIPort = appInstall.HttpsPort
if isOpenclawHTTPSVersion(appInstall.Version) {
item.WebUIPort = appInstall.HttpsPort
} else {
item.WebUIPort = appInstall.HttpPort
}
} else {
item.WebUIPort = appInstall.HttpPort
}
Expand All @@ -1592,6 +1597,102 @@
return item
}

func isOpenclawHTTPSVersion(version string) bool {
target := strings.TrimSpace(strings.ToLower(version))
if target == "" || target == "latest" {
return true
}
if !strings.ContainsAny(target, "0123456789") {
return true
}
return common.CompareAppVersion(target, openclawHTTPSVersion)
}

func shouldMigrateOpenclawHTTPSUpgrade(install *model.AppInstall, fromVersion, toVersion string) bool {
if install == nil || install.App.Key != constant.AppOpenclaw {
return false
}
return !isOpenclawHTTPSVersion(fromVersion) && isOpenclawHTTPSVersion(toVersion)
}

func migrateOpenclawHTTPSUpgrade(install *model.AppInstall, fromVersion, toVersion string) error {
systemIP, _ := settingRepo.GetValueByKey("SystemIP")
return migrateOpenclawHTTPSUpgradeWithSystemIP(install, fromVersion, toVersion, systemIP)
}

func migrateOpenclawHTTPSUpgradeWithSystemIP(install *model.AppInstall, fromVersion, toVersion, systemIP string) error {
if !shouldMigrateOpenclawHTTPSUpgrade(install, fromVersion, toVersion) {
return nil
}
migrateOpenclawInstallPorts(install)
if err := migrateOpenclawInstallEnv(install); err != nil {
return err
}
systemIP = strings.TrimSpace(systemIP)
if systemIP == "" || install.HttpsPort <= 0 {
return nil
}
allowedOrigin, err := buildOpenclawAllowedOrigin(systemIP, install.HttpsPort)
if err != nil {
return nil
}
configPath := path.Join(install.GetPath(), "data", "conf", "openclaw.json")
conf, err := readOpenclawConfig(configPath)
if err != nil {
return err
}
setSecurityConfig(conf, dto.AgentSecurityConfig{AllowedOrigins: []string{allowedOrigin}})
if err := writeOpenclawConfigRaw(configPath, conf); err != nil {
return err
}
return writeOpenclawCaddyfile(configPath, []string{allowedOrigin})
}

func migrateOpenclawInstallPorts(install *model.AppInstall) {
if install == nil {
return
}
if install.HttpsPort == 0 && install.HttpPort > 0 {
install.HttpsPort = install.HttpPort
}
if install.HttpPort > 0 {
install.HttpPort = 0
}
}

func migrateOpenclawInstallEnv(install *model.AppInstall) error {
if install == nil {
return nil
}
envMap := make(map[string]interface{})
if strings.TrimSpace(install.Env) != "" {
if err := json.Unmarshal([]byte(install.Env), &envMap); err != nil {
return err
}
}
if install.HttpsPort > 0 {
envMap["PANEL_APP_PORT_HTTPS"] = install.HttpsPort
}
delete(envMap, "PANEL_APP_PORT_HTTP")
payload, err := json.Marshal(envMap)
if err != nil {
return err
}
install.Env = string(payload)
return nil
}

func buildOpenclawAllowedOrigin(host string, port int) (string, error) {
host = strings.TrimSpace(host)
if host == "" || port <= 0 {
return "", fmt.Errorf("invalid openclaw allowed origin")
}
if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") && strings.Count(host, ":") > 1 {
host = "[" + host + "]"
}
return normalizeAllowedOrigin(fmt.Sprintf("https://%s:%d", host, port))
}

func writeOpenclawCaddyfile(configPath string, allowedOrigins []string) error {
content, err := buildOpenclawCaddyfile(allowedOrigins)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions agent/app/service/app_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,11 +670,12 @@
return nil
}

func upgradeInstall(req request.AppInstallUpgrade) error {

Check failure on line 673 in agent/app/service/app_utils.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 116 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZz01K9LGQUKvkf3Q_ls&open=AZz01K9LGQUKvkf3Q_ls&pullRequest=12175
install, err := appInstallRepo.GetFirst(repo.WithByID(req.InstallID))
if err != nil {
return err
}
oldVersion := install.Version
detail, err := appDetailRepo.GetFirst(repo.WithByID(req.DetailID))
if err != nil {
return err
Expand Down Expand Up @@ -801,6 +802,9 @@
}

var newCompose string
if err = migrateOpenclawHTTPSUpgrade(&install, oldVersion, detail.Version); err != nil {
return err
}
if req.DockerCompose == "" {
newCompose, err = getUpgradeCompose(install, detail)
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2419,6 +2419,12 @@ const message = {
reload: 'Reload',
upgradeWarn:
'Upgrading the application will replace the docker-compose.yml file. If there are any changes, you can click to view the file comparison',
openclawHttpsUpgradeNoticeTitle:
'Note: The following instructions only apply to users upgrading OpenClaw from versions earlier than 2026.3.13:',
openclawHttpsUpgradeNoticeItem1:
'After the deployed agent is upgraded, go to Configuration -> Settings -> Security and manually add the access address.',
openclawHttpsUpgradeNoticeItem2:
'The new version now requires HTTPS to access the agent. If you previously used a reverse proxy website, change the proxy target to https://IP:Port.',
newVersion: 'New version',
oldVersion: 'Current version',
composeDiff: 'File comparison',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/es-es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,12 @@ const message = {
showLocal: 'Mostrar apps locales',
reload: 'Recargar',
upgradeWarn: 'Actualizar reemplazará docker-compose.yml. Si hay cambios, puede ver la comparación.',
openclawHttpsUpgradeNoticeTitle:
'Nota: Las siguientes instrucciones solo se aplican a los usuarios que actualizan OpenClaw desde versiones anteriores a 2026.3.13:',
openclawHttpsUpgradeNoticeItem1:
'Después de actualizar el agente desplegado, vaya a Configuración -> Ajustes -> Seguridad y agregue manualmente la dirección de acceso.',
openclawHttpsUpgradeNoticeItem2:
'La nueva versión exige HTTPS para acceder al agente. Si antes usaba un sitio con proxy inverso, cambie el destino del proxy a https://IP:Port.',
newVersion: 'Nueva versión',
oldVersion: 'Versión actual',
composeDiff: 'Comparación de archivos',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2439,6 +2439,12 @@ const message = {
reload: 'リロード',
upgradeWarn:
'アプリケーションのアップグレードは、docker-compose.ymlファイルを置き換えます。変更がある場合は、クリックしてファイルの比較を表示できます',
openclawHttpsUpgradeNoticeTitle:
'注意: 以下の説明は、2026.3.13 より前のバージョンから OpenClaw をアップグレードするユーザーにのみ適用されます:',
openclawHttpsUpgradeNoticeItem1:
'デプロイ済みエージェントのアップグレード完了後、設定 -> 設定 -> セキュリティ に入り、アクセスアドレスを手動で追加してください。',
openclawHttpsUpgradeNoticeItem2:
'新バージョンではエージェントへのアクセスに HTTPS が必須です。以前リバースプロキシサイト経由でアクセスしていた場合は、プロキシ先を https://IP:Port に変更してください。',
newVersion: '新しいバージョン',
oldVersion: '現在のバージョン',
composeDiff: 'ファイルの比較',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,12 @@ const message = {
reload: '새로고침',
upgradeWarn:
'애플리케이션 업그레이드는 docker-compose.yml 파일을 교체합니다. 변경 사항이 있으면 파일 비교를 클릭하여 확인할 수 있습니다.',
openclawHttpsUpgradeNoticeTitle:
'주의: 다음 안내는 2026.3.13 이전 버전에서 OpenClaw 를 업그레이드하는 사용자에게만 적용됩니다:',
openclawHttpsUpgradeNoticeItem1:
'배포된 에이전트 업그레이드가 완료되면 구성 -> 설정 -> 보안 페이지로 이동해 접근 주소를 수동으로 추가해야 합니다.',
openclawHttpsUpgradeNoticeItem2:
'새 버전은 에이전트 접근에 HTTPS 를 강제합니다. 이전에 리버스 프록시 사이트로 접근했다면 프록시 대상 주소를 https://IP:Port 로 변경하세요.',
newVersion: '새 버전',
oldVersion: '현재 버전',
composeDiff: '파일 비교',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/ms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,12 @@ const message = {
showLocal: 'Papar aplikasi tempatan',
reload: 'Muat Semula',
upgradeWarn: 'Meningkatkan aplikasi akan menggantikan fail docker-compose.yml.',
openclawHttpsUpgradeNoticeTitle:
'Nota: Arahan berikut hanya terpakai kepada pengguna yang menaik taraf OpenClaw daripada versi lebih awal daripada 2026.3.13:',
openclawHttpsUpgradeNoticeItem1:
'Selepas ejen yang telah dipasang selesai dinaik taraf, pergi ke Konfigurasi -> Tetapan -> Keselamatan dan tambah alamat akses secara manual.',
openclawHttpsUpgradeNoticeItem2:
'Versi baharu kini mewajibkan HTTPS untuk mengakses ejen. Jika anda sebelum ini menggunakan laman reverse proxy, tukar alamat sasaran proksi kepada https://IP:Port.',
newVersion: 'Versi baru',
oldVersion: 'Versi semasa',
composeDiff: 'Perbandingan fail',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/pt-br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2600,6 +2600,12 @@ const message = {
reload: 'Recarregar',
upgradeWarn:
'Atualizar o aplicativo substituirá o arquivo docker-compose.yml. Se houver alterações, você pode clicar para visualizar a comparação do arquivo',
openclawHttpsUpgradeNoticeTitle:
'Nota: As instruções a seguir se aplicam apenas a usuários que estão atualizando o OpenClaw de versões anteriores à 2026.3.13:',
openclawHttpsUpgradeNoticeItem1:
'Depois que o agente implantado for atualizado, vá para Configuração -> Ajustes -> Segurança e adicione manualmente o endereço de acesso.',
openclawHttpsUpgradeNoticeItem2:
'A nova versão agora exige HTTPS para acessar o agente. Se você usava um site com proxy reverso, altere o destino do proxy para https://IP:Port.',
newVersion: 'Nova versão',
oldVersion: 'Versão atual',
composeDiff: 'Comparação de arquivo',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,12 @@ const message = {
reload: 'Перезагрузить',
upgradeWarn:
'Обновление приложения заменит файл docker-compose.yml. Если есть изменения, вы можете нажать для просмотра сравнения файлов',
openclawHttpsUpgradeNoticeTitle:
'Примечание: Следующие инструкции применяются только к пользователям, обновляющим OpenClaw с версий ниже 2026.3.13:',
openclawHttpsUpgradeNoticeItem1:
'После завершения обновления развернутого агента перейдите в Конфигурация -> Настройки -> Безопасность и вручную добавьте адрес доступа.',
openclawHttpsUpgradeNoticeItem2:
'Новая версия теперь требует HTTPS для доступа к агенту. Если раньше использовался сайт с обратным прокси, измените адрес назначения прокси на https://IP:Port.',
newVersion: 'Новая версия',
oldVersion: 'Текущая версия',
composeDiff: 'Сравнение файлов',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,12 @@ const message = {
reload: 'Yeniden yükle',
upgradeWarn:
'Uygulamanın yükseltilmesi docker-compose.yml dosyasını değiştirecektir. Herhangi bir değişiklik varsa, dosya karşılaştırmasını görüntülemek için tıklayabilirsiniz',
openclawHttpsUpgradeNoticeTitle:
"Not: Aşağıdaki talimatlar yalnızca OpenClaw'ı 2026.3.13 öncesi sürümlerden yükselten kullanıcılar için geçerlidir:",
openclawHttpsUpgradeNoticeItem1:
'Dağıtılmış ajan yükseltmesi tamamlandıktan sonra Yapılandırma -> Ayarlar -> Güvenlik sayfasına gidip erişim adresini manuel olarak ekleyin.',
openclawHttpsUpgradeNoticeItem2:
'Yeni sürüm artık ajana erişim için HTTPS zorunlu kılıyor. Daha önce ters proxy sitesi kullanıyorsanız proxy hedef adresini https://IP:Port olarak değiştirin.',
newVersion: 'Yeni sürüm',
oldVersion: 'Mevcut sürüm',
composeDiff: 'Dosya karşılaştırması',
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/lang/modules/zh-Hant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,10 @@ const message = {
showLocal: '顯示本機應用程式',
reload: '重載',
upgradeWarn: '升級應用程式會取代 docker-compose.yml 檔案,如有更改,可以點選檢視檔案對比',
openclawHttpsUpgradeNoticeTitle: '注意:以下說明僅適用於 OpenClaw 從 2026.3.13 之前版本升級的使用者:',
openclawHttpsUpgradeNoticeItem1: '已部署的智慧體升級完成後,需要進入 配置 → 設定 → 安全 頁面手動新增存取地址。',
openclawHttpsUpgradeNoticeItem2:
'新版本已強制使用 HTTPS 存取智慧體。如果之前透過反向代理網站存取,請將代理目標地址修改為 https://IP:Port。',
newVersion: '新版本',
oldVersion: '當前版本',
composeDiff: '檔案對比',
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,10 @@ const message = {
showLocal: '本地应用',
reload: '重载',
upgradeWarn: '升级应用会替换 docker-compose.yml 文件,如有更改,可以点击查看文件对比',
openclawHttpsUpgradeNoticeTitle: '注意:以下说明仅适用于 OpenClaw 从 2026.3.13 之前版本升级的用户:',
openclawHttpsUpgradeNoticeItem1: '已部署的智能体升级完成后,需要进入 配置 → 设置 → 安全 页面手动添加访问地址。',
openclawHttpsUpgradeNoticeItem2:
'新版本已强制使用 HTTPS 访问智能体。如果之前通过反向代理网站访问,请将代理目标地址修改为 https://IP:Port。',
newVersion: '新版本',
oldVersion: '当前版本',
composeDiff: '文件对比',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/ai/agents/agent/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ const isOpenClawHttpsVersion = (version: string) => {
if (!/\d/.test(target)) {
return true;
}
return compareVersion(target, '2026.3.12');
return compareVersion(target, '2026.3.13');
};

const jumpWebUI = (row: AI.AgentItem) => {
Expand Down
63 changes: 62 additions & 1 deletion frontend/src/views/app-store/installed/upgrade/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@
></el-option>
</el-select>
</el-form-item>
<el-alert
v-if="showOpenclawHttpsUpgradeNotice"
type="warning"
:closable="false"
show-icon
class="upgrade-notice"
>
<template #title>{{ $t('app.openclawHttpsUpgradeNoticeTitle') }}</template>
<div class="upgrade-notice-content">
<div>1. {{ $t('app.openclawHttpsUpgradeNoticeItem1') }}</div>
<div>2. {{ $t('app.openclawHttpsUpgradeNoticeItem2') }}</div>
</div>
</el-alert>
<el-form-item prop="backup" v-if="operateReq.operate === 'upgrade'">
<el-checkbox v-model="operateReq.backup" :label="$t('app.backupApp')" />
<span class="input-help">
Expand Down Expand Up @@ -86,15 +99,17 @@ import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import { App } from '@/api/interface/app';
import { getAppUpdateVersions, ignoreUpgrade, installedOp } from '@/api/modules/app';
import { getAppStoreConfig } from '@/api/modules/setting';
import { compareVersion } from '@/utils/version';
import i18n from '@/lang';
import { ElMessageBox, FormInstance } from 'element-plus';
import { reactive, ref, onBeforeUnmount } from 'vue';
import { computed, onBeforeUnmount, reactive, ref } from 'vue';
import { MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules';
import bus from '@/global/bus';
import { v4 as uuidv4 } from 'uuid';
import { useGlobalStore } from '@/composables/useGlobalStore';
const { currentNode } = useGlobalStore();
const openclawHttpsVersion = '2026.3.13';

const composeDiffRef = ref();
const updateRef = ref<FormInstance>();
Expand Down Expand Up @@ -135,6 +150,40 @@ const ignoreAppReq = reactive({
});
const isEdit = ref(false);
const node = ref('');
const currentVersion = ref('');
const currentAppKey = ref('');

const isOpenclawHttpsVersion = (version: string) => {
const target = String(version || '')
.trim()
.toLowerCase();
if (!target || target === 'latest') {
return true;
}
if (!/\d/.test(target)) {
return false;
}
return compareVersion(target, openclawHttpsVersion);
};

const isLegacyOpenclawVersion = (version: string) => {
const target = String(version || '')
.trim()
.toLowerCase();
if (!target || target === 'latest' || !/\d/.test(target)) {
return false;
}
return !compareVersion(target, openclawHttpsVersion);
};

const showOpenclawHttpsUpgradeNotice = computed(() => {
return (
operateReq.operate === 'upgrade' &&
currentAppKey.value === 'openclaw' &&
isLegacyOpenclawVersion(currentVersion.value) &&
isOpenclawHttpsVersion(operateReq.version)
);
});

const toLink = (link: string) => {
window.open(link, '_blank');
Expand Down Expand Up @@ -174,6 +223,8 @@ const acceptParams = (appInstall: App.AppInstallDto, op: string, opNode?: string
node.value = currentNode.value;
}
isEdit.value = appInstall.isEdit;
currentVersion.value = appInstall.version;
currentAppKey.value = appInstall.appKey;
operateReq.installId = appInstall.id;
operateReq.operate = op;
resourceName.value = appInstall.name;
Expand Down Expand Up @@ -268,3 +319,13 @@ defineExpose({
acceptParams,
});
</script>

<style lang="scss" scoped>
.upgrade-notice {
margin-bottom: 16px;
}

.upgrade-notice-content {
line-height: 1.8;
}
</style>
Loading