Merge branch 'main' into dev

This commit is contained in:
Owen
2026-01-21 14:39:15 -08:00
16 changed files with 3350 additions and 3076 deletions

View File

@@ -29,7 +29,7 @@ jobs:
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
@@ -264,7 +264,7 @@ jobs:
shell: bash
- name: Install Go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: 1.24
@@ -513,7 +513,7 @@ jobs:
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600

View File

@@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Node.js
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'

View File

@@ -23,7 +23,7 @@ jobs:
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
@@ -69,7 +69,7 @@ jobs:
fi
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.aws_account_id }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
@@ -110,7 +110,7 @@ jobs:
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600

View File

@@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'

View File

@@ -1,27 +1,30 @@
# To see all available options, please visit the docs:
# https://docs.pangolin.net/self-host/advanced/config-file
# https://docs.pangolin.net/
gerbil:
start_port: 51820
base_endpoint: "{{.DashboardDomain}}"
app:
dashboard_url: http://localhost:3002
log_level: debug
dashboard_url: "https://{{.DashboardDomain}}"
log_level: "info"
telemetry:
anonymous_usage: true
domains:
domain1:
base_domain: example.com
base_domain: "{{.BaseDomain}}"
server:
secret: my_secret_key
gerbil:
base_endpoint: example.com
orgs:
block_size: 24
subnet_group: 100.90.137.0/20
secret: "{{.Secret}}"
cors:
origins: ["https://{{.DashboardDomain}}"]
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"]
allowed_headers: ["X-CSRF-Token", "Content-Type"]
credentials: false
flags:
require_email_verification: false
disable_signup_without_invite: true
disable_user_create_org: true
disable_user_create_org: false
allow_raw_resources: true
enable_integration_api: true

View File

@@ -21,9 +21,8 @@ http:
# Next.js router (handles everything except API and WebSocket paths)
next-router:
rule: "Host(`{{.DashboardDomain}}`)"
rule: "Host(`{{.DashboardDomain}}`) && !PathPrefix(`/api/v1`)"
service: next-service
priority: 10
entryPoints:
- websecure
middlewares:
@@ -35,7 +34,6 @@ http:
api-router:
rule: "Host(`{{.DashboardDomain}}`) && PathPrefix(`/api/v1`)"
service: api-service
priority: 100
entryPoints:
- websecure
middlewares:
@@ -53,3 +51,12 @@ http:
loadBalancer:
servers:
- url: "http://pangolin:3000" # API/WebSocket server
tcp:
serversTransports:
pp-transport-v1:
proxyProtocol:
version: 1
pp-transport-v2:
proxyProtocol:
version: 2

View File

@@ -3,32 +3,52 @@ api:
dashboard: true
providers:
http:
endpoint: "http://pangolin:3001/api/v1/traefik-config"
pollInterval: "5s"
file:
directory: "/var/dynamic"
watch: true
filename: "/etc/traefik/dynamic_config.yml"
experimental:
plugins:
badger:
moduleName: "github.com/fosrl/badger"
version: "v1.3.0"
version: "{{.BadgerVersion}}"
log:
level: "DEBUG"
level: "INFO"
format: "common"
maxSize: 100
maxBackups: 3
maxAge: 3
compress: true
certificatesResolvers:
letsencrypt:
acme:
httpChallenge:
entryPoint: web
email: "{{.LetsEncryptEmail}}"
storage: "/letsencrypt/acme.json"
caServer: "https://acme-v02.api.letsencrypt.org/directory"
entryPoints:
web:
address: ":80"
websecure:
address: ":9443"
address: ":443"
transport:
respondingTimeouts:
readTimeout: "30m"
http:
tls:
certResolver: "letsencrypt"
encodedCharacters:
allowEncodedSlash: true
allowEncodedQuestionMark: true
serversTransport:
insecureSkipVerify: true
ping:
entryPoint: "web"

View File

@@ -3,8 +3,8 @@ module installer
go 1.24.0
require (
golang.org/x/term v0.38.0
golang.org/x/term v0.39.0
gopkg.in/yaml.v3 v3.0.1
)
require golang.org/x/sys v0.39.0 // indirect
require golang.org/x/sys v0.40.0 // indirect

View File

