mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-10 18:05:48 +02:00
refactor(preference): show more settings
This commit is contained in:
parent
59947a35db
commit
a0c005f314
17 changed files with 400 additions and 213 deletions
|
@ -1,6 +1,7 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/api"
|
||||
"github.com/0xJacky/Nginx-UI/internal/cron"
|
||||
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
||||
|
@ -19,22 +20,52 @@ func GetServerName(c *gin.Context) {
|
|||
func GetSettings(c *gin.Context) {
|
||||
settings.NginxSettings.AccessLogPath = nginx.GetAccessLogPath()
|
||||
settings.NginxSettings.ErrorLogPath = nginx.GetErrorLogPath()
|
||||
settings.NginxSettings.ConfigDir = nginx.GetConfPath()
|
||||
settings.NginxSettings.PIDPath = nginx.GetPIDPath()
|
||||
|
||||
if settings.NginxSettings.ReloadCmd == "" {
|
||||
settings.NginxSettings.ReloadCmd = "nginx -s reload"
|
||||
}
|
||||
|
||||
if settings.NginxSettings.RestartCmd == "" {
|
||||
pidPath := nginx.GetPIDPath()
|
||||
daemon := nginx.GetSbinPath()
|
||||
if daemon == "" {
|
||||
settings.NginxSettings.RestartCmd =
|
||||
fmt.Sprintf("start-stop-daemon --stop --quiet --oknodo --retry=TERM/30/KILL/5"+
|
||||
" --pidfile %s && nginx", pidPath)
|
||||
return
|
||||
}
|
||||
|
||||
settings.NginxSettings.RestartCmd =
|
||||
fmt.Sprintf("start-stop-daemon --start --quiet --pidfile %s --exec %s", pidPath, daemon)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"app": cSettings.AppSettings,
|
||||
"server": cSettings.ServerSettings,
|
||||
"nginx": settings.NginxSettings,
|
||||
"openai": settings.OpenAISettings,
|
||||
"logrotate": settings.LogrotateSettings,
|
||||
"database": settings.DatabaseSettings,
|
||||
"auth": settings.AuthSettings,
|
||||
"casdoor": settings.CasdoorSettings,
|
||||
"cert": settings.CertSettings,
|
||||
"http": settings.HTTPSettings,
|
||||
"logrotate": settings.LogrotateSettings,
|
||||
"nginx": settings.NginxSettings,
|
||||
"node": settings.NodeSettings,
|
||||
"openai": settings.OpenAISettings,
|
||||
"terminal": settings.TerminalSettings,
|
||||
"webauthn": settings.WebAuthnSettings,
|
||||
})
|
||||
}
|
||||
|
||||
func SaveSettings(c *gin.Context) {
|
||||
var json struct {
|
||||
Server cSettings.Server `json:"server"`
|
||||
Nginx settings.Nginx `json:"nginx"`
|
||||
Auth settings.Auth `json:"auth"`
|
||||
Cert settings.Cert `json:"cert"`
|
||||
Http settings.HTTP `json:"http"`
|
||||
Node settings.Node `json:"node"`
|
||||
Openai settings.OpenAI `json:"openai"`
|
||||
Logrotate settings.Logrotate `json:"logrotate"`
|
||||
Auth settings.Auth `json:"auth"`
|
||||
}
|
||||
|
||||
if !api.BindAndValid(c, &json) {
|
||||
|
@ -46,11 +77,12 @@ func SaveSettings(c *gin.Context) {
|
|||
go cron.RestartLogrotate()
|
||||
}
|
||||
|
||||
cSettings.ProtectedFill(cSettings.ServerSettings, &json.Server)
|
||||
cSettings.ProtectedFill(settings.NginxSettings, &json.Nginx)
|
||||
cSettings.ProtectedFill(settings.AuthSettings, &json.Auth)
|
||||
cSettings.ProtectedFill(settings.CertSettings, &json.Cert)
|
||||
cSettings.ProtectedFill(settings.HTTPSettings, &json.Http)
|
||||
cSettings.ProtectedFill(settings.NodeSettings, &json.Node)
|
||||
cSettings.ProtectedFill(settings.OpenAISettings, &json.Openai)
|
||||
cSettings.ProtectedFill(settings.LogrotateSettings, &json.Logrotate)
|
||||
cSettings.ProtectedFill(settings.AuthSettings, &json.Auth)
|
||||
|
||||
err := settings.Save()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,16 +1,114 @@
|
|||
import http from '@/lib/http'
|
||||
|
||||
export interface AppSettings {
|
||||
page_size: number
|
||||
jwt_secret: string
|
||||
}
|
||||
|
||||
export interface ServerSettings {
|
||||
host: string
|
||||
port: number
|
||||
run_mode: 'debug' | 'release'
|
||||
}
|
||||
|
||||
export interface DatabaseSettings {
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface AuthSettings {
|
||||
ip_white_list: string[]
|
||||
ban_threshold_minutes: number
|
||||
max_attempts: number
|
||||
}
|
||||
|
||||
export interface CasdoorSettings {
|
||||
endpoint: string
|
||||
client_id: string
|
||||
client_secret: string
|
||||
certificate_path: string
|
||||
organization: string
|
||||
application: string
|
||||
redirect_uri: string
|
||||
}
|
||||
|
||||
export interface CertSettings {
|
||||
email: string
|
||||
ca_dir: string
|
||||
renewal_interval: number
|
||||
recursive_nameservers: string[]
|
||||
http_challenge_port: string
|
||||
}
|
||||
|
||||
export interface HTTPSettings {
|
||||
github_proxy: string
|
||||
insecure_skip_verify: boolean
|
||||
}
|
||||
|
||||
export interface LogrotateSettings {
|
||||
enabled: boolean
|
||||
cmd: string
|
||||
interval: number
|
||||
}
|
||||
|
||||
export interface NginxSettings {
|
||||
access_log_path: string
|
||||
error_log_path: string
|
||||
config_dir: string
|
||||
log_dir_white_list: string[]
|
||||
pid_path: string
|
||||
reload_cmd: string
|
||||
restart_cmd: string
|
||||
}
|
||||
|
||||
export interface NodeSettings {
|
||||
name: string
|
||||
secret: string
|
||||
}
|
||||
|
||||
export interface OpenaiSettings {
|
||||
model: string
|
||||
base_url: string
|
||||
proxy: string
|
||||
token: string
|
||||
}
|
||||
|
||||
export interface TerminalSettings {
|
||||
start_cmd: string
|
||||
}
|
||||
|
||||
export interface WebauthnSettings {
|
||||
rp_display_name: string
|
||||
rpid: string
|
||||
rp_origins: string[]
|
||||
}
|
||||
|
||||
export interface BannedIP {
|
||||
ip: string
|
||||
attempts: number
|
||||
expired_at: string
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
app: AppSettings
|
||||
server: ServerSettings
|
||||
database: DatabaseSettings
|
||||
auth: AuthSettings
|
||||
casdoor: CasdoorSettings
|
||||
cert: CertSettings
|
||||
http: HTTPSettings
|
||||
logrotate: LogrotateSettings
|
||||
nginx: NginxSettings
|
||||
node: NodeSettings
|
||||
openai: OpenaiSettings
|
||||
terminal: TerminalSettings
|
||||
webauthn: WebauthnSettings
|
||||
}
|
||||
|
||||
const settings = {
|
||||
get<T>(): Promise<T> {
|
||||
get(): Promise<Settings> {
|
||||
return http.get('/settings')
|
||||
},
|
||||
save<T>(data: T) {
|
||||
save(data: Settings) {
|
||||
return http.post('/settings', data)
|
||||
},
|
||||
get_server_name(): Promise<{ name: string }> {
|
||||
|
|
|
@ -3,10 +3,9 @@ import { message } from 'ant-design-vue'
|
|||
import type { Ref } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import PasskeyRegistration from './components/Passkey.vue'
|
||||
import type { BannedIP } from '@/api/settings'
|
||||
import type { BannedIP, Settings } from '@/api/settings'
|
||||
import setting from '@/api/settings'
|
||||
import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import TOTP from '@/views/preference/components/TOTP.vue'
|
||||
|
||||
const data: Settings = inject('data') as Settings
|
||||
|
@ -62,13 +61,41 @@ function removeBannedIP(ip: string) {
|
|||
<h2>
|
||||
{{ $gettext('Authentication Settings') }}
|
||||
</h2>
|
||||
<AAlert
|
||||
<div
|
||||
v-if="data.webauthn.rpid
|
||||
&& data.webauthn.rp_display_name
|
||||
&& data.webauthn.rp_origins?.length > 0"
|
||||
class="mb-4"
|
||||
:message="$gettext('Tips')"
|
||||
:description="$gettext('If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes,'
|
||||
+ ' the ip will be banned for a period of time.')"
|
||||
type="info"
|
||||
/>
|
||||
>
|
||||
<h3>
|
||||
{{ $gettext('Webauthn') }}
|
||||
</h3>
|
||||
<div class="mb-4">
|
||||
<h4>
|
||||
{{ $gettext('RPID') }}
|
||||
</h4>
|
||||
<p>{{ data.webauthn.rpid }}</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<h4>
|
||||
{{ $gettext('RP Display Name') }}
|
||||
</h4>
|
||||
<p>{{ data.webauthn.rp_display_name }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>
|
||||
{{ $gettext('RP Origins') }}
|
||||
</h4>
|
||||
<div
|
||||
v-for="origin in data.webauthn.rp_origins"
|
||||
:key="origin"
|
||||
class="mb-4"
|
||||
>
|
||||
{{ origin }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3>{{ $gettext('Throttle') }}</h3>
|
||||
<AForm
|
||||
layout="horizontal"
|
||||
style="width:90%;max-width: 500px"
|
||||
|
@ -86,7 +113,14 @@ function removeBannedIP(ip: string) {
|
|||
/>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
<h3>
|
||||
<AAlert
|
||||
class="mb-6"
|
||||
:message="$gettext('Tips')"
|
||||
:description="$gettext('If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes,'
|
||||
+ ' the ip will be banned for a period of time.')"
|
||||
type="info"
|
||||
/>
|
||||
<h3 class="mb-4">
|
||||
{{ $gettext('Banned IPs') }}
|
||||
</h3>
|
||||
<div class="mb-6">
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import Draggable from 'vuedraggable'
|
||||
import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import type { Settings } from '@/api/settings'
|
||||
import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
|
||||
|
||||
const data: Settings = inject('data') as Settings
|
||||
|
@ -11,116 +9,43 @@ const errors: Record<string, Record<string, string>> = inject('errors') as Recor
|
|||
<template>
|
||||
<AForm layout="vertical">
|
||||
<AFormItem :label="$gettext('HTTP Host')">
|
||||
<p>{{ data.server.http_host }}</p>
|
||||
<p>{{ data.server.host }}</p>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('HTTP Port')">
|
||||
<p>{{ data.server.http_port }}</p>
|
||||
<p>{{ data.server.port }}</p>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Run Mode')">
|
||||
<p>{{ data.server.run_mode }}</p>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Jwt Secret')">
|
||||
<SensitiveString :value="data.server.jwt_secret" />
|
||||
<SensitiveString :value="data.app.jwt_secret" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Node Secret')">
|
||||
<SensitiveString :value="data.server.node_secret" />
|
||||
<SensitiveString :value="data.node.secret" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Terminal Start Command')">
|
||||
<p>{{ data.server.start_cmd }}</p>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('HTTP Challenge Port')">
|
||||
<AInputNumber v-model:value="data.server.http_challenge_port" />
|
||||
<p>{{ data.terminal.start_cmd }}</p>
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:label="$gettext('Github Proxy')"
|
||||
:validate-status="errors?.server?.github_proxy ? 'error' : ''"
|
||||
:help="errors?.server?.github_proxy === 'url'
|
||||
:validate-status="errors?.http?.github_proxy ? 'error' : ''"
|
||||
:help="errors?.http?.github_proxy === 'url'
|
||||
? $gettext('The url is invalid')
|
||||
: ''"
|
||||
>
|
||||
<AInput
|
||||
v-model:value="data.server.github_proxy"
|
||||
v-model:value="data.http.github_proxy"
|
||||
:placeholder="$gettext('For Chinese user: https://mirror.ghproxy.com/')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:label="$gettext('CADir')"
|
||||
:validate-status="errors?.server?.ca_dir ? 'error' : ''"
|
||||
:help="errors?.server?.ca_dir === 'url'
|
||||
? $gettext('The url is invalid')
|
||||
: ''"
|
||||
:label="$gettext('Node name')"
|
||||
:validate-status="errors?.node?.name ? 'error' : ''"
|
||||
:help="errors?.node?.name.includes('safety_text')
|
||||
? $gettext('The node name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
|
||||
: $gettext('Customize the name of local node to be displayed in the environment indicator.')"
|
||||
>
|
||||
<AInput v-model:value="data.server.ca_dir" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Certificate Renewal Interval')">
|
||||
<AInputNumber
|
||||
v-model:value="data.server.cert_renewal_interval"
|
||||
:min="7"
|
||||
:max="21"
|
||||
:addon-after="$gettext('Days')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:help="$gettext('Set the recursive nameservers to override the systems nameservers '
|
||||
+ 'for the step of DNS challenge.')"
|
||||
>
|
||||
<template #label>
|
||||
{{ $gettext('Recursive Nameservers') }}
|
||||
<AButton
|
||||
type="link"
|
||||
@click="data.server.recursive_nameservers.push('')"
|
||||
>
|
||||
{{ $gettext('Add') }}
|
||||
</AButton>
|
||||
</template>
|
||||
|
||||
<Draggable
|
||||
:list="data.server.recursive_nameservers"
|
||||
item-key="name"
|
||||
class="list-group"
|
||||
ghost-class="ghost"
|
||||
handle=".anticon-holder"
|
||||
>
|
||||
<template #item="{ index }">
|
||||
<ARow>
|
||||
<ACol :span="2">
|
||||
<HolderOutlined class="p-2" />
|
||||
</ACol>
|
||||
<ACol :span="20">
|
||||
<AInput
|
||||
v-model:value="data.server.recursive_nameservers[index]"
|
||||
:status="errors?.server?.recursive_nameservers?.[index] ? 'error' : undefined"
|
||||
placeholder="8.8.8.8:53"
|
||||
class="mb-4"
|
||||
/>
|
||||
</ACol>
|
||||
<ACol :span="2">
|
||||
<APopconfirm
|
||||
:title="$gettext('Are you sure you want to remove this item?')"
|
||||
:ok-text="$gettext('Yes')"
|
||||
:cancel-text="$gettext('No')"
|
||||
@confirm="data.server.recursive_nameservers.splice(index, 1)"
|
||||
>
|
||||
<AButton
|
||||
type="link"
|
||||
danger
|
||||
>
|
||||
<DeleteOutlined />
|
||||
</AButton>
|
||||
</APopconfirm>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</template>
|
||||
</Draggable>
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:label="$gettext('Server Name')"
|
||||
:validate-status="errors?.server?.name ? 'error' : ''"
|
||||
:help="errors?.server?.name.includes('safety_text')
|
||||
? $gettext('The server name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
|
||||
: $gettext('Customize the name of local server to be displayed in the environment indicator.')"
|
||||
>
|
||||
<AInput v-model:value="data.server.name" />
|
||||
<AInput v-model:value="data.node.name" />
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</template>
|
||||
|
|
90
app/src/views/preference/CertSettings.vue
Normal file
90
app/src/views/preference/CertSettings.vue
Normal file
|
@ -0,0 +1,90 @@
|
|||
<script setup lang="ts">
|
||||
import Draggable from 'vuedraggable'
|
||||
import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
|
||||
import type { Settings } from '@/api/settings'
|
||||
|
||||
const data: Settings = inject('data') as Settings
|
||||
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AForm layout="vertical">
|
||||
<AFormItem :label="$gettext('HTTP Challenge Port')">
|
||||
<AInputNumber v-model:value="data.cert.http_challenge_port" />
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:label="$gettext('CADir')"
|
||||
:validate-status="errors?.cert?.ca_dir ? 'error' : ''"
|
||||
:help="errors?.cert?.ca_dir === 'url'
|
||||
? $gettext('The url is invalid')
|
||||
: ''"
|
||||
>
|
||||
<AInput v-model:value="data.cert.ca_dir" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Certificate Renewal Interval')">
|
||||
<AInputNumber
|
||||
v-model:value="data.cert.renewal_interval"
|
||||
:min="7"
|
||||
:max="21"
|
||||
:addon-after="$gettext('Days')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:help="$gettext('Set the recursive nameservers to override the systems nameservers '
|
||||
+ 'for the step of DNS challenge.')"
|
||||
>
|
||||
<template #label>
|
||||
{{ $gettext('Recursive Nameservers') }}
|
||||
<AButton
|
||||
type="link"
|
||||
@click="data.cert.recursive_nameservers.push('')"
|
||||
>
|
||||
{{ $gettext('Add') }}
|
||||
</AButton>
|
||||
</template>
|
||||
|
||||
<Draggable
|
||||
:list="data.cert.recursive_nameservers"
|
||||
item-key="name"
|
||||
class="list-group"
|
||||
ghost-class="ghost"
|
||||
handle=".anticon-holder"
|
||||
>
|
||||
<template #item="{ index }">
|
||||
<ARow>
|
||||
<ACol :span="2">
|
||||
<HolderOutlined class="p-2" />
|
||||
</ACol>
|
||||
<ACol :span="20">
|
||||
<AInput
|
||||
v-model:value="data.cert.recursive_nameservers[index]"
|
||||
:status="errors?.cert?.recursive_nameservers?.[index] ? 'error' : undefined"
|
||||
placeholder="8.8.8.8:53"
|
||||
class="mb-4"
|
||||
/>
|
||||
</ACol>
|
||||
<ACol :span="2">
|
||||
<APopconfirm
|
||||
:title="$gettext('Are you sure you want to remove this item?')"
|
||||
:ok-text="$gettext('Yes')"
|
||||
:cancel-text="$gettext('No')"
|
||||
@confirm="data.cert.recursive_nameservers.splice(index, 1)"
|
||||
>
|
||||
<AButton
|
||||
type="link"
|
||||
danger
|
||||
>
|
||||
<DeleteOutlined />
|
||||
</AButton>
|
||||
</APopconfirm>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</template>
|
||||
</Draggable>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import type { Settings } from '@/api/settings'
|
||||
|
||||
const data: Settings = inject('data')!
|
||||
</script>
|
||||
|
|
|
@ -1,30 +1,38 @@
|
|||
<script setup lang="ts">
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import type { Settings } from '@/api/settings'
|
||||
|
||||
const data: Settings = inject('data')!
|
||||
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AForm layout="vertical">
|
||||
<AFormItem
|
||||
:label="$gettext('Nginx Access Log Path')"
|
||||
:validate-status="errors?.nginx?.access_log_path ? 'error' : ''"
|
||||
:help="errors?.nginx?.access_log_path === 'file'
|
||||
? $gettext('File not found')
|
||||
: ''"
|
||||
>
|
||||
<AFormItem :label="$gettext('Nginx Access Log Path')">
|
||||
{{ data.nginx.access_log_path }}
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
:label="$gettext('Nginx Error Log Path')"
|
||||
:validate-status="errors?.nginx?.error_log_path ? 'error' : ''"
|
||||
:help="errors?.nginx?.error_log_path === 'file'
|
||||
? $gettext('File not found')
|
||||
: ''"
|
||||
>
|
||||
<AFormItem :label="$gettext('Nginx Error Log Path')">
|
||||
{{ data.nginx.error_log_path }}
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Nginx Configurations Directory')">
|
||||
{{ data.nginx.config_dir }}
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Nginx Log Directory Whitelist')">
|
||||
<div
|
||||
v-for="dir in data.nginx.log_dir_white_list"
|
||||
:key="dir"
|
||||
class="mb-2"
|
||||
>
|
||||
{{ dir }}
|
||||
</div>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Nginx PID Path')">
|
||||
{{ data.nginx.pid_path }}
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Nginx Reload Command')">
|
||||
{{ data.nginx.reload_cmd }}
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Nginx Restart Command')">
|
||||
{{ data.nginx.restart_cmd }}
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import type { Settings } from '@/api/settings'
|
||||
|
||||
const data: Settings = inject('data')!
|
||||
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
|
||||
|
|
|
@ -7,55 +7,86 @@ import settings from '@/api/settings'
|
|||
import BasicSettings from '@/views/preference/BasicSettings.vue'
|
||||
import OpenAISettings from '@/views/preference/OpenAISettings.vue'
|
||||
import NginxSettings from '@/views/preference/NginxSettings.vue'
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import type { Settings } from '@/api/settings'
|
||||
import LogrotateSettings from '@/views/preference/LogrotateSettings.vue'
|
||||
import { useSettingsStore } from '@/pinia'
|
||||
import AuthSettings from '@/views/preference/AuthSettings.vue'
|
||||
import use2FAModal from '@/components/TwoFA/use2FAModal'
|
||||
import CertSettings from '@/views/preference/CertSettings.vue'
|
||||
|
||||
const data = ref<Settings>({
|
||||
server: {
|
||||
http_host: '0.0.0.0',
|
||||
http_port: '9000',
|
||||
run_mode: 'debug',
|
||||
app: {
|
||||
page_size: 10,
|
||||
jwt_secret: '',
|
||||
start_cmd: '',
|
||||
email: '',
|
||||
http_challenge_port: '9180',
|
||||
github_proxy: '',
|
||||
ca_dir: '',
|
||||
node_secret: '',
|
||||
cert_renewal_interval: 7,
|
||||
recursive_nameservers: [],
|
||||
},
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 9000,
|
||||
run_mode: 'debug',
|
||||
},
|
||||
database: {
|
||||
name: '',
|
||||
},
|
||||
auth: {
|
||||
ip_white_list: [],
|
||||
ban_threshold_minutes: 10,
|
||||
max_attempts: 10,
|
||||
},
|
||||
casdoor: {
|
||||
endpoint: '',
|
||||
client_id: '',
|
||||
client_secret: '',
|
||||
certificate_path: '',
|
||||
organization: '',
|
||||
application: '',
|
||||
redirect_uri: '',
|
||||
},
|
||||
cert: {
|
||||
email: '',
|
||||
ca_dir: '',
|
||||
renewal_interval: 7,
|
||||
recursive_nameservers: [],
|
||||
http_challenge_port: '9180',
|
||||
},
|
||||
http: {
|
||||
github_proxy: '',
|
||||
insecure_skip_verify: false,
|
||||
},
|
||||
logrotate: {
|
||||
enabled: false,
|
||||
cmd: '',
|
||||
interval: 1440,
|
||||
},
|
||||
nginx: {
|
||||
access_log_path: '',
|
||||
error_log_path: '',
|
||||
config_dir: '',
|
||||
log_dir_white_list: [],
|
||||
pid_path: '',
|
||||
reload_cmd: '',
|
||||
restart_cmd: '',
|
||||
},
|
||||
node: {
|
||||
name: '',
|
||||
secret: '',
|
||||
},
|
||||
openai: {
|
||||
model: '',
|
||||
base_url: '',
|
||||
proxy: '',
|
||||
token: '',
|
||||
},
|
||||
logrotate: {
|
||||
enabled: false,
|
||||
cmd: '',
|
||||
interval: 1440,
|
||||
terminal: {
|
||||
start_cmd: '',
|
||||
},
|
||||
auth: {
|
||||
ip_white_list: [],
|
||||
ban_threshold_minutes: 10,
|
||||
max_attempts: 10,
|
||||
webauthn: {
|
||||
rp_display_name: '',
|
||||
rpid: '',
|
||||
rp_origins: [],
|
||||
},
|
||||
})
|
||||
|
||||
settings.get<Settings>().then(r => {
|
||||
settings.get().then(r => {
|
||||
data.value = r
|
||||
})
|
||||
|
||||
|
@ -66,7 +97,7 @@ const refAuthSettings = ref()
|
|||
|
||||
async function save() {
|
||||
// fix type
|
||||
data.value.server.http_challenge_port = data.value.server.http_challenge_port.toString()
|
||||
data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
|
||||
|
||||
const otpModal = use2FAModal()
|
||||
|
||||
|
@ -123,6 +154,12 @@ onMounted(() => {
|
|||
>
|
||||
<AuthSettings ref="refAuthSettings" />
|
||||
</ATabPane>
|
||||
<ATabPane
|
||||
key="cert"
|
||||
:tab="$gettext('Cert')"
|
||||
>
|
||||
<CertSettings />
|
||||
</ATabPane>
|
||||
<ATabPane
|
||||
key="nginx"
|
||||
:tab="$gettext('Nginx')"
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
export interface Settings {
|
||||
server: {
|
||||
http_host: string
|
||||
http_port: string
|
||||
run_mode: string
|
||||
jwt_secret: string
|
||||
node_secret: string
|
||||
start_cmd: string
|
||||
http_challenge_port: string
|
||||
github_proxy: string
|
||||
email: string
|
||||
ca_dir: string
|
||||
cert_renewal_interval: number
|
||||
recursive_nameservers: string[]
|
||||
name: string
|
||||
}
|
||||
nginx: {
|
||||
access_log_path: string
|
||||
error_log_path: string
|
||||
config_dir: string
|
||||
pid_path: string
|
||||
reload_cmd: string
|
||||
restart_cmd: string
|
||||
}
|
||||
openai: {
|
||||
model: string
|
||||
base_url: string
|
||||
proxy: string
|
||||
token: string
|
||||
}
|
||||
logrotate: {
|
||||
enabled: boolean
|
||||
cmd: string
|
||||
interval: number
|
||||
}
|
||||
auth: {
|
||||
ip_white_list: string[]
|
||||
ban_threshold_minutes: number
|
||||
max_attempts: number
|
||||
}
|
||||
}
|
|
@ -5,12 +5,16 @@ services:
|
|||
restart: always
|
||||
networks:
|
||||
- nginx-ui-network
|
||||
entrypoint:
|
||||
- NGINX_UI_NODE_DEMO=true
|
||||
ports:
|
||||
- "9003:80"
|
||||
|
||||
nginx-demo-2:
|
||||
image: uozi/nginx-ui-demo:latest
|
||||
restart: always
|
||||
entrypoint:
|
||||
- NGINX_UI_NODE_DEMO=true
|
||||
networks:
|
||||
- nginx-ui-network
|
||||
networks:
|
||||
|
|
|
@ -2,8 +2,8 @@ package nginx
|
|||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/internal/helper"
|
||||
"github.com/uozi-tech/cosy/logger"
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/uozi-tech/cosy/logger"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
|
|
@ -5,7 +5,7 @@ import "github.com/go-acme/lego/v4/lego"
|
|||
type Cert struct {
|
||||
Email string `json:"email" protected:"true"`
|
||||
CADir string `json:"ca_dir" binding:"omitempty,url"`
|
||||
RenewalInterval int `json:"cert_renewal_interval" binding:"min=7,max=21"`
|
||||
RenewalInterval int `json:"renewal_interval" binding:"min=7,max=21"`
|
||||
RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
|
||||
HTTPChallengePort string `json:"http_challenge_port"`
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package settings
|
|||
import "github.com/uozi-tech/cosy/settings"
|
||||
|
||||
type Cluster struct {
|
||||
Node []string `ini:",,allowshadow"`
|
||||
Node []string `json:"node" ini:",,allowshadow"`
|
||||
}
|
||||
|
||||
var ClusterSettings = &Cluster{
|
||||
|
|
|
@ -3,7 +3,7 @@ package settings
|
|||
import "crypto/md5"
|
||||
|
||||
type Crypto struct {
|
||||
Secret string
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
var CryptoSettings = &Crypto{}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package settings
|
||||
|
||||
type Database struct {
|
||||
Name string
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
var DatabaseSettings = &Database{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package settings
|
||||
|
||||
type WebAuthn struct {
|
||||
RPDisplayName string
|
||||
RPID string
|
||||
RPOrigins []string
|
||||
RPDisplayName string `json:"rp_display_name"`
|
||||
RPID string `json:"rpid"`
|
||||
RPOrigins []string `json:"rp_origins"`
|
||||
}
|
||||
|
||||
var WebAuthnSettings = &WebAuthn{}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue