Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5a811e5ee | ||
|
|
b3adfe5c8f | ||
|
|
8eda2eae99 | ||
|
|
99673913a6 | ||
|
|
83e48e3485 | ||
|
|
8607591871 |
@@ -43,8 +43,8 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache,mode=max
|
||||
# cache-from: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache
|
||||
# cache-to: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache,mode=max
|
||||
# platforms: linux/amd64,linux/arm64
|
||||
platforms: linux/amd64
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "litek",
|
||||
"private": true,
|
||||
"version": "0.0.11",
|
||||
"version": "0.0.14",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
/* 默认浅色模式使用黑色 */
|
||||
path {
|
||||
fill: #000000;
|
||||
}
|
||||
/* 暗色模式使用白色 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path {
|
||||
fill: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
<g id="SVGRepo_iconCarrier"> <path d="M12.6089 6.12601C12.6785 5.85878 12.5183 5.58573 12.251 5.51614C11.9838 5.44655 11.7108 5.60676 11.6412 5.87399L10.0842 11.8528L7.85646 12.5211C7.59196 12.6005 7.44187 12.8792 7.52122 13.1437C7.60057 13.4082 7.87931 13.5583 8.14381 13.479L9.78926 12.9853L8.51617 17.874C8.47715 18.0238 8.50974 18.1833 8.60443 18.3058C8.69911 18.4283 8.8452 18.5 9.00003 18.5H16C16.2762 18.5 16.5 18.2761 16.5 18C16.5 17.7239 16.2762 17.5 16 17.5H9.64691L10.9102 12.6491L13.1438 11.979C13.4083 11.8996 13.5584 11.6209 13.479 11.3564C13.3997 11.0919 13.121 10.9418 12.8565 11.0211L11.2051 11.5165L12.6089 6.12601Z"/> </g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -91,8 +91,8 @@ const Tool: FC = () => {
|
||||
const startTime = performance.now();
|
||||
|
||||
try {
|
||||
// 使用 ip-api.com (免费,功能较全)
|
||||
const response = await fetch(`http://ip-api.com/json/${encodeURIComponent(ip.trim())}?fields=status,message,country,countryCode,region,city,lat,lon,timezone,isp,org,as,proxy,hosting,query`);
|
||||
// 使用 ipinfo.io (免费,稳定可靠)
|
||||
const response = await fetch(`https://ipinfo.io/${encodeURIComponent(ip.trim())}/json`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
@@ -103,28 +103,8 @@ const Tool: FC = () => {
|
||||
|
||||
setQueryTime(endTime - startTime);
|
||||
|
||||
if (data.status === "fail") {
|
||||
toast.error(data.message || "Query failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换为统一格式
|
||||
const ipData: IPInfo = {
|
||||
ip: data.query,
|
||||
city: data.city,
|
||||
region: data.region,
|
||||
country: data.country,
|
||||
countryCode: data.countryCode,
|
||||
loc: data.lat && data.lon ? `${data.lat},${data.lon}` : undefined,
|
||||
timezone: data.timezone,
|
||||
isp: data.isp,
|
||||
org: data.org,
|
||||
as: data.as,
|
||||
proxy: data.proxy,
|
||||
hosting: data.hosting,
|
||||
};
|
||||
|
||||
setIpInfo(ipData);
|
||||
// ipinfo.io 返回格式已经符合 IPInfo 接口
|
||||
setIpInfo(data);
|
||||
toast.success("Query successful");
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -146,14 +126,18 @@ const Tool: FC = () => {
|
||||
const getRiskLevel = () => {
|
||||
if (!ipInfo) return null;
|
||||
|
||||
if (ipInfo.proxy || ipInfo.hosting) {
|
||||
// ipinfo.io 通过 org 字段可以简单判断是否为托管IP
|
||||
const orgLower = ipInfo.org?.toLowerCase() || "";
|
||||
const isHosting = orgLower.includes("hosting") ||
|
||||
orgLower.includes("datacenter") ||
|
||||
orgLower.includes("cloud") ||
|
||||
orgLower.includes("server");
|
||||
|
||||
if (isHosting) {
|
||||
return {
|
||||
level: "High",
|
||||
color: "text-red-500",
|
||||
reasons: [
|
||||
ipInfo.proxy && "Proxy/VPN detected",
|
||||
ipInfo.hosting && "Hosting/Datacenter IP",
|
||||
].filter(Boolean),
|
||||
level: "Medium",
|
||||
color: "text-yellow-500",
|
||||
reasons: ["Possible Hosting/Datacenter IP"],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user