mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
feat: 同步后端修改
This commit is contained in:
@@ -11,9 +11,9 @@ const (
|
||||
|
||||
// Redirect 重定向配置
|
||||
type Redirect struct {
|
||||
Type RedirectType // 重定向类型
|
||||
From string // 源地址,如: "example.com", "http://example.com", "/old"
|
||||
To string // 目标地址,如: "https://example.com"
|
||||
KeepURI bool // 是否保持 URI 不变(即保留请求参数)
|
||||
StatusCode int // 自定义状态码,如: 301, 302, 307, 308,默认 308
|
||||
Type RedirectType `json:"type"` // 重定向类型
|
||||
From string `json:"from"` // 源地址,如: "example.com", "http://example.com", "/old"
|
||||
To string `json:"to"` // 目标地址,如: "https://example.com"
|
||||
KeepURI bool `json:"keep_uri"` // 是否保持 URI 不变(即保留请求参数)
|
||||
StatusCode int `json:"status_code"` // 自定义状态码,如: 301, 302, 307, 308,默认 308
|
||||
}
|
||||
|
||||
@@ -142,33 +142,33 @@ type VhostProxy interface {
|
||||
|
||||
// Listen 监听配置
|
||||
type Listen struct {
|
||||
Address string // 监听地址,如: "80", "0.0.0.0:80", "[::]:443"
|
||||
Args []string // 其他参数,如: ["default_server", "ssl", "quic"]
|
||||
Address string `form:"address" json:"address"` // 监听地址,如: "80", "0.0.0.0:80", "[::]:443"
|
||||
Args []string `form:"args" json:"args"` // 其他参数,如: ["default_server", "ssl", "quic"]
|
||||
}
|
||||
|
||||
// SSLConfig SSL/TLS 配置
|
||||
type SSLConfig struct {
|
||||
Cert string // 证书路径
|
||||
Key string // 私钥路径
|
||||
Protocols []string // 支持的协议,如: ["TLSv1.2", "TLSv1.3"]
|
||||
Ciphers string // 加密套件
|
||||
Cert string `json:"cert"` // 证书路径
|
||||
Key string `json:"key"` // 私钥路径
|
||||
Protocols []string `json:"protocols"` // 支持的协议,如: ["TLSv1.2", "TLSv1.3"]
|
||||
Ciphers string `json:"ciphers"` // 加密套件
|
||||
|
||||
// 高级选项
|
||||
HSTS bool // HTTP 严格传输安全
|
||||
OCSP bool // OCSP Stapling
|
||||
HTTPRedirect bool // HTTP 强制跳转 HTTPS
|
||||
AltSvc string // Alt-Svc 配置,如: 'h3=":443"; ma=86400'
|
||||
HSTS bool `json:"hsts"` // HTTP 严格传输安全
|
||||
OCSP bool `json:"ocsp"` // OCSP Stapling
|
||||
HTTPRedirect bool `json:"http_redirect"` // HTTP 强制跳转 HTTPS
|
||||
AltSvc string `json:"alt_svc"` // Alt-Svc 配置,如: 'h3=":443"; ma=86400'
|
||||
}
|
||||
|
||||
// RateLimit 限流限速配置
|
||||
type RateLimit struct {
|
||||
Rate string // 速率限制,如: "512k", "10r/s"
|
||||
Concurrent int // 并发连接数限制
|
||||
Zone map[string]string // 条件配置,如: map["perip"] = "10"
|
||||
Rate string `json:"rate"` // 速率限制,如: "512k", "10r/s"
|
||||
Concurrent int `json:"concurrent"` // 并发连接数限制
|
||||
Zone map[string]string `json:"zone"` // 条件配置,如: map["perip"] = "10"
|
||||
}
|
||||
|
||||
// IncludeFile 包含文件配置
|
||||
type IncludeFile struct {
|
||||
Path string // 文件路径
|
||||
Comment []string // 注释说明
|
||||
Path string `json:"path"` // 文件路径
|
||||
Comment []string `json:"comment"` // 注释说明
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { useGettext } from 'vue3-gettext'
|
||||
import cert from '@/api/panel/cert'
|
||||
import home from '@/api/panel/home'
|
||||
import website from '@/api/panel/website'
|
||||
import ProxyBuilderModal from '@/views/website/ProxyBuilderModal.vue'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
let messageReactive: MessageReactive | null = null
|
||||
@@ -23,28 +22,32 @@ const { data: setting, send: fetchSetting } = useRequest(website.config(Number(i
|
||||
initialData: {
|
||||
id: 0,
|
||||
name: '',
|
||||
type: 'proxy',
|
||||
listens: [],
|
||||
domains: [],
|
||||
root: '',
|
||||
path: '',
|
||||
root: '',
|
||||
index: [],
|
||||
php: 0,
|
||||
open_basedir: false,
|
||||
https: false,
|
||||
ssl_certificate: '',
|
||||
ssl_certificate_key: '',
|
||||
ssl: false,
|
||||
ssl_cert: '',
|
||||
ssl_key: '',
|
||||
hsts: false,
|
||||
ocsp: false,
|
||||
http_redirect: false,
|
||||
ssl_protocols: [],
|
||||
ssl_ciphers: '',
|
||||
ssl_not_before: '',
|
||||
ssl_not_after: '',
|
||||
ssl_dns_names: [],
|
||||
ssl_issuer: '',
|
||||
ssl_ocsp_server: [],
|
||||
http_redirect: false,
|
||||
hsts: false,
|
||||
ocsp: false,
|
||||
access_log: '',
|
||||
error_log: '',
|
||||
php: 0,
|
||||
rewrite: '',
|
||||
raw: '',
|
||||
log: '',
|
||||
error_log: ''
|
||||
open_basedir: false,
|
||||
upstreams: {},
|
||||
proxies: []
|
||||
}
|
||||
})
|
||||
const { data: installedDbAndPhp } = useRequest(home.installedDbAndPhp, {
|
||||
@@ -67,7 +70,6 @@ const certs = ref<any>([])
|
||||
useRequest(cert.certs(1, 10000)).onSuccess(({ data }) => {
|
||||
certs.value = data.items
|
||||
})
|
||||
const proxyBuilderModal = ref(false)
|
||||
const { data: rewrites } = useRequest(website.rewrites, {
|
||||
initialData: {}
|
||||
})
|
||||
@@ -97,16 +99,14 @@ const handleSave = () => {
|
||||
if (setting.value.https && !setting.value.listens.some((item: any) => item.https)) {
|
||||
setting.value.listens.push({
|
||||
address: '443',
|
||||
https: true,
|
||||
quic: true
|
||||
args: ['ssl', 'quic']
|
||||
})
|
||||
}
|
||||
// 如果关闭了https,自动禁用所有https和quic
|
||||
if (!setting.value.https) {
|
||||
setting.value.listens = setting.value.listens.filter((item: any) => item.address !== '443') // 443直接删掉
|
||||
setting.value.listens.forEach((item: any) => {
|
||||
item.https = false
|
||||
item.quic = false
|
||||
item.args = []
|
||||
})
|
||||
}
|
||||
|
||||
@@ -164,10 +164,22 @@ const clearLog = async () => {
|
||||
const onCreateListen = () => {
|
||||
return {
|
||||
address: '',
|
||||
https: false,
|
||||
quic: false
|
||||
args: []
|
||||
}
|
||||
}
|
||||
|
||||
const toggleArg = (args: string[], arg: string, checked: boolean) => {
|
||||
const index = args.indexOf(arg)
|
||||
if (checked && index === -1) {
|
||||
args.push(arg)
|
||||
} else if (!checked && index !== -1) {
|
||||
args.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const hasArg = (args: string[], arg: string) => {
|
||||
return args.includes(arg)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -192,8 +204,22 @@ const onCreateListen = () => {
|
||||
<template #default="{ value }">
|
||||
<div w-full flex items-center>
|
||||
<n-input v-model:value="value.address" clearable />
|
||||
<n-checkbox v-model:checked="value.https" ml-20 mr-20 w-120> HTTPS </n-checkbox>
|
||||
<n-checkbox v-model:checked="value.quic" w-200> QUIC(HTTP3) </n-checkbox>
|
||||
<n-checkbox
|
||||
:checked="hasArg(value.args, 'ssl')"
|
||||
@update:checked="(checked) => toggleArg(value.args, 'ssl', checked)"
|
||||
ml-20
|
||||
mr-20
|
||||
w-120
|
||||
>
|
||||
HTTPS
|
||||
</n-checkbox>
|
||||
<n-checkbox
|
||||
:checked="hasArg(value.args, 'quic')"
|
||||
@update:checked="(checked) => toggleArg(value.args, 'quic', checked)"
|
||||
w-200
|
||||
>
|
||||
QUIC(HTTP3)
|
||||
</n-checkbox>
|
||||
</div>
|
||||
</template>
|
||||
</n-dynamic-input>
|
||||
@@ -220,7 +246,7 @@ const onCreateListen = () => {
|
||||
<n-form-item :label="$gettext('Default Document')">
|
||||
<n-dynamic-tags v-model:value="setting.index" />
|
||||
</n-form-item>
|
||||
<n-form-item :label="$gettext('PHP Version')">
|
||||
<n-form-item v-if="setting.type == 'php'" :label="$gettext('PHP Version')">
|
||||
<n-select
|
||||
v-model:value="setting.php"
|
||||
:default-value="0"
|
||||
@@ -230,7 +256,7 @@ const onCreateListen = () => {
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item>
|
||||
<n-form-item :label="$gettext('Anti-cross-site Attack (PHP)')">
|
||||
<n-form-item v-if="setting.type == 'php'" :label="$gettext('Anti-cross-site Attack')">
|
||||
<n-switch v-model:value="setting.open_basedir" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
@@ -238,16 +264,7 @@ const onCreateListen = () => {
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="https" tab="HTTPS">
|
||||
<n-flex vertical v-if="setting">
|
||||
<n-button
|
||||
:loading="isObtainCert"
|
||||
:disabled="isObtainCert"
|
||||
class="ml-16"
|
||||
type="success"
|
||||
@click="handleObtainCert"
|
||||
>
|
||||
{{ $gettext('One-click Certificate Issuance') }}
|
||||
</n-button>
|
||||
<n-card v-if="setting.https && setting.ssl_issuer != ''">
|
||||
<n-card v-if="setting.ssl && setting.ssl_issuer != ''">
|
||||
<n-descriptions :title="$gettext('Certificate Information')" :column="2">
|
||||
<n-descriptions-item>
|
||||
<template #label>{{ $gettext('Certificate Validity') }}</template>
|
||||
@@ -280,10 +297,10 @@ const onCreateListen = () => {
|
||||
<n-form>
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-form-item-gi :span="12" :label="$gettext('Main Switch')">
|
||||
<n-switch v-model:value="setting.https" />
|
||||
<n-switch v-model:value="setting.ssl" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi
|
||||
v-if="setting.https"
|
||||
v-if="setting.ssl"
|
||||
:span="12"
|
||||
:label="$gettext('Use Existing Certificate')"
|
||||
>
|
||||
@@ -295,7 +312,7 @@ const onCreateListen = () => {
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
<n-form inline v-if="setting.https">
|
||||
<n-form inline v-if="setting.ssl">
|
||||
<n-form-item label="HSTS">
|
||||
<n-switch v-model:value="setting.hsts" />
|
||||
</n-form-item>
|
||||
@@ -306,10 +323,10 @@ const onCreateListen = () => {
|
||||
<n-switch v-model:value="setting.ocsp" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<n-form v-if="setting.https">
|
||||
<n-form v-if="setting.ssl">
|
||||
<n-form-item :label="$gettext('Certificate')">
|
||||
<n-input
|
||||
v-model:value="setting.ssl_certificate"
|
||||
v-model:value="setting.ssl_cert"
|
||||
type="textarea"
|
||||
:placeholder="$gettext('Enter the content of the PEM certificate file')"
|
||||
:autosize="{ minRows: 10, maxRows: 15 }"
|
||||
@@ -317,7 +334,7 @@ const onCreateListen = () => {
|
||||
</n-form-item>
|
||||
<n-form-item :label="$gettext('Private Key')">
|
||||
<n-input
|
||||
v-model:value="setting.ssl_certificate_key"
|
||||
v-model:value="setting.ssl_key"
|
||||
type="textarea"
|
||||
:placeholder="$gettext('Enter the content of the KEY private key file')"
|
||||
:autosize="{ minRows: 10, maxRows: 15 }"
|
||||
@@ -327,11 +344,8 @@ const onCreateListen = () => {
|
||||
</n-flex>
|
||||
<n-skeleton v-else text :repeat="10" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="rewrite" :tab="$gettext('Rewrite')">
|
||||
<n-tab-pane v-if="setting.type == 'php'" name="rewrite" :tab="$gettext('Rewrite')">
|
||||
<n-flex vertical>
|
||||
<n-button type="success" @click="proxyBuilderModal = true">
|
||||
{{ $gettext('Generate Reverse Proxy Configuration') }}
|
||||
</n-button>
|
||||
<n-form label-placement="left" label-width="auto">
|
||||
<n-form-item :label="$gettext('Presets')">
|
||||
<n-select
|
||||
@@ -371,25 +385,6 @@ const onCreateListen = () => {
|
||||
)
|
||||
}}
|
||||
</n-alert>
|
||||
<n-popconfirm @positive-click="handleReset">
|
||||
<template #trigger>
|
||||
<n-button type="success">
|
||||
{{ $gettext('Reset Configuration') }}
|
||||
</n-button>
|
||||
</template>
|
||||
{{ $gettext('Are you sure you want to reset the configuration?') }}
|
||||
</n-popconfirm>
|
||||
<Editor
|
||||
v-if="setting"
|
||||
v-model:value="setting.raw"
|
||||
language="ini"
|
||||
theme="vs-dark"
|
||||
height="60vh"
|
||||
:options="{
|
||||
automaticLayout: true,
|
||||
smoothScrolling: true
|
||||
}"
|
||||
/>
|
||||
</n-flex>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="log" :tab="$gettext('Access Log')">
|
||||
@@ -397,7 +392,7 @@ const onCreateListen = () => {
|
||||
<n-flex flex items-center>
|
||||
<n-alert type="warning" w-full>
|
||||
{{ $gettext('All logs can be viewed by downloading the file') }}
|
||||
<n-tag>{{ setting.log }}</n-tag>
|
||||
<n-tag>{{ setting.access_log }}</n-tag>
|
||||
{{ $gettext('view') }}.
|
||||
</n-alert>
|
||||
<n-popconfirm @positive-click="clearLog">
|
||||
@@ -409,7 +404,7 @@ const onCreateListen = () => {
|
||||
{{ $gettext('Are you sure you want to clear?') }}
|
||||
</n-popconfirm>
|
||||
</n-flex>
|
||||
<realtime-log :path="setting.log" />
|
||||
<realtime-log :path="setting.access_log" />
|
||||
</n-flex>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="error_log" :tab="$gettext('Error Log')">
|
||||
@@ -428,6 +423,23 @@ const onCreateListen = () => {
|
||||
<n-button v-if="current !== 'log'" type="primary" @click="handleSave">
|
||||
{{ $gettext('Save') }}
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="current === 'https' && setting && setting.domains.length > 0"
|
||||
:loading="isObtainCert"
|
||||
:disabled="isObtainCert"
|
||||
class="ml-16"
|
||||
type="info"
|
||||
@click="handleObtainCert"
|
||||
>
|
||||
{{ $gettext('One-click Certificate Issuance') }}
|
||||
</n-button>
|
||||
<n-popconfirm v-if="current === 'config'" @positive-click="handleReset">
|
||||
<template #trigger>
|
||||
<n-button type="warning" ml-16>
|
||||
{{ $gettext('Reset Configuration') }}
|
||||
</n-button>
|
||||
</template>
|
||||
{{ $gettext('Are you sure you want to reset the configuration?') }}
|
||||
</n-popconfirm>
|
||||
</common-page>
|
||||
<ProxyBuilderModal v-model:show="proxyBuilderModal" v-model:config="setting.rewrite" />
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user