Skip to content

Commit 3dc6da8

Browse files
committed
fix: waf page
1 parent 7463bbe commit 3dc6da8

File tree

9 files changed

+52
-23
lines changed

9 files changed

+52
-23
lines changed

src/api/waf.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { ModelWAF } from "@/types"
1+
import { ModelWAFApiMock } from "@/types"
22
import { fetcher, FetcherMethod } from "./api"
33

44
export const deleteWAF = async (ip: string[]): Promise<void> => {
55
return fetcher<void>(FetcherMethod.POST, '/api/v1/batch-delete/waf', ip);
66
}
77

8-
export const getWAFList = async (): Promise<ModelWAF[]> => {
9-
return fetcher<ModelWAF[]>(FetcherMethod.GET, '/api/v1/waf', null);
8+
export const getWAFList = async (): Promise<ModelWAFApiMock[]> => {
9+
return fetcher<ModelWAFApiMock[]>(FetcherMethod.GET, '/api/v1/waf', null);
1010
}

src/lib/utils.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,18 @@ export function joinIP(p?: ModelIP) {
141141
return '';
142142
}
143143

144-
export function ip16Str(p: number[]) {
145-
const buf = new Uint8Array(p);
144+
function base64toUint8Array(base64str: string) {
145+
const binary = atob(base64str);
146+
const len = binary.length;
147+
const buf = new Uint8Array(len);
148+
for (let i = 0; i < len; i++) {
149+
buf[i] = binary.charCodeAt(i);
150+
}
151+
return buf;
152+
}
153+
154+
export function ip16Str(base64str: string) {
155+
const buf = base64toUint8Array(base64str);
146156
const ip4 = buf.slice(-6);
147157
if (ip4[0] === 255 && ip4[1] === 255) {
148158
return ip4.slice(2).join('.');

src/locales/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
"CustomCodesDashboard": "Custom Codes for Dashboard",
135135
"CustomPublicDNSNameserversforDDNS": "Custom Public DNS Nameservers for DDNS",
136136
"RealIPHeader": "Real IP request header",
137+
"UseDirectConnectingIP": "Use direct connection IP",
137138
"IPChangeNotification": "IP Change notification",
138139
"FullIPNotification": "Show Full IP Address in Notification Messages",
139140
"EditService": "Editing services",

src/locales/it/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
"DashboardOriginalHost": "Nome di dominio/IP del server Dashboard (no CDN)",
142142
"CustomPublicDNSNameserversforDDNS": "Server dei nomi DNS pubblici personalizzati per DDNS",
143143
"RealIPHeader": "Intestazione della richiesta IP reale",
144+
"UseDirectConnectingIP": "Utilizzare l'IP di connessione diretta",
144145
"IPChangeNotification": "Notifica di modifica IP",
145146
"FullIPNotification": "Mostra l'indirizzo IP completo nei messaggi di notifica",
146147
"LoginFailed": "Accesso non riuscito",

src/locales/zh-CN/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
"DashboardOriginalHost": "仪表板服务器域名/IP(无 CDN)",
141141
"CustomPublicDNSNameserversforDDNS": "DDNS 的自定义公共 DNS 名称服务器",
142142
"RealIPHeader": "真实IP请求头",
143+
"UseDirectConnectingIP": "使用直连 IP",
143144
"IPChangeNotification": "IP变更通知",
144145
"FullIPNotification": "在通知消息中显示完整的 IP 地址",
145146
"LoginFailed": "登录失败",

src/locales/zh-TW/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
"DashboardOriginalHost": "儀表板伺服器網域/IP(無 CDN)",
141141
"CustomPublicDNSNameserversforDDNS": "DDNS 的自訂公共 DNS 名稱伺服器",
142142
"RealIPHeader": "真實IP請求頭",
143+
"UseDirectConnectingIP": "使用直連 IP",
143144
"IPChangeNotification": "IP變更通知",
144145
"FullIPNotification": "在通知訊息中顯示完整的 IP 位址",
145146
"LoginFailed": "登入失敗",

src/routes/settings.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const settingFormSchema = z.object({
4848
});
4949

5050
export default function SettingsPage() {
51-
const { t , i18n} = useTranslation();
51+
const { t, i18n } = useTranslation();
5252
const [config, setConfig] = useState<ModelConfig>();
5353
const [error, setError] = useState<Error>();
5454

@@ -57,7 +57,7 @@ export default function SettingsPage() {
5757
toast(t("Error"), {
5858
description: t("Results.ErrorFetchingResource", { error: error.message }),
5959
});
60-
// eslint-disable-next-line react-hooks/exhaustive-deps
60+
// eslint-disable-next-line react-hooks/exhaustive-deps
6161
}, [error]);
6262

6363
useEffect(() => {
@@ -106,9 +106,9 @@ export default function SettingsPage() {
106106
return;
107107
} finally {
108108
toast(t("Success"));
109-
if (values.language!= "auto"){
109+
if (values.language != "auto") {
110110
i18n.changeLanguage(values.language)
111-
}else{
111+
} else {
112112
i18n.changeLanguage(i18n.services.languageDetector.detect());
113113
}
114114
}
@@ -204,7 +204,7 @@ export default function SettingsPage() {
204204
render={({ field }) => (
205205
<FormItem>
206206
<FormLabel>
207-
{t("CustomPublicDNSNameserversforDDNS")+" " + t("SeparateWithComma")}
207+
{t("CustomPublicDNSNameserversforDDNS") + " " + t("SeparateWithComma")}
208208
</FormLabel>
209209
<FormControl>
210210
<Input {...field} />
@@ -220,7 +220,21 @@ export default function SettingsPage() {
220220
<FormItem>
221221
<FormLabel>{t("RealIPHeader")}</FormLabel>
222222
<FormControl>
223-
<Input placeholder="NZ::Use-Peer-IP" {...field} />
223+
<div className="flex items-center">
224+
<Input disabled={field.value == 'NZ::Use-Peer-IP'} className="w-1/2" placeholder="CF-Connecting-IP" {...field} />
225+
<Checkbox checked={field.value == 'NZ::Use-Peer-IP'} className="ml-2" onCheckedChange={(checked) => {
226+
if (checked) {
227+
field.disabled = true;
228+
form.setValue("real_ip_header", "NZ::Use-Peer-IP");
229+
} else {
230+
field.disabled = false;
231+
form.setValue("real_ip_header", "");
232+
}
233+
}} />
234+
<FormLabel className="font-normal ml-2">
235+
{t("UseDirectConnectingIP")}
236+
</FormLabel>
237+
</div>
224238
</FormControl>
225239
<FormMessage />
226240
</FormItem>
@@ -260,7 +274,7 @@ export default function SettingsPage() {
260274
name="ignored_ip_notification"
261275
render={({ field }) => (
262276
<FormItem>
263-
<FormLabel>{t("SpecificServers")+" " + t("SeparateWithComma")}</FormLabel>
277+
<FormLabel>{t("SpecificServers") + " " + t("SeparateWithComma")}</FormLabel>
264278
<FormControl>
265279
<Input placeholder="1,2,3" {...field} />
266280
</FormControl>

src/routes/waf.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useEffect, useMemo } from "react";
1414
import { ActionButtonGroup } from "@/components/action-button-group";
1515
import { HeaderButtonGroup } from "@/components/header-button-group";
1616
import { toast } from "sonner";
17-
import { ModelWAF, wafBlockReasons } from "@/types";
17+
import { ModelWAFApiMock, wafBlockReasons } from "@/types";
1818
import { deleteWAF } from "@/api/waf";
1919
import { ip16Str } from "@/lib/utils";
2020
import { SettingsTab } from "@/components/settings-tab";
@@ -23,7 +23,7 @@ import { useTranslation } from "react-i18next";
2323

2424
export default function WAFPage() {
2525
const { t } = useTranslation();
26-
const { data, mutate, error, isLoading } = useSWR<ModelWAF[]>("/api/v1/waf", swrFetcher);
26+
const { data, mutate, error, isLoading } = useSWR<ModelWAFApiMock[]>("/api/v1/waf", swrFetcher);
2727

2828
useEffect(() => {
2929
if (error)
@@ -33,7 +33,7 @@ export default function WAFPage() {
3333
// eslint-disable-next-line react-hooks/exhaustive-deps
3434
}, [error]);
3535

36-
const columns: ColumnDef<ModelWAF>[] = [
36+
const columns: ColumnDef<ModelWAFApiMock>[] = [
3737
{
3838
id: "select",
3939
header: ({ table }) => (
@@ -59,7 +59,7 @@ export default function WAFPage() {
5959
{
6060
header: "IP",
6161
accessorKey: "ip",
62-
accessorFn: (row) => ip16Str(row.ip ?? []),
62+
accessorFn: (row) => ip16Str(row.ip ?? ""),
6363
},
6464
{
6565
header: t("Count"),
@@ -78,7 +78,7 @@ export default function WAFPage() {
7878
accessorFn: (row) => row.last_block_timestamp,
7979
cell: ({ row }) => {
8080
const s = row.original;
81-
const date = new Date(s.last_block_timestamp || 0);
81+
const date = new Date((s.last_block_timestamp || 0)*1000);
8282
return <span>{date.toISOString()}</span>;
8383
},
8484
},
@@ -92,7 +92,7 @@ export default function WAFPage() {
9292
className="flex gap-2"
9393
delete={{
9494
fn: deleteWAF,
95-
id: ip16Str(s.ip ?? []),
95+
id: ip16Str(s.ip ?? ""),
9696
mutate: mutate,
9797
}}
9898
>
@@ -123,7 +123,7 @@ export default function WAFPage() {
123123
className="flex-2 flex gap-2 ml-auto"
124124
delete={{
125125
fn: deleteWAF,
126-
id: selectedRows.map((r) => ip16Str(r.original.ip ?? [])),
126+
id: selectedRows.map((r) => ip16Str(r.original.ip ?? "")),
127127
mutate: mutate,
128128
}}
129129
>

src/types/api.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ export interface GithubComNezhahqNezhaModelCommonResponseArrayModelUser {
7575
success?: boolean;
7676
}
7777

78-
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelWAF {
79-
data?: ModelWAF[];
78+
export interface GithubComNezhahqNezhaModelCommonResponseArrayModelWAFApiMock {
79+
data?: ModelWAFApiMock[];
8080
error?: string;
8181
success?: boolean;
8282
}
@@ -425,6 +425,7 @@ export interface ModelProfile {
425425

426426
export interface ModelProfileForm {
427427
new_password?: string;
428+
new_username?: string;
428429
original_password?: string;
429430
}
430431

@@ -647,9 +648,9 @@ export interface ModelUserForm {
647648
username?: string;
648649
}
649650

650-
export interface ModelWAF {
651+
export interface ModelWAFApiMock {
651652
count?: number;
652-
ip?: number[];
653+
ip?: string;
653654
last_block_reason?: number;
654655
last_block_timestamp?: number;
655656
}

0 commit comments

Comments
 (0)