@@ -1,7 +1,7 @@
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@@ -1,5 +1,7 @@
{
"setupCreate": "創建您的第一個組織、網站和資源",
"headerAuthCompatibilityInfo": "啟用此選項以在缺少驗證令牌時強制回傳 401 未授權回應。這對於不會在沒有伺服器挑戰的情況下發送憑證的瀏覽器或特定 HTTP 函式庫是必需的。",
"headerAuthCompatibility": "擴展相容性",
"setupNewOrg": "新建組織",
"setupCreateOrg": "創建組織",
"setupCreateResources": "創建資源",
@@ -51,6 +53,9 @@
"siteQuestionRemove": "您確定要從組織中刪除該站點嗎?",
"siteManageSites": "管理站點",
"siteDescription": "允許通過安全隧道連接到您的網路",
"sitesBannerTitle": "連接任何網路",
"sitesBannerDescription": "站點是與遠端網路的連接,使 Pangolin 能夠為任何地方的使用者提供對公共或私有資源的存取。在任何可以執行二進位檔案或容器的地方安裝站點網路連接器 (Newt) 以建立連接。",
"sitesBannerButtonText": "安裝站點",
"siteCreate": "創建站點",
"siteCreateDescription2": "按照下面的步驟創建和連接一個新站點",
"siteCreateDescription": "創建一個新站點開始連接您的資源",
@@ -65,8 +70,8 @@
"siteLoadWGConfig": "正在載入 WireGuard 配置...",
"siteDocker": "擴展 Docker 部署詳細資訊",
"toggle": "切換",
"dockerCompose": "Docker 配置",
"dockerRun": "停靠欄",
"dockerCompose": "Docker Compose",
"dockerRun": "Docker Run",
"siteLearnLocal": "本地站點不需要隧道連接,點擊了解更多",
"siteConfirmCopy": "我已經複製了配置資訊",
"searchSitesProgress": "搜索站點...",
@@ -98,9 +103,10 @@
"siteLocalDescriptionSaas": "僅本地資源。沒有隧道。僅在遠程節點上可用。",
"siteSeeAll": "查看所有站點",
"siteTunnelDescription": "確定如何連接到您的網站",
"siteNewtCredentials": "Newt 憑",
"siteNewtCredentialsDescription": "這是 Newt 伺服器的身份驗證憑",
"siteCredentialsSave": "保存您的憑據",
"siteNewtCredentials": "Newt 憑",
"siteNewtCredentialsDescription": "這是 Newt 伺服器的身份驗證憑",
"remoteNodeCredentialsDescription": "這是遠端節點與伺服器進行驗證的方式",
"siteCredentialsSave": "保存您的憑證",
"siteCredentialsSaveDescription": "您只能看到一次。請確保將其複製並保存到一個安全的地方。",
"siteInfo": "站點資訊",
"status": "狀態",
@@ -144,8 +150,14 @@
"expires": "過期時間",
"never": "永不過期",
"shareErrorSelectResource": "請選擇一個資源",
"resourceTitle": "管理資源",
"resourceDescription": "為您的私人應用程式創建安全代理",
"proxyResourceTitle": "管理公開資源",
"proxyResourceDescription": "建立和管理可透過網頁瀏覽器公開存取的資源",
"proxyResourcesBannerTitle": "基於網頁的公開存取",
"proxyResourcesBannerDescription": "公開資源是任何人都可以透過網頁瀏覽器存取的 HTTPS 或 TCP/UDP 代理。與私有資源不同,它們不需要客戶端軟體,並且可以包含基於身份和情境感知的存取策略。",
"clientResourceTitle": "管理私有資源",
"clientResourceDescription": "建立和管理只能透過已連接的客戶端存取的資源",
"privateResourcesBannerTitle": "零信任私有存取",
"privateResourcesBannerDescription": "私有資源使用零信任安全性,確保使用者和機器只能存取您明確授權的資源。連接使用者裝置或機器客戶端以透過安全的虛擬私人網路存取這些資源。",
"resourcesSearch": "搜索資源...",
"resourceAdd": "添加資源",
"resourceErrorDelte": "刪除資源時出錯",
@@ -179,7 +191,7 @@
"baseDomain": "根域名",
"subdomnainDescription": "您的資源可以訪問的子域名。",
"resourceRawSettings": "TCP/UDP 設置",
"resourceRawSettingsDescription": "配置如何過 TCP/UDP 訪問您的資源。 您映射資源到主機Pangolin伺服器上的埠這樣您就可以訪問伺服器-公共-ip:mapped埠的資源",
"resourceRawSettingsDescription": "設定如何過 TCP/UDP 存取資源",
"protocol": "協議",
"protocolSelect": "選擇協議",
"resourcePortNumber": "埠號",
@@ -436,6 +448,16 @@
"inviteEmailSent": "發送邀請郵件給用戶",
"inviteValid": "有效",
"selectDuration": "選擇持續時間",
"selectResource": "選擇資源",
"filterByResource": "依資源篩選",
"resetFilters": "重設篩選條件",
"totalBlocked": "被 Pangolin 阻擋的請求",
"totalRequests": "總請求數",
"requestsByCountry": "依國家/地區的請求",
"requestsByDay": "依日期的請求",
"blocked": "已阻擋",
"allowed": "已允許",
"topCountries": "熱門國家/地區",
"accessRoleSelect": "選擇角色",
"inviteEmailSentDescription": "一封電子郵件已經發送給用戶,帶有下面的訪問連結。他們必須訪問該連結才能接受邀請。",
"inviteSentDescription": "用戶已被邀請。他們必須訪問下面的連結才能接受邀請。",
@@ -465,7 +487,7 @@
"proxyErrorTls": "無效的 TLS 伺服器名稱。使用域名格式,或保存空以刪除 TLS 伺服器名稱。",
"proxyEnableSSL": "啟用 SSL",
"proxyEnableSSLDescription": "啟用 SSL/TLS 加密以確保您目標的 HTTPS 連接。",
"target": "Target",
"target": "目標",
"configureTarget": "配置目標",
"targetErrorFetch": "獲取目標失敗",
"targetErrorFetchDescription": "獲取目標時出錯",
@@ -516,6 +538,8 @@
"targetCreatedDescription": "目標已成功創建",
"targetErrorCreate": "創建目標失敗",
"targetErrorCreateDescription": "創建目標時出錯",
"tlsServerName": "TLS 伺服器名稱",
"tlsServerNameDescription": "用於 SNI 的 TLS 伺服器名稱",
"save": "保存",
"proxyAdditional": "附加代理設置",
"proxyAdditionalDescription": "配置你的資源如何處理代理設置",
@@ -702,6 +726,7 @@
"resourceTransferSubmit": "轉移資源",
"siteDestination": "目標站點",
"searchSites": "搜索站點",
"countries": "國家/地區",
"accessRoleCreate": "創建角色",
"accessRoleCreateDescription": "創建一個新角色來分組用戶並管理他們的權限。",
"accessRoleCreateSubmit": "創建角色",
@@ -825,6 +850,7 @@
"orgPolicyConfig": "配置組織訪問權限",
"idpUpdatedDescription": "身份提供商更新成功",
"redirectUrl": "重定向網址",
"orgIdpRedirectUrls": "重新導向網址",
"redirectUrlAbout": "關於重定向網址",
"redirectUrlAboutDescription": "這是用戶在驗證後將被重定向到的URL。您需要在身份提供商設置中配置此URL。",
"pangolinAuth": "認證 - Pangolin",
@@ -909,6 +935,10 @@
"passwordResetSent": "我們將發送一個驗證碼到這個電子郵件地址。",
"passwordResetCode": "驗證碼",
"passwordResetCodeDescription": "請檢查您的電子郵件以獲取驗證碼。",
"generatePasswordResetCode": "產生密碼重設代碼",
"passwordResetCodeGenerated": "密碼重設代碼已產生",
"passwordResetCodeGeneratedDescription": "請將此代碼分享給使用者。他們可以用它來重設密碼。",
"passwordResetUrl": "重設網址",
"passwordNew": "新密碼",
"passwordNewConfirm": "確認新密碼",
"changePassword": "更改密碼",
@@ -926,6 +956,9 @@
"pincodeAuth": "驗證器代碼",
"pincodeSubmit2": "提交代碼",
"passwordResetSubmit": "請求重設",
"passwordResetAlreadyHaveCode": "輸入代碼",
"passwordResetSmtpRequired": "請聯絡您的管理員",
"passwordResetSmtpRequiredDescription": "需要密碼重設代碼才能重設您的密碼。請聯絡您的管理員尋求協助。",
"passwordBack": "回到密碼",
"loginBack": "返回登錄",
"signup": "註冊",
@@ -1013,6 +1046,7 @@
"updateOrgUser": "更新組織用戶",
"createOrgUser": "創建組織用戶",
"actionUpdateOrg": "更新組織",
"actionRemoveInvitation": "移除邀請",
"actionUpdateUser": "更新用戶",
"actionGetUser": "獲取用戶",
"actionGetOrgUser": "獲取組織用戶",
@@ -1093,12 +1127,15 @@
"actionListSiteResources": "列出站點資源",
"actionUpdateSiteResource": "更新站點資源",
"actionListInvitations": "邀請列表",
"actionExportLogs": "匯出日誌",
"actionViewLogs": "查看日誌",
"noneSelected": "未選擇",
"orgNotFound2": "未找到組織。",
"searchProgress": "搜索中...",
"create": "創建",
"orgs": "組織",
"loginError": "登錄時出錯",
"loginRequiredForDevice": "需要登入以驗證您的裝置。",
"passwordForgot": "忘記密碼?",
"otpAuth": "兩步驗證",
"otpAuthDescription": "從您的身份驗證程序中輸入代碼或您的單次備份代碼。",
@@ -1153,8 +1190,12 @@
"sidebarHome": "首頁",
"sidebarSites": "站點",
"sidebarResources": "資源",
"sidebarProxyResources": "公開",
"sidebarClientResources": "私有",
"sidebarAccessControl": "訪問控制",
"sidebarLogsAndAnalytics": "日誌與分析",
"sidebarUsers": "用戶",
"sidebarAdmin": "管理員",
"sidebarInvitations": "邀請",
"sidebarRoles": "角色",
"sidebarShareableLinks": "分享連結",
@@ -1164,8 +1205,14 @@
"sidebarIdentityProviders": "身份提供商",
"sidebarLicense": "證書",
"sidebarClients": "用戶端",
"sidebarUserDevices": "使用者",
"sidebarMachineClients": "機器",
"sidebarDomains": "域",
"sidebarGeneral": "管理",
"sidebarLogAndAnalytics": "日誌與分析",
"sidebarBluePrints": "藍圖",
"sidebarOrganization": "組織",
"sidebarLogsAnalytics": "分析",
"blueprints": "藍圖",
"blueprintsDescription": "應用聲明配置並查看先前運行的",
"blueprintAdd": "添加藍圖",
@@ -1275,12 +1322,24 @@
"accountSetupSuccess": "帳號設定完成!歡迎來到 Pangolin",
"documentation": "文件",
"saveAllSettings": "保存所有設置",
"saveResourceTargets": "儲存目標",
"saveResourceHttp": "儲存代理設定",
"saveProxyProtocol": "儲存代理協定設定",
"settingsUpdated": "設置已更新",
"settingsUpdatedDescription": "所有設置已成功更新",
"settingsErrorUpdate": "設置更新失敗",
"settingsErrorUpdateDescription": "更新設置時發生錯誤",
"sidebarCollapse": "摺疊",
"sidebarExpand": "展開",
"productUpdateMoreInfo": "還有 {noOfUpdates} 項更新",
"productUpdateInfo": "{noOfUpdates} 項更新",
"productUpdateWhatsNew": "新功能",
"productUpdateTitle": "產品更新",
"productUpdateEmpty": "沒有更新",
"dismissAll": "全部關閉",
"pangolinUpdateAvailable": "有可用更新",
"pangolinUpdateAvailableInfo": "版本 {version} 已準備好安裝",
"pangolinUpdateAvailableReleaseNotes": "查看發行說明",
"newtUpdateAvailable": "更新可用",
"newtUpdateAvailableInfo": "新版本的 Newt 已可用。請更新到最新版本以獲得最佳體驗。",
"domainPickerEnterDomain": "域名",
@@ -1423,6 +1482,9 @@
"and": "和",
"privacyPolicy": "隱私政策"
},
"signUpMarketing": {
"keepMeInTheLoop": "透過電子郵件接收新聞、更新和新功能通知。"
},
"siteRequired": "需要站點。",
"olmTunnel": "Olm 隧道",
"olmTunnelDescription": "使用 Olm 進行用戶端連接",
@@ -1456,15 +1518,14 @@
"sitesFetchError": "獲取站點時出錯。",
"olmErrorFetchReleases": "獲取 Olm 發布版本時出錯。",
"olmErrorFetchLatest": "獲取最新 Olm 發布版本時出錯。",
"remoteSubnets": "遠程子網",
"enterCidrRange": "輸入 CIDR 範圍",
"remoteSubnetsDescription": "添加可以通過用戶端遠端存取該站點的 CIDR 範圍。使用類似 10.0.0.0/24 的格式。這僅適用於 VPN 用戶端連接。",
"resourceEnableProxy": "啟用公共代理",
"resourceEnableProxyDescription": "啟用到此資源的公共代理。這允許外部網路通過開放埠訪問資源。需要 Traefik 配置。",
"externalProxyEnabled": "外部代理已啟用",
"addNewTarget": "添加新目標",
"targetsList": "目標列表",
"advancedMode": "高級模式",
"advancedSettings": "進階設定",
"targetErrorDuplicateTargetFound": "找到重複的目標",
"healthCheckHealthy": "正常",
"healthCheckUnhealthy": "不正常",
@@ -1476,6 +1537,7 @@
"enableHealthChecksDescription": "監視此目標的健康狀況。如果需要,您可以監視一個不同的終點。",
"healthScheme": "方法",
"healthSelectScheme": "選擇方法",
"healthCheckPortInvalid": "健康檢查連接埠必須介於 1 到 65535 之間",
"healthCheckPath": "路徑",
"healthHostname": "IP / 主機",
"healthPort": "埠",
@@ -1524,9 +1586,15 @@
"resourcesTableNoProxyResourcesFound": "未找到代理資源。",
"resourcesTableNoInternalResourcesFound": "未找到內部資源。",
"resourcesTableDestination": "目標",
"resourcesTableTheseResourcesForUseWith": "這些資源供...使用",
"resourcesTableAlias": "別名",
"resourcesTableClients": "用戶端",
"resourcesTableAndOnlyAccessibleInternally": "且僅在與用戶端連接時可內部訪問。",
"resourcesTableNoTargets": "無目標",
"resourcesTableHealthy": "健康",
"resourcesTableDegraded": "降級",
"resourcesTableOffline": "離線",
"resourcesTableUnknown": "未知",
"resourcesTableNotMonitored": "未監控",
"editInternalResourceDialogEditClientResource": "編輯用戶端資源",
"editInternalResourceDialogUpdateResourceProperties": "更新 {resourceName} 的資源屬性和目標配置。",
"editInternalResourceDialogResourceProperties": "資源屬性",
@@ -1547,6 +1615,17 @@
"editInternalResourceDialogInvalidIPAddressFormat": "無效的 IP 位址格式",
"editInternalResourceDialogDestinationPortMin": "目標埠必須至少為 1",
"editInternalResourceDialogDestinationPortMax": "目標埠必須小於 65536",
"editInternalResourceDialogPortModeRequired": "連接埠模式需要協定、代理連接埠和目標連接埠",
"editInternalResourceDialogMode": "模式",
"editInternalResourceDialogModePort": "連接埠",
"editInternalResourceDialogModeHost": "主機",
"editInternalResourceDialogModeCidr": "CIDR",
"editInternalResourceDialogDestination": "目的地",
"editInternalResourceDialogDestinationHostDescription": "站點網路上資源的 IP 位址或主機名稱。",
"editInternalResourceDialogDestinationIPDescription": "站點網路上資源的 IP 或主機名稱位址。",
"editInternalResourceDialogDestinationCidrDescription": "站點網路上資源的 CIDR 範圍。",
"editInternalResourceDialogAlias": "別名",
"editInternalResourceDialogAliasDescription": "此資源的可選內部 DNS 別名。",
"createInternalResourceDialogNoSitesAvailable": "暫無可用站點",
"createInternalResourceDialogNoSitesAvailableDescription": "您需要至少配置一個子網的 Newt 站點來創建內部資源。",
"createInternalResourceDialogClose": "關閉",
@@ -1555,9 +1634,8 @@
"createInternalResourceDialogResourceProperties": "資源屬性",
"createInternalResourceDialogName": "名稱",
"createInternalResourceDialogSite": "站點",
"createInternalResourceDialogSelectSite": "選擇站點...",
"createInternalResourceDialogSearchSites": "搜索站點...",
"createInternalResourceDialogNoSitesFound": "未找到站點。",
"selectSite": "選擇站點...",
"noSitesFound": "找不到站點。",
"createInternalResourceDialogProtocol": "協議",
"createInternalResourceDialogTcp": "TCP",
"createInternalResourceDialogUdp": "UDP",
@@ -1580,11 +1658,22 @@
"createInternalResourceDialogInvalidIPAddressFormat": "無效的 IP 位址格式",
"createInternalResourceDialogDestinationPortMin": "目標埠必須至少為 1",
"createInternalResourceDialogDestinationPortMax": "目標埠必須小於 65536",
"createInternalResourceDialogPortModeRequired": "連接埠模式需要協定、代理連接埠和目標連接埠",
"createInternalResourceDialogMode": "模式",
"createInternalResourceDialogModePort": "連接埠",
"createInternalResourceDialogModeHost": "主機",
"createInternalResourceDialogModeCidr": "CIDR",
"createInternalResourceDialogDestination": "目的地",
"createInternalResourceDialogDestinationHostDescription": "站點網路上資源的 IP 位址或主機名稱。",
"createInternalResourceDialogDestinationCidrDescription": "站點網路上資源的 CIDR 範圍。",
"createInternalResourceDialogAlias": "別名",
"createInternalResourceDialogAliasDescription": "此資源的可選內部 DNS 別名。",
"siteConfiguration": "配置",
"siteAcceptClientConnections": "接受用戶端連接",
"siteAcceptClientConnectionsDescription": "允許其他設備透過此 Newt 實例使用用戶端作為閘道器連接。",
"siteAddress": "站點地址",
"siteAddressDescription": "指定主機的 IP 位址以供用戶端連接。這是 Pangolin 網路中站點的內部地址,供用戶端訪問。必須在 Org 子網內。",
"siteNameDescription": "站點的顯示名稱,可以稍後更改。",
"autoLoginExternalIdp": "自動使用外部 IDP 登錄",
"autoLoginExternalIdpDescription": "立即將用戶重定向到外部 IDP 進行身份驗證。",
"selectIdp": "選擇 IDP",
@@ -1608,6 +1697,8 @@
"remoteExitNodeConfirmDelete": "確認刪除節點",
"remoteExitNodeDelete": "刪除節點",
"sidebarRemoteExitNodes": "遠程節點",
"remoteExitNodeId": "ID",
"remoteExitNodeSecretKey": "密鑰",
"remoteExitNodeCreate": {
"title": "創建節點",
"description": "創建一個新節點來擴展您的網路連接",
@@ -1731,12 +1822,33 @@
"idpAzureClientIdDescription2": "您的 Azure 應用程式註冊用戶端 ID",
"idpAzureClientSecretDescription2": "您的 Azure 應用程式註冊用戶端金鑰",
"idpGoogleDescription": "Google OAuth2/OIDC 提供商",
"idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider",
"idpAzureDescription": "Microsoft Azure OAuth2/OIDC 提供者",
"subnet": "子網",
"subnetDescription": "此組織網路配置的子網。",
"customDomain": "自訂網域",
"authPage": "認證頁面",
"authPageDescription": "配置您的組織認證頁面",
"authPageDomain": "認證頁面域",
"authPageBranding": "自訂品牌",
"authPageBrandingDescription": "設定此組織驗證頁面上顯示的品牌",
"authPageBrandingUpdated": "驗證頁面品牌更新成功",
"authPageBrandingRemoved": "驗證頁面品牌移除成功",
"authPageBrandingRemoveTitle": "移除驗證頁面品牌",
"authPageBrandingQuestionRemove": "您確定要移除驗證頁面的品牌嗎?",
"authPageBrandingDeleteConfirm": "確認刪除品牌",
"brandingLogoURL": "Logo 網址",
"brandingPrimaryColor": "主要顏色",
"brandingLogoWidth": "寬度 (px)",
"brandingLogoHeight": "高度 (px)",
"brandingOrgTitle": "組織驗證頁面標題",
"brandingOrgDescription": "{orgName} 將被替換為組織名稱",
"brandingOrgSubtitle": "組織驗證頁面副標題",
"brandingResourceTitle": "資源驗證頁面標題",
"brandingResourceSubtitle": "資源驗證頁面副標題",
"brandingResourceDescription": "{resourceName} 將被替換為組織名稱",
"saveAuthPageDomain": "儲存網域",
"saveAuthPageBranding": "儲存品牌",
"removeAuthPageBranding": "移除品牌",
"noDomainSet": "沒有域設置",
"changeDomain": "更改域",
"selectDomain": "選擇域",
@@ -1764,6 +1876,15 @@
"orgAuthChooseIdpDescription": "選擇您的身份提供商以繼續",
"orgAuthNoIdpConfigured": "此機構沒有配置任何身份提供者。您可以使用您的 Pangolin 身份登錄。",
"orgAuthSignInWithPangolin": "使用 Pangolin 登錄",
"orgAuthSignInToOrg": "登入組織",
"orgAuthSelectOrgTitle": "組織登入",
"orgAuthSelectOrgDescription": "輸入您的組織 ID 以繼續",
"orgAuthOrgIdPlaceholder": "your-organization",
"orgAuthOrgIdHelp": "輸入您組織的唯一識別碼",
"orgAuthSelectOrgHelp": "輸入組織 ID 後,您將被導向到組織的登入頁面,在那裡您可以使用 SSO 或組織憑證。",
"orgAuthRememberOrgId": "記住此組織 ID",
"orgAuthBackToSignIn": "返回標準登入",
"orgAuthNoAccount": "沒有帳戶?",
"subscriptionRequiredToUse": "需要訂閱才能使用此功能。",
"idpDisabled": "身份提供者已禁用。",
"orgAuthPageDisabled": "組織認證頁面已禁用。",
@@ -1778,6 +1899,8 @@
"enableTwoFactorAuthentication": "啟用兩步驗證",
"completeSecuritySteps": "完成安全步驟",
"securitySettings": "安全設定",
"dangerSection": "危險區域",
"dangerSectionDescription": "永久刪除與此組織相關的所有資料",
"securitySettingsDescription": "配置您組織的安全策略",
"requireTwoFactorForAllUsers": "所有用戶需要兩步驗證",
"requireTwoFactorDescription": "如果啟用,此組織的所有內部用戶必須啟用雙重身份驗證才能訪問組織。",
@@ -1815,7 +1938,7 @@
"securityPolicyChangeWarningText": "這將影響組織中的所有用戶",
"authPageErrorUpdateMessage": "更新身份驗證頁面設置時出錯",
"authPageErrorUpdate": "無法更新認證頁面",
"authPageUpdated": "身份驗證頁面更新成功",
"authPageDomainUpdated": "驗證頁面網域更新成功",
"healthCheckNotAvailable": "本地的",
"rewritePath": "重寫路徑",
"rewritePathDescription": "在轉發到目標之前,可以選擇重寫路徑。",
@@ -1841,8 +1964,19 @@
"enterpriseEdition": "企業版",
"unlicensed": "未授權",
"beta": "測試版",
"manageClients": "管理用戶端",
"manageClientsDescription": "用戶端是可以連接到您的站點的設備",
"manageUserDevices": "使用者裝置",
"manageUserDevicesDescription": "查看和管理使用者用於私密連接資源的裝置",
"downloadClientBannerTitle": "下載 Pangolin 客戶端",
"downloadClientBannerDescription": "下載適用於您系統的 Pangolin 客戶端,以連接到 Pangolin 網路並私密存取資源。",
"manageMachineClients": "管理機器客戶端",
"manageMachineClientsDescription": "建立和管理伺服器和系統用於私密連接資源的客戶端",
"machineClientsBannerTitle": "伺服器與自動化系統",
"machineClientsBannerDescription": "機器客戶端適用於與特定使用者無關的伺服器和自動化系統。它們使用 ID 和密鑰進行驗證,可以透過 Pangolin CLI、Olm CLI 或 Olm 容器執行。",
"machineClientsBannerPangolinCLI": "Pangolin CLI",
"machineClientsBannerOlmCLI": "Olm CLI",
"machineClientsBannerOlmContainer": "Olm 容器",
"clientsTableUserClients": "使用者",
"clientsTableMachineClients": "機器",
"licenseTableValidUntil": "有效期至",
"saasLicenseKeysSettingsTitle": "企業許可證",
"saasLicenseKeysSettingsDescription": "為自我託管的 Pangolin 實例生成和管理企業許可證金鑰",
@@ -1982,6 +2116,7 @@
"clientMessageRemove": "一旦刪除,用戶端將無法連接到站點。",
"sidebarLogs": "日誌",
"request": "請求",
"requests": "請求",
"logs": "日誌",
"logsSettingsDescription": "監視從此 orginization 中收集的日誌",
"searchLogs": "搜索日誌...",
@@ -1990,6 +2125,8 @@
"timestamp": "時間戳",
"accessLogs": "訪問日誌",
"exportCsv": "導出 CSV",
"exportError": "匯出 CSV 時發生未知錯誤",
"exportCsvTooltip": "在時間範圍內",
"actorId": "執行者 ID",
"allowedByRule": "根據規則允許",
"allowedNoAuth": "無認證",
@@ -2007,6 +2144,7 @@
"ip": "IP",
"reason": "原因",
"requestLogs": "請求日誌",
"requestAnalytics": "請求分析",
"host": "主機",
"location": "地點",
"actionLogs": "操作日誌",
@@ -2016,6 +2154,7 @@
"logRetention": "日誌保留",
"logRetentionDescription": "管理不同類型的日誌為這個機構保留多長時間或禁用這些日誌",
"requestLogsDescription": "查看此機構資源的詳細請求日誌",
"requestAnalyticsDescription": "查看此組織資源的詳細請求分析",
"logRetentionRequestLabel": "請求日誌保留",
"logRetentionRequestDescription": "保留請求日誌的時間",
"logRetentionAccessLabel": "訪問日誌保留",
@@ -2029,6 +2168,7 @@
"logRetention30Days": "30 天",
"logRetention90Days": "90 天",
"logRetentionForever": "永遠的",
"logRetentionEndOfFollowingYear": "次年年底",
"actionLogsDescription": "查看此機構執行的操作歷史",
"accessLogsDescription": "查看此機構資源的訪問認證請求",
"licenseRequiredToUse": "需要企業許可證才能使用此功能。",
@@ -2084,6 +2224,43 @@
"supportMessageSent": "消息已發送!",
"supportWillContact": "我們很快就會聯繫起來!",
"selectLogRetention": "選擇保留日誌",
"terms": "條款",
"privacy": "隱私權",
"security": "安全性",
"docs": "文件",
"deviceActivation": "裝置啟用",
"deviceCodeInvalidFormat": "代碼必須為 9 個字元例如A1AJ-N5JD",
"deviceCodeInvalidOrExpired": "代碼無效或已過期",
"deviceCodeVerifyFailed": "驗證裝置代碼失敗",
"signedInAs": "已登入為",
"deviceCodeEnterPrompt": "輸入裝置上顯示的代碼",
"continue": "繼續",
"deviceUnknownLocation": "未知位置",
"deviceAuthorizationRequested": "此授權請求來自 {location},時間為 {date}。請確保您信任此裝置,因為它將獲得帳戶存取權限。",
"deviceLabel": "裝置:{deviceName}",
"deviceWantsAccess": "想要存取您的帳戶",
"deviceExistingAccess": "現有存取權限:",
"deviceFullAccess": "完整帳戶存取權限",
"deviceOrganizationsAccess": "存取您帳戶有權限的所有組織",
"deviceAuthorize": "授權 {applicationName}",
"deviceConnected": "裝置已連接!",
"deviceAuthorizedMessage": "裝置已獲授權存取您的帳戶。請返回客戶端應用程式。",
"pangolinCloud": "Pangolin 雲端",
"viewDevices": "查看裝置",
"viewDevicesDescription": "管理您已連接的裝置",
"noDevices": "找不到裝置",
"dateCreated": "建立日期",
"unnamedDevice": "未命名裝置",
"deviceQuestionRemove": "您確定要刪除此裝置嗎?",
"deviceMessageRemove": "此操作無法復原。",
"deviceDeleteConfirm": "刪除裝置",
"deleteDevice": "刪除裝置",
"errorLoadingDevices": "載入裝置時發生錯誤",
"failedToLoadDevices": "載入裝置失敗",
"deviceDeleted": "裝置已刪除",
"deviceDeletedDescription": "裝置已成功刪除。",
"errorDeletingDevice": "刪除裝置時發生錯誤",
"failedToDeleteDevice": "刪除裝置失敗",
"showColumns": "顯示列",
"hideColumns": "隱藏列",
"columnVisibility": "列可見性",
@@ -2097,5 +2274,125 @@
"selectedResources": "選定的資源",
"enableSelected": "啟用選中的",
"disableSelected": "禁用選中的",
"checkSelectedStatus": "檢查選中的狀態"
"checkSelectedStatus": "檢查選中的狀態",
"clients": "客戶端",
"accessClientSelect": "選擇機器客戶端",
"resourceClientDescription": "可以存取此資源的機器客戶端",
"regenerate": "重新產生",
"credentials": "憑證",
"savecredentials": "儲存憑證",
"regenerateCredentialsButton": "重新產生憑證",
"regenerateCredentials": "重新產生憑證",
"generatedcredentials": "已產生的憑證",
"copyandsavethesecredentials": "複製並儲存這些憑證",
"copyandsavethesecredentialsdescription": "離開此頁面後將不會再顯示這些憑證。請立即安全儲存。",
"credentialsSaved": "憑證已儲存",
"credentialsSavedDescription": "憑證已成功重新產生並儲存。",
"credentialsSaveError": "憑證儲存錯誤",
"credentialsSaveErrorDescription": "重新產生和儲存憑證時發生錯誤。",
"regenerateCredentialsWarning": "重新產生憑證將使先前的憑證失效並導致斷線。請確保更新任何使用這些憑證的設定。",
"confirm": "確認",
"regenerateCredentialsConfirmation": "您確定要重新產生憑證嗎?",
"endpoint": "端點",
"Id": "ID",
"SecretKey": "密鑰",
"niceId": "友善 ID",
"niceIdUpdated": "友善 ID 已更新",
"niceIdUpdatedSuccessfully": "友善 ID 更新成功",
"niceIdUpdateError": "更新友善 ID 時發生錯誤",
"niceIdUpdateErrorDescription": "更新友善 ID 時發生錯誤。",
"niceIdCannotBeEmpty": "友善 ID 不能為空",
"enterIdentifier": "輸入識別碼",
"identifier": "識別碼",
"deviceLoginUseDifferentAccount": "不是您嗎?使用其他帳戶。",
"deviceLoginDeviceRequestingAccessToAccount": "有裝置正在請求存取此帳戶。",
"noData": "無資料",
"machineClients": "機器客戶端",
"install": "安裝",
"run": "執行",
"clientNameDescription": "客戶端的顯示名稱,可以稍後更改。",
"clientAddress": "客戶端位址(進階)",
"setupFailedToFetchSubnet": "取得預設子網路失敗",
"setupSubnetAdvanced": "子網路(進階)",
"setupSubnetDescription": "此組織內部網路的子網路。",
"setupUtilitySubnet": "工具子網路(進階)",
"setupUtilitySubnetDescription": "此組織別名位址和 DNS 伺服器的子網路。",
"siteRegenerateAndDisconnect": "重新產生並斷開連接",
"siteRegenerateAndDisconnectConfirmation": "您確定要重新產生憑證並斷開此站點的連接嗎?",
"siteRegenerateAndDisconnectWarning": "這將重新產生憑證並立即斷開站點連接。站點需要使用新憑證重新啟動。",
"siteRegenerateCredentialsConfirmation": "您確定要重新產生此站點的憑證嗎?",
"siteRegenerateCredentialsWarning": "這將重新產生憑證。站點將保持連接,直到您手動重新啟動並使用新憑證。",
"clientRegenerateAndDisconnect": "重新產生並斷開連接",
"clientRegenerateAndDisconnectConfirmation": "您確定要重新產生憑證並斷開此客戶端的連接嗎?",
"clientRegenerateAndDisconnectWarning": "這將重新產生憑證並立即斷開客戶端連接。客戶端需要使用新憑證重新啟動。",
"clientRegenerateCredentialsConfirmation": "您確定要重新產生此客戶端的憑證嗎?",
"clientRegenerateCredentialsWarning": "這將重新產生憑證。客戶端將保持連接,直到您手動重新啟動並使用新憑證。",
"remoteExitNodeRegenerateAndDisconnect": "重新產生並斷開連接",
"remoteExitNodeRegenerateAndDisconnectConfirmation": "您確定要重新產生憑證並斷開此遠端出口節點的連接嗎?",
"remoteExitNodeRegenerateAndDisconnectWarning": "這將重新產生憑證並立即斷開遠端出口節點連接。遠端出口節點需要使用新憑證重新啟動。",
"remoteExitNodeRegenerateCredentialsConfirmation": "您確定要重新產生此遠端出口節點的憑證嗎?",
"remoteExitNodeRegenerateCredentialsWarning": "這將重新產生憑證。遠端出口節點將保持連接,直到您手動重新啟動並使用新憑證。",
"agent": "代理",
"personalUseOnly": "僅限個人使用",
"loginPageLicenseWatermark": "此實例僅授權個人使用。",
"instanceIsUnlicensed": "此實例未授權。",
"portRestrictions": "連接埠限制",
"allPorts": "全部",
"custom": "自訂",
"allPortsAllowed": "允許所有連接埠",
"allPortsBlocked": "阻擋所有連接埠",
"tcpPortsDescription": "指定此資源允許的 TCP 連接埠。使用「*」表示所有連接埠留空表示阻擋全部或輸入以逗號分隔的連接埠和範圍例如80,443,8000-9000。",
"udpPortsDescription": "指定此資源允許的 UDP 連接埠。使用「*」表示所有連接埠留空表示阻擋全部或輸入以逗號分隔的連接埠和範圍例如53,123,500-600。",
"organizationLoginPageTitle": "組織登入頁面",
"organizationLoginPageDescription": "自訂此組織的登入頁面",
"resourceLoginPageTitle": "資源登入頁面",
"resourceLoginPageDescription": "自訂個別資源的登入頁面",
"enterConfirmation": "輸入確認",
"blueprintViewDetails": "詳細資訊",
"defaultIdentityProvider": "預設身份提供者",
"defaultIdentityProviderDescription": "當選擇預設身份提供者時,使用者將自動被重新導向到該提供者進行驗證。",
"editInternalResourceDialogNetworkSettings": "網路設定",
"editInternalResourceDialogAccessPolicy": "存取策略",
"editInternalResourceDialogAddRoles": "新增角色",
"editInternalResourceDialogAddUsers": "新增使用者",
"editInternalResourceDialogAddClients": "新增客戶端",
"editInternalResourceDialogDestinationLabel": "目的地",
"editInternalResourceDialogDestinationDescription": "指定內部資源的目的地位址。根據所選模式這可以是主機名稱、IP 位址或 CIDR 範圍。可選擇設定內部 DNS 別名以便識別。",
"editInternalResourceDialogPortRestrictionsDescription": "限制對特定 TCP/UDP 連接埠的存取,或允許/阻擋所有連接埠。",
"editInternalResourceDialogTcp": "TCP",
"editInternalResourceDialogUdp": "UDP",
"editInternalResourceDialogIcmp": "ICMP",
"editInternalResourceDialogAccessControl": "存取控制",
"editInternalResourceDialogAccessControlDescription": "控制哪些角色、使用者和機器客戶端在連接時可以存取此資源。管理員始終擁有存取權限。",
"editInternalResourceDialogPortRangeValidationError": "連接埠範圍必須是「*」表示所有連接埠或以逗號分隔的連接埠和範圍列表例如「80,443,8000-9000」。連接埠必須介於 1 到 65535 之間。",
"orgAuthWhatsThis": "我在哪裡可以找到我的組織 ID",
"learnMore": "了解更多",
"backToHome": "返回首頁",
"needToSignInToOrg": "需要使用您組織的身份提供者嗎?",
"maintenanceMode": "維護模式",
"maintenanceModeDescription": "向訪客顯示維護頁面",
"maintenanceModeType": "維護模式類型",
"showMaintenancePage": "向訪客顯示維護頁面",
"enableMaintenanceMode": "啟用維護模式",
"automatic": "自動",
"automaticModeDescription": "僅在所有後端目標都關閉或不健康時顯示維護頁面。只要至少有一個目標健康,您的資源就會正常運作。",
"forced": "強制",
"forcedModeDescription": "無論後端健康狀況如何,始終顯示維護頁面。當您想要阻止所有存取時,用於計劃維護。",
"warning:": "警告:",
"forcedeModeWarning": "所有流量將被導向維護頁面。您的後端資源將不會收到任何請求。",
"pageTitle": "頁面標題",
"pageTitleDescription": "維護頁面上顯示的主標題",
"maintenancePageMessage": "維護訊息",
"maintenancePageMessagePlaceholder": "我們很快就會回來!我們的網站目前正在進行預定維護。",
"maintenancePageMessageDescription": "說明維護的詳細訊息",
"maintenancePageTimeTitle": "預計完成時間(可選)",
"maintenanceTime": "例如2 小時、11 月 1 日下午 5:00",
"maintenanceEstimatedTimeDescription": "您預計何時完成維護",
"editDomain": "編輯網域",
"editDomainDescription": "為您的資源選擇網域",
"maintenanceModeDisabledTooltip": "此功能需要有效的授權才能啟用。",
"maintenanceScreenTitle": "服務暫時無法使用",
"maintenanceScreenMessage": "我們目前遇到技術問題。請稍後再試。",
"maintenanceScreenEstimatedCompletion": "預計完成時間:",
"createInternalResourceDialogDestinationRequired": "目的地為必填欄位"
}

