diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f8c59c5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 nezhahq + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/api/settings.ts b/src/api/settings.ts index 61156bb..18d0a66 100644 --- a/src/api/settings.ts +++ b/src/api/settings.ts @@ -1,10 +1,10 @@ -import { ModelSettingForm, ModelConfig } from "@/types" +import { ModelSettingForm, ModelSettingResponse } from "@/types" import { fetcher, FetcherMethod } from "./api" export const updateSettings = async (data: ModelSettingForm): Promise => { return fetcher(FetcherMethod.PATCH, `/api/v1/setting`, data); } -export const getSettings = async (): Promise => { - return fetcher(FetcherMethod.GET, '/api/v1/setting', null); +export const getSettings = async (): Promise => { + return fetcher(FetcherMethod.GET, '/api/v1/setting', null); } diff --git a/src/components/header.tsx b/src/components/header.tsx index 32c54ab..5a65170 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -13,7 +13,7 @@ import { NzNavigationMenuLink } from "./xui/navigation-menu"; import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger } from "./ui/dropdown-menu"; import { LogOut, Settings, User2 } from "lucide-react"; import { useAuth } from "@/hooks/useAuth"; -import { Link, useLocation } from "react-router-dom"; +import { Link, useLocation, useNavigate } from "react-router-dom"; import { useMediaQuery } from "@/hooks/useMediaQuery"; import { Drawer, @@ -53,6 +53,8 @@ export default function Header() { const [open, setOpen] = useState(false) const [dropdownOpen, setDropdownOpen] = useState(false); + const navigate = useNavigate(); + return ( isDesktop ? (
@@ -121,17 +123,27 @@ export default function Header() { {profile.username} - { setDropdownOpen(false) }}> - + { + setDropdownOpen(false) + navigate("/dashboard/profile") + }} + className="cursor-pointer" + > +
{t('Profile')} - +
- { setDropdownOpen(false) }}> - + { + setDropdownOpen(false) + navigate("/dashboard/settings") + }} + className="cursor-pointer" + > +
{t('Settings')} - +
@@ -199,19 +211,27 @@ export default function Header() { {profile.username} - { setDropdownOpen(false) }}> - + { + setDropdownOpen(false) + navigate("/dashboard/profile") + }} + className="cursor-pointer" + > +
{t('Profile')} - ⇧⌘P - +
- { setDropdownOpen(false) }}> - + { + setDropdownOpen(false) + navigate("/dashboard/settings") + }} + className="cursor-pointer" + > +
{t('Settings')} - ⇧⌘S - +
diff --git a/src/components/install-commands.tsx b/src/components/install-commands.tsx index 59fc8d3..ea5f57c 100644 --- a/src/components/install-commands.tsx +++ b/src/components/install-commands.tsx @@ -7,7 +7,7 @@ import { import { Button, ButtonProps } from "@/components/ui/button" import { forwardRef, useState } from "react" import useSettings from "@/hooks/useSetting" -import { ModelConfig } from "@/types" +import { ModelSettingResponse } from "@/types" import { Check, Clipboard } from "lucide-react" import { toast } from "sonner" import { copyToClipboard } from "@/lib/utils" @@ -62,7 +62,7 @@ export const InstallCommandsMenu = forwardRef((p ); }) -const generateCommand = (type: number, { agent_secret_key, install_host, tls }: ModelConfig) => { +const generateCommand = (type: number, { agent_secret_key, install_host, tls }: ModelSettingResponse) => { if (!install_host) throw new Error(i18next.t("Results.InstallHostRequired")); @@ -72,7 +72,7 @@ const generateCommand = (type: number, { agent_secret_key, install_host, tls }: switch (type) { case OSTypes.Linux: case OSTypes.macOS: { - return `curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh -o nezha.sh && chmod +x nezha.sh && env ${env} ./nezha.sh` + return `curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh -o agent.sh && chmod +x agent.sh && env ${env} ./agent.sh` } case OSTypes.Windows: { return `${env} [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 -bor [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12;set-ExecutionPolicy RemoteSigned;Invoke-WebRequest https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.ps1 -OutFile C:\install.ps1;powershell.exe C:\install.ps1` diff --git a/src/hooks/useSetting.tsx b/src/hooks/useSetting.tsx index 657b195..b563b2f 100644 --- a/src/hooks/useSetting.tsx +++ b/src/hooks/useSetting.tsx @@ -1,9 +1,9 @@ import { swrFetcher } from "@/api/api"; -import { ModelConfig } from "@/types"; +import { ModelSettingResponse } from "@/types"; import useSWR from "swr"; export default function useSetting() { - const { data } = useSWR( + const { data } = useSWR( "/api/v1/setting", swrFetcher ); diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 9ecddf2..c8b866b 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -127,6 +127,7 @@ "WAF": "Web application firewall", "SiteName": "Site name", "DashboardOriginalHost": "Agent docking address [domain name/IP:port]", + "ConfigTLS": "Use TLS to connect Agent", "LoginFailed": "Login failed", "BruteForceAttackingToken": "Brute Force Attacking Token", "BruteForceAttackingAgentSecret": "Brute Force Attacking Agent Secret", diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json index ab9bf41..b8e794a 100644 --- a/src/locales/it/translation.json +++ b/src/locales/it/translation.json @@ -140,6 +140,7 @@ "CustomCodes": "Codice personalizzato (stili e script)", "CustomCodesDashboard": "Codice personalizzato per dashboard", "DashboardOriginalHost": "Indirizzo di ancoraggio dell'agente [nome dominio/IP:porta]", + "ConfigTLS": "Usa TLS per connettere Agent", "CustomPublicDNSNameserversforDDNS": "Server dei nomi DNS pubblici personalizzati per DDNS", "RealIPHeader": "Intestazione della richiesta IP reale", "UseDirectConnectingIP": "Utilizzare l'IP di connessione diretta", diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index ea2b575..85264ac 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -140,6 +140,7 @@ "CustomCodes": "自定义代码(样式和脚本)", "CustomCodesDashboard": "仪表板的自定义代码", "DashboardOriginalHost": "Agent对接地址【域名/IP:端口】", + "ConfigTLS": "Agent 使用 TLS 连接", "CustomPublicDNSNameserversforDDNS": "DDNS 的自定义公共 DNS 名称服务器", "RealIPHeader": "真实IP请求头", "UseDirectConnectingIP": "使用直连 IP", diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json index 34fcc7d..7bd92e4 100644 --- a/src/locales/zh-TW/translation.json +++ b/src/locales/zh-TW/translation.json @@ -140,6 +140,7 @@ "CustomCodes": "自訂程式碼(樣式和腳本)", "CustomCodesDashboard": "儀表板的自訂程式碼", "DashboardOriginalHost": "Agent對接位址【網域名稱/IP:連接埠】", + "ConfigTLS": "Agent 使用 TLS 連線", "CustomPublicDNSNameserversforDDNS": "DDNS 的自訂公共 DNS 名稱伺服器", "RealIPHeader": "真實IP請求頭", "UseDirectConnectingIP": "使用直連 IP", diff --git a/src/routes/alert-rule.tsx b/src/routes/alert-rule.tsx index 440e238..f6ccd94 100644 --- a/src/routes/alert-rule.tsx +++ b/src/routes/alert-rule.tsx @@ -34,7 +34,7 @@ export default function AlertRulePage() { toast(t("Error"), { description: t("Results.ErrorFetchingResource", { error: error.message }), }); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [error]); const columns: ColumnDef[] = [ @@ -44,7 +44,7 @@ export default function AlertRulePage() { table.toggleAllPageRowsSelected(!!value)} aria-label="Select all" @@ -86,8 +86,10 @@ export default function AlertRulePage() { }, { header: t("Rules"), - accessorKey: "rules", - accessorFn: (row) => JSON.stringify(row.rules), + cell: ({ row }) => { + const s = row.original; + return
{JSON.stringify(s.rules)}
; + }, }, { header: t("TasksToTriggerOnAlert"), diff --git a/src/routes/root.tsx b/src/routes/root.tsx index 9d442c1..b27195e 100644 --- a/src/routes/root.tsx +++ b/src/routes/root.tsx @@ -1,4 +1,5 @@ import { Outlet } from "react-router-dom"; +import { useEffect } from "react"; import { Card } from "@/components/ui/card"; import { ThemeProvider } from "@/components/theme-provider"; @@ -6,9 +7,16 @@ import Header from "@/components/header"; import { Toaster } from "@/components/ui/sonner"; import { useTranslation } from "react-i18next"; +import useSetting from "@/hooks/useSetting"; export default function Root() { const { t } = useTranslation(); + const settings = useSetting(); + + useEffect(() => { + document.title = settings?.site_name || "哪吒监控 Nezha Monitoring"; + }, [settings]); + return ( @@ -17,7 +25,7 @@ export default function Root() {
- © 2019-2024 {t('nezha')} + © 2019-2024 {t('nezha')} {settings?.version}
diff --git a/src/routes/settings.tsx b/src/routes/settings.tsx index 4855f38..7471026 100644 --- a/src/routes/settings.tsx +++ b/src/routes/settings.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; import { toast } from "sonner"; -import { ModelConfig, settingCoverageTypes, nezhaLang } from "@/types"; +import { ModelSettingResponse, settingCoverageTypes, nezhaLang } from "@/types"; import { SettingsTab } from "@/components/settings-tab"; import { z } from "zod"; import { asOptionalField } from "@/lib/utils"; @@ -43,13 +43,14 @@ const settingFormSchema = z.object({ custom_code_dashboard: asOptionalField(z.string()), real_ip_header: asOptionalField(z.string()), + tls: asOptionalField(z.boolean()), enable_ip_change_notification: asOptionalField(z.boolean()), enable_plain_ip_in_notification: asOptionalField(z.boolean()), }); export default function SettingsPage() { const { t, i18n } = useTranslation(); - const [config, setConfig] = useState(); + const [config, setConfig] = useState(); const [error, setError] = useState(); useEffect(() => { @@ -196,6 +197,23 @@ export default function SettingsPage() { )} /> + ( + + +
+ + +
+
+ +
+ )} + /> )} /> + ( + + {t("NotifierGroupID")} + + + + + + )} + /> bool(值为true代表当前ServerID在特定服务器列表内) */ - ignored_ip_notification_server_ids?: Record; - install_host?: string; - ip_change_notification_group_id?: number; - jwt_secret_key?: string; - /** 系统语言,默认 zh_CN */ - language?: string; - listen_port?: number; - /** 时区,默认为 Asia/Shanghai */ - location?: string; - /** 真实IP */ - real_ip_header?: string; - site_name?: string; - tls?: boolean; + trigger_mode: number; } export interface ModelCreateFMResponse { - session_id?: string; + session_id: string; } export interface ModelCreateTerminalResponse { - server_id?: number; - server_name?: string; - session_id?: string; + server_id: number; + server_name: string; + session_id: string; } export interface ModelCron { - command?: string; + command: string; /** 计划任务覆盖范围 (0:仅覆盖特定服务器 1:仅忽略特定服务器 2:由触发该计划任务的服务器执行) */ - cover?: number; - created_at?: string; - cron_job_id?: number; - id?: number; + cover: number; + created_at: string; + cron_job_id: number; + id: number; /** 最后一次执行时间 */ - last_executed_at?: string; + last_executed_at: string; /** 最后一次执行结果 */ - last_result?: boolean; - name?: string; + last_result: boolean; + name: string; /** 指定通知方式的分组 */ - notification_group_id?: number; + notification_group_id: number; /** 推送成功的通知 */ - push_successful?: boolean; + push_successful: boolean; /** 分钟 小时 天 月 星期 */ - scheduler?: string; - servers?: number[]; + scheduler: string; + servers: number[]; /** 0:计划任务 1:触发任务 */ - task_type?: number; - updated_at?: string; + task_type: number; + updated_at: string; } export interface ModelCronForm { command?: string; /** @default 0 */ - cover?: number; + cover: number; /** @minLength 1 */ - name?: string; - notification_group_id?: number; + name: string; + notification_group_id: number; push_successful?: boolean; - scheduler?: string; - servers?: number[]; + scheduler: string; + servers: number[]; /** * 0:计划任务 1:触发任务 * @default 0 */ - task_type?: number; + task_type: number; } export interface ModelCycleTransferStats { - from?: string; - max?: number; - min?: number; - name?: string; - next_update?: Record; - server_name?: Record; - to?: string; - transfer?: Record; + from: string; + max: number; + min: number; + name: string; + next_update: Record; + server_name: Record; + to: string; + transfer: Record; } export interface ModelDDNSForm { access_id?: string; access_secret?: string; - domains?: string[]; + domains: string[]; enable_ipv4?: boolean; enable_ipv6?: boolean; /** @default 3 */ - max_retries?: number; + max_retries: number; /** @minLength 1 */ - name?: string; - provider?: string; + name: string; + provider: string; webhook_headers?: string; /** @default 1 */ webhook_method?: number; @@ -275,22 +243,22 @@ export interface ModelDDNSForm { } export interface ModelDDNSProfile { - access_id?: string; - access_secret?: string; - created_at?: string; - domains?: string[]; - enable_ipv4?: boolean; - enable_ipv6?: boolean; - id?: number; - max_retries?: number; - name?: string; - provider?: string; - updated_at?: string; - webhook_headers?: string; - webhook_method?: number; - webhook_request_body?: string; - webhook_request_type?: number; - webhook_url?: string; + access_id: string; + access_secret: string; + created_at: string; + domains: string[]; + enable_ipv4: boolean; + enable_ipv6: boolean; + id: number; + max_retries: number; + name: string; + provider: string; + updated_at: string; + webhook_headers: string; + webhook_method: number; + webhook_request_body: string; + webhook_request_type: number; + webhook_url: string; } export interface ModelForceUpdateResponse { @@ -300,138 +268,138 @@ export interface ModelForceUpdateResponse { } export interface ModelGeoIP { - country_code?: string; - ip?: ModelIP; + country_code: string; + ip: ModelIP; } export interface ModelHost { - arch?: string; - boot_time?: number; - cpu?: string[]; - disk_total?: number; - gpu?: string[]; - mem_total?: number; - platform?: string; - platform_version?: string; - swap_total?: number; - version?: string; - virtualization?: string; + arch: string; + boot_time: number; + cpu: string[]; + disk_total: number; + gpu: string[]; + mem_total: number; + platform: string; + platform_version: string; + swap_total: number; + version: string; + virtualization: string; } export interface ModelHostState { - cpu?: number; - disk_used?: number; - gpu?: number[]; - load_1?: number; - load_15?: number; - load_5?: number; - mem_used?: number; - net_in_speed?: number; - net_in_transfer?: number; - net_out_speed?: number; - net_out_transfer?: number; - process_count?: number; - swap_used?: number; - tcp_conn_count?: number; - temperatures?: ModelSensorTemperature[]; - udp_conn_count?: number; - uptime?: number; + cpu: number; + disk_used: number; + gpu: number[]; + load_1: number; + load_15: number; + load_5: number; + mem_used: number; + net_in_speed: number; + net_in_transfer: number; + net_out_speed: number; + net_out_transfer: number; + process_count: number; + swap_used: number; + tcp_conn_count: number; + temperatures: ModelSensorTemperature[]; + udp_conn_count: number; + uptime: number; } export interface ModelIP { - ipv4_addr?: string; - ipv6_addr?: string; + ipv4_addr: string; + ipv6_addr: string; } export interface ModelLoginRequest { - password?: string; - username?: string; + password: string; + username: string; } export interface ModelLoginResponse { - expire?: string; - token?: string; + expire: string; + token: string; } export interface ModelNAT { - created_at?: string; - domain?: string; - host?: string; - id?: number; - name?: string; - server_id?: number; - updated_at?: string; + created_at: string; + domain: string; + host: string; + id: number; + name: string; + server_id: number; + updated_at: string; } export interface ModelNATForm { - domain?: string; - host?: string; + domain: string; + host: string; /** @minLength 1 */ - name?: string; - server_id?: number; + name: string; + server_id: number; } export interface ModelNotification { - created_at?: string; - id?: number; - name?: string; - request_body?: string; - request_header?: string; - request_method?: number; - request_type?: number; - updated_at?: string; - url?: string; - verify_tls?: boolean; + created_at: string; + id: number; + name: string; + request_body: string; + request_header: string; + request_method: number; + request_type: number; + updated_at: string; + url: string; + verify_tls: boolean; } export interface ModelNotificationForm { /** @minLength 1 */ - name?: string; - request_body?: string; - request_header?: string; - request_method?: number; - request_type?: number; + name: string; + request_body: string; + request_header: string; + request_method: number; + request_type: number; skip_check?: boolean; - url?: string; + url: string; verify_tls?: boolean; } export interface ModelNotificationGroup { - created_at?: string; - id?: number; - name?: string; - updated_at?: string; + created_at: string; + id: number; + name: string; + updated_at: string; } export interface ModelNotificationGroupForm { /** @minLength 1 */ - name?: string; - notifications?: number[]; + name: string; + notifications: number[]; } export interface ModelNotificationGroupResponseItem { - group?: ModelNotificationGroup; - notifications?: number[]; + group: ModelNotificationGroup; + notifications: number[]; } export interface ModelProfile { - created_at?: string; - id?: number; - login_ip?: string; - password?: string; - updated_at?: string; - username?: string; + created_at: string; + id: number; + login_ip: string; + password: string; + updated_at: string; + username: string; } export interface ModelProfileForm { - new_password?: string; - new_username?: string; - original_password?: string; + new_password: string; + new_username: string; + original_password: string; } export interface ModelRule { /** 覆盖范围 RuleCoverAll/IgnoreAll */ - cover?: number; + cover: number; /** 流量统计周期 */ cycle_interval?: number; /** 流量统计的开始时间 */ @@ -454,7 +422,7 @@ export interface ModelRule { * net_all_speed、transfer_in、transfer_out、transfer_all、offline * transfer_in_cycle、transfer_out_cycle、transfer_all_cycle */ - type?: string; + type: string; } export interface ModelSensorTemperature { @@ -463,27 +431,27 @@ export interface ModelSensorTemperature { } export interface ModelServer { - created_at?: string; + created_at: string; /** DDNS配置 */ ddns_profiles?: number[]; /** 展示排序,越大越靠前 */ - display_index?: number; + display_index: number; /** 启用DDNS */ - enable_ddns?: boolean; - geoip?: ModelGeoIP; + enable_ddns: boolean; + geoip: ModelGeoIP; /** 对游客隐藏 */ - hide_for_guest?: boolean; - host?: ModelHost; - id?: number; - last_active?: string; - name?: string; + hide_for_guest: boolean; + host: ModelHost; + id: number; + last_active: string; + name: string; /** 管理员可见备注 */ - note?: string; + note: string; /** 公开备注 */ - public_note?: string; - state?: ModelHostState; - updated_at?: string; - uuid?: string; + public_note: string; + state: ModelHostState; + updated_at: string; + uuid: string; } export interface ModelServerForm { @@ -493,12 +461,12 @@ export interface ModelServerForm { * 展示排序,越大越靠前 * @default 0 */ - display_index?: number; + display_index: number; /** 启用DDNS */ enable_ddns?: boolean; /** 对游客隐藏 */ hide_for_guest?: boolean; - name?: string; + name: string; /** 管理员可见备注 */ note?: string; /** 公开备注 */ @@ -506,95 +474,95 @@ export interface ModelServerForm { } export interface ModelServerGroup { - created_at?: string; - id?: number; - name?: string; - updated_at?: string; + created_at: string; + id: number; + name: string; + updated_at: string; } export interface ModelServerGroupForm { /** @minLength 1 */ - name?: string; - servers?: number[]; + name: string; + servers: number[]; } export interface ModelServerGroupResponseItem { - group?: ModelServerGroup; - servers?: number[]; + group: ModelServerGroup; + servers: number[]; } export interface ModelService { - cover?: number; - created_at?: string; - duration?: number; - enable_show_in_service?: boolean; - enable_trigger_task?: boolean; + cover: number; + created_at: string; + duration: number; + enable_show_in_service: boolean; + enable_trigger_task: boolean; /** 失败时执行的触发任务id */ - fail_trigger_tasks?: number[]; - id?: number; - latency_notify?: boolean; - max_latency?: number; - min_latency?: number; - name?: string; + fail_trigger_tasks: number[]; + id: number; + latency_notify: boolean; + max_latency: number; + min_latency: number; + name: string; /** 当前服务监控所属的通知组 ID */ - notification_group_id?: number; - notify?: boolean; + notification_group_id: number; + notify: boolean; /** 恢复时执行的触发任务id */ - recover_trigger_tasks?: number[]; - skip_servers?: Record; - target?: string; - type?: number; - updated_at?: string; + recover_trigger_tasks: number[]; + skip_servers: Record; + target: string; + type: number; + updated_at: string; } export interface ModelServiceForm { - cover?: number; - duration?: number; + cover: number; + duration: number; enable_show_in_service?: boolean; enable_trigger_task?: boolean; - fail_trigger_tasks?: number[]; + fail_trigger_tasks: number[]; latency_notify?: boolean; /** @default 0 */ - max_latency?: number; + max_latency: number; /** @default 0 */ - min_latency?: number; + min_latency: number; /** @minLength 1 */ - name?: string; - notification_group_id?: number; + name: string; + notification_group_id: number; notify?: boolean; - recover_trigger_tasks?: number[]; - skip_servers?: Record; - target?: string; - type?: number; + recover_trigger_tasks: number[]; + skip_servers: Record; + target: string; + type: number; } export interface ModelServiceInfos { - avg_delay?: number[]; - created_at?: number[]; - monitor_id?: number; - monitor_name?: string; - server_id?: number; - server_name?: string; + avg_delay: number[]; + created_at: number[]; + monitor_id: number; + monitor_name: string; + server_id: number; + server_name: string; } export interface ModelServiceResponse { - cycle_transfer_stats?: Record; - services?: Record; + cycle_transfer_stats: Record; + services: Record; } export interface ModelServiceResponseItem { - current_down?: number; - current_up?: number; - delay?: number[]; - down?: number[]; - service?: ModelService; - total_down?: number; - total_up?: number; - up?: number[]; + current_down: number; + current_up: number; + delay: number[]; + down: number[]; + service: ModelService; + total_down: number; + total_up: number; + up: number[]; } export interface ModelSettingForm { - cover?: number; + cover: number; custom_code?: string; custom_code_dashboard?: string; custom_nameservers?: string; @@ -603,54 +571,88 @@ export interface ModelSettingForm { ignored_ip_notification?: string; install_host?: string; /** IP变更提醒的通知组 */ - ip_change_notification_group_id?: number; + ip_change_notification_group_id: number; /** @minLength 2 */ - language?: string; + language: string; /** 真实IP */ real_ip_header?: string; /** @minLength 1 */ - site_name?: string; + site_name: string; + tls?: boolean; +} + +export interface ModelSettingResponse { + agent_secret_key: string; + avg_ping_count: number; + /** 覆盖范围(0:提醒未被 IgnoredIPNotification 包含的所有服务器; 1:仅提醒被 IgnoredIPNotification 包含的服务器;) */ + cover: number; + custom_code: string; + custom_code_dashboard: string; + /** debug模式开关 */ + debug: boolean; + dns_servers: string; + /** IP变更提醒 */ + enable_ip_change_notification: boolean; + /** 通知信息IP不打码 */ + enable_plain_ip_in_notification: boolean; + /** 特定服务器IP(多个服务器用逗号分隔) */ + ignored_ip_notification: string; + /** [ServerID] -> bool(值为true代表当前ServerID在特定服务器列表内) */ + ignored_ip_notification_server_ids: Record; + install_host: string; + ip_change_notification_group_id: number; + jwt_secret_key: string; + /** 系统语言,默认 zh_CN */ + language: string; + listen_port: number; + /** 时区,默认为 Asia/Shanghai */ + location: string; + /** 真实IP */ + real_ip_header: string; + site_name: string; + tls: boolean; + version: string; } export interface ModelStreamServer { - country_code?: string; + country_code: string; /** 展示排序,越大越靠前 */ - display_index?: number; - host?: ModelHost; - id?: number; - last_active?: string; - name?: string; + display_index: number; + host: ModelHost; + id: number; + last_active: string; + name: string; /** 公开备注,只第一个数据包有值 */ - public_note?: string; - state?: ModelHostState; + public_note: string; + state: ModelHostState; } export interface ModelStreamServerData { - now?: number; - servers?: ModelStreamServer[]; + now: number; + servers: ModelStreamServer[]; } export interface ModelTerminalForm { - protocol?: string; - server_id?: number; + protocol: string; + server_id: number; } export interface ModelUser { - created_at?: string; - id?: number; - password?: string; - updated_at?: string; - username?: string; + created_at: string; + id: number; + password: string; + updated_at: string; + username: string; } export interface ModelUserForm { - password?: string; - username?: string; + password: string; + username: string; } export interface ModelWAFApiMock { - count?: number; - ip?: string; - last_block_reason?: number; - last_block_timestamp?: number; + count: number; + ip: string; + last_block_reason: number; + last_block_timestamp: number; }