admin/internet: new "Lookup IP" button
Massimo Melina committed
Mar 10, 2025 at 00:18 UTC
cfcb75ab08a4cd7d3171103d20c94fa60e5dfa84
2 files changed
+21
-3
admin/src/InternetPage.ts
+15
-2
@@ -1,7 +1,7 @@
1
import { createElement as h, ReactNode, useEffect, useMemo, useRef, useState } from 'react'
2
import { Alert, Box, Button, Card, CardContent, CircularProgress, Divider, LinearProgress, Link, Typography } from '@mui/material'
3
import { CardMembership, Check, Dns, HomeWorkTwoTone, Lock, Public, PublicTwoTone, RouterTwoTone, Send, Storage,
4
- Error as ErrorIcon, SvgIconComponent } from '@mui/icons-material'
4
+ Error as ErrorIcon, SvgIconComponent, Search } from '@mui/icons-material'
5
import { apiCall, useApiEvents, useApiEx } from './api'
6
import {
7
closeDialog, DAY, formatTimestamp, wait, wantArray, with_, PORT_DISABLED, isIP, CFG, md,
@@ -152,11 +152,24 @@ export default function InternetPage({ setTitleSide }: PageProps) {
152
options: { Allow: true, Block: false },
153
},
154
]
155
- ] })
155
+ ] }),
156
+ addToBar: [
157
+ h(Box, { flex: 1 }),
158
+ h(Btn, { icon: Search, onClick: lookup }, "Lookup IP")
159
+ ],
160
})
161
)
162
}
163
164
+ async function lookup() {
165
+ const ip = await promptDialog("Lookup IP")
166
+ if (!ip) return
167
+ const { country } = await apiCall('geo_ip', { ip })
168
+ if (!country)
169
+ return alertDialog("IP not found", 'error')
170
+ return alertDialog(h(Country, { code: country, long: true }), 'success')
171
+ }
172
+
173
function httpsBox() {
174
const [values, setValues] = useState<any>()
175
const cert = useApiEx('get_cert')
src/adminApis.ts
+6
-1
@@ -161,7 +161,12 @@ export const adminApis = {
161
const optionals = _.pickBy({ expire, comment }, v => v !== undefined) // passing undefined-s would override values in merge
162
addBlock({ ip, ...optionals }, merge)
163
return {}
164
- }
164
+ },
165
+
166
+ async geo_ip({ ip }) {
167
+ apiAssertTypes({ string: { ip } })
168
+ return { country: await ip2country(ip) }
169
+ },
170
171
} satisfies ApiHandlers
172