1776
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -33,9 +33,9 @@
"format": "prettier --write ."
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "8.2.0",
"@aws-sdk/client-s3": "3.955.0",
"@faker-js/faker": "10.1.0",
"@asteasolutions/zod-to-openapi": "8.4.0",
"@aws-sdk/client-s3": "3.971.0",
"@faker-js/faker": "10.2.0",
"@headlessui/react": "2.2.9",
"@hookform/resolvers": "5.2.2",
"@monaco-editor/react": "4.7.0",
@@ -92,7 +92,7 @@
"http-errors": "2.0.1",
"i": "0.3.7",
"input-otp": "1.4.2",
"ioredis": "5.8.2",
"ioredis": "5.9.2",
"jmespath": "0.16.0",
"js-yaml": "4.1.1",
"jsonwebtoken": "9.0.3",
@@ -100,7 +100,7 @@
"maxmind": "5.0.1",
"moment": "2.30.1",
"next": "15.5.9",
"next-intl": "4.6.1",
"next-intl": "4.7.0",
"next-themes": "0.4.6",
"nextjs-toploader": "3.9.17",
"node-cache": "5.1.2",
@@ -109,21 +109,21 @@
"npm": "11.7.0",
"nprogress": "0.2.0",
"oslo": "1.2.1",
"pg": "8.16.3",
"posthog-node": "5.17.4",
"pg": "8.17.1",
"posthog-node": "5.23.0",
"qrcode.react": "4.2.0",
"react": "19.2.3",
"react-day-picker": "9.13.0",
"react-dom": "19.2.3",
"react-easy-sort": "1.8.0",
"react-hook-form": "7.68.0",
"react-hook-form": "7.71.1",
"react-icons": "5.5.0",
"rebuild": "0.1.2",
"recharts": "2.15.4",
"reodotdev": "1.0.0",
"resend": "6.6.0",
"resend": "6.8.0",
"semver": "7.7.3",
"stripe": "20.1.0",
"stripe": "20.2.0",
"swagger-ui-express": "5.0.1",
"tailwind-merge": "3.4.0",
"topojson-client": "3.1.0",
@@ -133,10 +133,10 @@
"visionscarto-world-atlas": "1.0.0",
"winston": "3.19.0",
"winston-daily-rotate-file": "5.0.0",
"ws": "8.18.3",
"ws": "8.19.0",
"yaml": "2.8.2",
"yargs": "18.0.0",
"zod": "4.2.1",
"zod": "4.3.5",
"zod-validation-error": "5.0.0"
},
"devDependencies": {
@@ -170,12 +170,12 @@
"esbuild": "0.27.2",
"esbuild-node-externals": "1.20.1",
"postcss": "8.5.6",
"prettier": "3.7.4",
"react-email": "5.0.7",
"prettier": "3.8.0",
"react-email": "5.2.5",
"tailwindcss": "4.1.18",
"tsc-alias": "1.8.16",
"tsx": "4.21.0",
"typescript": "5.9.3",
"typescript-eslint": "8.49.0"
"typescript-eslint": "8.53.1"
}
}

View File

@@ -265,4 +265,3 @@ function GeneralSectionForm({ org }: SectionFormProps) {
</SettingsSection>
);
}

View File

@@ -319,7 +319,7 @@ export default function CredentialsPage() {
{!loadingDefaults && (
<>
{wgConfig ? (
<div className="flex items-center gap-4">
<div className="flex flex-col sm:flex-row items-center gap-4">
<CopyTextBox
text={wgConfig}
outline={true}

View File

@@ -673,7 +673,7 @@ export default function Page() {
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<div className="flex items-center gap-4">
<div className="flex flex-col sm:flex-row items-center gap-4">
<CopyTextBox text={wgConfig} />
<div
className={`relative w-fit border rounded-md`}

View File

@@ -60,6 +60,18 @@ export default function LocaleSwitcher() {
{
value: "zh-TW",
label: "繁體中文"
},
{
value: "ru-RU",
label: "Русский"
},
{
value: "bg-BG",
label: "Български"
},
{
value: "cs-CZ",
label: "Čeština"
}
]}
/>