fix: missing notification group input in settings (#24)

* fix: missing notification group input in settings

* change script name

* license

* update settings api

* improve: cell width

* feat: site name
This commit is contained in:
UUBulb
2024-12-04 20:03:16 +08:00
committed by GitHub
parent 36472035e1
commit 58efdde19e
13 changed files with 639 additions and 371 deletions

View File

@@ -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<void> => {
return fetcher<void>(FetcherMethod.PATCH, `/api/v1/setting`, data);
}
export const getSettings = async (): Promise<ModelConfig> => {
return fetcher<ModelConfig>(FetcherMethod.GET, '/api/v1/setting', null);
export const getSettings = async (): Promise<ModelSettingResponse> => {
return fetcher<ModelSettingResponse>(FetcherMethod.GET, '/api/v1/setting', null);
}

View File

@@ -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 ? (
<header className="h-16 flex items-center border-b-2 px-4 overflow-x-auto">
@@ -121,17 +123,27 @@ export default function Header() {
<DropdownMenuLabel>{profile.username}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem onClick={() => { setDropdownOpen(false) }}>
<Link to="/dashboard/profile" className="flex items-center gap-2 w-full">
<DropdownMenuItem onClick={() => {
setDropdownOpen(false)
navigate("/dashboard/profile")
}}
className="cursor-pointer"
>
<div className="flex items-center gap-2 w-full">
<User2 />
{t('Profile')}
</Link>
</div>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => { setDropdownOpen(false) }}>
<Link to="/dashboard/settings" className="flex items-center gap-2 w-full">
<DropdownMenuItem onClick={() => {
setDropdownOpen(false)
navigate("/dashboard/settings")
}}
className="cursor-pointer"
>
<div className="flex items-center gap-2 w-full">
<Settings />
{t('Settings')}
</Link>
</div>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
@@ -199,19 +211,27 @@ export default function Header() {
<DropdownMenuLabel>{profile.username}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem onClick={() => { setDropdownOpen(false) }}>
<Link to="/dashboard/profile" className="flex items-center gap-2 w-full">
<DropdownMenuItem onClick={() => {
setDropdownOpen(false)
navigate("/dashboard/profile")
}}
className="cursor-pointer"
>
<div className="flex items-center gap-2 w-full">
<User2 />
{t('Profile')}
<DropdownMenuShortcut>P</DropdownMenuShortcut>
</Link>
</div>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => { setDropdownOpen(false) }}>
<Link to="/dashboard/settings" className="flex items-center gap-2 w-full">
<DropdownMenuItem onClick={() => {
setDropdownOpen(false)
navigate("/dashboard/settings")
}}
className="cursor-pointer"
>
<div className="flex items-center gap-2 w-full">
<Settings />
{t('Settings')}
<DropdownMenuShortcut>S</DropdownMenuShortcut>
</Link>
</div>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />

View File

@@ -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<HTMLButtonElement, ButtonProps>((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`

View File

@@ -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<ModelConfig>(
const { data } = useSWR<ModelSettingResponse>(
"/api/v1/setting",
swrFetcher
);

View File

@@ -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",

View File

@@ -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",

View File

@@ -140,6 +140,7 @@
"CustomCodes": "自定义代码(样式和脚本)",
"CustomCodesDashboard": "仪表板的自定义代码",
"DashboardOriginalHost": "Agent对接地址【域名/IP:端口】",
"ConfigTLS": "Agent 使用 TLS 连接",
"CustomPublicDNSNameserversforDDNS": "DDNS 的自定义公共 DNS 名称服务器",
"RealIPHeader": "真实IP请求头",
"UseDirectConnectingIP": "使用直连 IP",

View File

@@ -140,6 +140,7 @@
"CustomCodes": "自訂程式碼(樣式和腳本)",
"CustomCodesDashboard": "儀表板的自訂程式碼",
"DashboardOriginalHost": "Agent對接位址【網域名稱/IP:連接埠】",
"ConfigTLS": "Agent 使用 TLS 連線",
"CustomPublicDNSNameserversforDDNS": "DDNS 的自訂公共 DNS 名稱伺服器",
"RealIPHeader": "真實IP請求頭",
"UseDirectConnectingIP": "使用直連 IP",

View File

@@ -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<ModelAlertRule>[] = [
@@ -44,7 +44,7 @@ export default function AlertRulePage() {
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() && "indeterminate")
(table.getIsSomePageRowsSelected() && "indeterminate")
}
onCheckedChange={(value) => 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 <div className="max-w-48 whitespace-normal break-words">{JSON.stringify(s.rules)}</div>;
},
},
{
header: t("TasksToTriggerOnAlert"),

View File

@@ -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 (
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
<Card className="text-sm max-w-7xl mx-auto mt-5 min-h-[90%] flex flex-col justify-between">
@@ -17,7 +25,7 @@ export default function Root() {
<Outlet />
</div>
<footer className="mx-5 pb-5 text-foreground/60 font-thin text-center">
&copy; 2019-2024 {t('nezha')}
&copy; 2019-2024 {t('nezha')} {settings?.version}
</footer>
</Card>
<Toaster />

View File

@@ -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<ModelConfig>();
const [config, setConfig] = useState<ModelSettingResponse>();
const [error, setError] = useState<Error>();
useEffect(() => {
@@ -196,6 +197,23 @@ export default function SettingsPage() {
</FormItem>
)}
/>
<FormField
control={form.control}
name="tls"
render={({ field }) => (
<FormItem className="flex items-center space-x-2">
<FormControl>
<div className="flex items-center gap-2">
<Checkbox checked={field.value} onCheckedChange={field.onChange} />
<Label className="text-sm">
{t("ConfigTLS")}
</Label>
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="custom_nameservers"
@@ -280,6 +298,19 @@ export default function SettingsPage() {
</FormItem>
)}
/>
<FormField
control={form.control}
name="ip_change_notification_group_id"
render={({ field }) => (
<FormItem>
<FormLabel>{t("NotifierGroupID")}</FormLabel>
<FormControl>
<Input placeholder="0" type="number" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="enable_ip_change_notification"

View File

@@ -10,261 +10,229 @@
*/
export interface GithubComNezhahqNezhaModelCommonResponseAny {
data?: any;
error?: string;
success?: boolean;
data: any;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelAlertRule {
data?: ModelAlertRule[];
error?: string;
success?: boolean;
data: ModelAlertRule[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelCron {
data?: ModelCron[];
error?: string;
success?: boolean;
data: ModelCron[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelDDNSProfile {
data?: ModelDDNSProfile[];
error?: string;
success?: boolean;
data: ModelDDNSProfile[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelNAT {
data?: ModelNAT[];
error?: string;
success?: boolean;
data: ModelNAT[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelNotification {
data?: ModelNotification[];
error?: string;
success?: boolean;
data: ModelNotification[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelNotificationGroupResponseItem {
data?: ModelNotificationGroupResponseItem[];
error?: string;
success?: boolean;
data: ModelNotificationGroupResponseItem[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelServer {
data?: ModelServer[];
error?: string;
success?: boolean;
data: ModelServer[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelServerGroupResponseItem {
data?: ModelServerGroupResponseItem[];
error?: string;
success?: boolean;
data: ModelServerGroupResponseItem[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelServiceInfos {
data?: ModelServiceInfos[];
error?: string;
success?: boolean;
data: ModelServiceInfos[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelUser {
data?: ModelUser[];
error?: string;
success?: boolean;
data: ModelUser[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelWAFApiMock {
data?: ModelWAFApiMock[];
error?: string;
success?: boolean;
data: ModelWAFApiMock[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayString {
data?: string[];
error?: string;
success?: boolean;
data: string[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseArrayUint64 {
data?: number[];
error?: string;
success?: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelConfig {
data?: ModelConfig;
error?: string;
success?: boolean;
data: number[];
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelForceUpdateResponse {
data?: ModelForceUpdateResponse;
error?: string;
success?: boolean;
data: ModelForceUpdateResponse;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelLoginResponse {
data?: ModelLoginResponse;
error?: string;
success?: boolean;
data: ModelLoginResponse;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelProfile {
data?: ModelProfile;
error?: string;
success?: boolean;
data: ModelProfile;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelServiceResponse {
data?: ModelServiceResponse;
error?: string;
success?: boolean;
data: ModelServiceResponse;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseModelSettingResponse {
data: ModelSettingResponse;
error: string;
success: boolean;
}
export interface GithubComNezhahqNezhaModelCommonResponseUint64 {
data?: number;
error?: string;
success?: boolean;
data: number;
error: string;
success: boolean;
}
export interface ModelAlertRule {
created_at?: string;
enable?: boolean;
created_at: string;
enable: boolean;
/** 失败时执行的触发任务id */
fail_trigger_tasks?: number[];
id?: number;
name?: string;
fail_trigger_tasks: number[];
id: number;
name: string;
/** 该报警规则所在的通知组 */
notification_group_id?: number;
notification_group_id: number;
/** 恢复时执行的触发任务id */
recover_trigger_tasks?: number[];
rules?: ModelRule[];
recover_trigger_tasks: number[];
rules: ModelRule[];
/** 触发模式: 0-始终触发(默认) 1-单次触发 */
trigger_mode?: number;
updated_at?: string;
trigger_mode: number;
updated_at: string;
}
export interface ModelAlertRuleForm {
enable?: boolean;
/** 失败时触发的任务id */
fail_trigger_tasks?: number[];
fail_trigger_tasks: number[];
/** @minLength 1 */
name?: string;
notification_group_id?: number;
name: string;
notification_group_id: number;
/** 恢复时触发的任务id */
recover_trigger_tasks?: number[];
rules?: ModelRule[];
recover_trigger_tasks: number[];
rules: ModelRule[];
/** @default 0 */
trigger_mode?: number;
}
export interface ModelConfig {
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<string, boolean>;
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<string, string>;
server_name?: Record<string, string>;
to?: string;
transfer?: Record<string, number>;
from: string;
max: number;
min: number;
name: string;
next_update: Record<string, string>;
server_name: Record<string, string>;
to: string;
transfer: Record<string, number>;
}
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<string, boolean>;
target?: string;
type?: number;
updated_at?: string;
recover_trigger_tasks: number[];
skip_servers: Record<string, boolean>;
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<string, boolean>;
target?: string;
type?: number;
recover_trigger_tasks: number[];
skip_servers: Record<string, boolean>;
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<string, ModelCycleTransferStats>;
services?: Record<string, ModelServiceResponseItem>;
cycle_transfer_stats: Record<string, ModelCycleTransferStats>;
services: Record<string, ModelServiceResponseItem>;
}
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<string, boolean>;
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;
}