@samitouri / QOSami-HFS / commits / f3346b87

admin/logs: block-ip will append to existing "from log" rule (if any), and same does monitoring

Massimo Melina committed Jun 23, 2024 at 00:10 UTC f3346b8704ff50d448b7f69ee0aea1bc9ceaa776
4 files changed +21 -7
admin/src/OptionsPage.ts
+1
@@ -147,6 +147,7 @@ export default function OptionsPage() {
147 k: 'disabled',
148 $type: 'boolean',
149 label: "Enabled",
150 + helperText: "In case you want to not block without deleting the rule",
151 toField: (x: any) => !x,
152 fromField: (x: any) => x ? undefined : true,
153 sm: 6,
admin/src/useBlockIp.ts
+4 -6
@@ -1,6 +1,5 @@
1 import { apiCall, useApi } from '@hfs/shared/api'
2 import { createElement as h, useCallback } from 'react'
3 -import { BlockingRule } from '../../src/block'
3 import { toast } from './dialog'
4 import _ from 'lodash'
5 import { IconBtn, IconBtnProps } from './mui'
@@ -8,10 +7,6 @@ import { Block } from '@mui/icons-material'
7
8 export function useBlockIp() {
9 const { data, reload } = useApi('get_config', { only: ['block'] })
11 - const block = useCallback((ip: string, more: Partial<BlockingRule>={}, showResult=true) =>
12 - apiCall('set_config', { values: { block: [...data.block, { ip, ...more }] } })
13 - .then(reload).then(() => showResult && toast("Blocked", 'success')),
14 - [data, reload])
10 const isBlocked = useCallback((ip: string) => _.find(data?.block, { ip }), [data])
11 return {
12 iconBtn: (ip: string, comment: string, options: Partial<IconBtnProps>={}) => h(IconBtn, {
@@ -20,7 +15,10 @@ export function useBlockIp() {
15 confirm: "Block address " + ip,
16 ...isBlocked(ip) && { disabled: true, title: "Blocked" },
17 ...options,
23 - onClick: () => block(ip, { comment }),
18 + onClick() {
19 + return apiCall('add_block', { ip, comment, merge: { comment } })
20 + .then(reload).then(() => toast("Blocked", 'success'))
21 + },
22 }),
23 }
24 }
src/adminApis.ts
+15
@@ -36,6 +36,7 @@ import { ip2country } from './geo'
36 import { roots } from './roots'
37 import { SendListReadable } from './SendList'
38 import { get_dynamic_dns_error } from './ddns'
39 +import { block, BlockingRule } from './block'
40
41 export const adminApis = {
42
@@ -136,6 +137,20 @@ export const adminApis = {
137 return files
138 },
139
140 + async add_block({ merge, ip, expire, comment }: BlockingRule & { merge?: Partial<BlockingRule> }) {
141 + apiAssertTypes({
142 + string: { ip },
143 + string_undefined: { comment, expire },
144 + object_undefined: { merge },
145 + })
146 + block.set(was => {
147 + const found = merge && _.findIndex(was, merge)
148 + return found ? was.map((x, i) => i === found ? { ...x, ip: `${x.ip}|${ip}` } : x)
149 + : [...was, { ip, expire, comment }]
150 + })
151 + return {}
152 + }
153 +
154 } satisfies ApiHandlers
155
156 for (const [k, was] of typedEntries(adminApis))
src/perm.ts
+1 -1
@@ -59,7 +59,7 @@ createAdminConfig.sub(v => {
59
60 export async function createAdmin(password: string, username='admin') {
61 const acc = await addAccount(username, { admin: true, password }, true)
62 - console.log(acc ? "account admin created" : "something went wrong")
62 + console.log(acc ? "account admin set" : "something went wrong")
63 }
64
65 const srp6aNimbusRoutines = new SRPRoutines(new SRPParameters())