mirror of
https://github.com/spacebarchat/server.git
synced 2026-03-30 20:25:40 +00:00
Classes for abuseipdb/ipdata
This commit is contained in:
65
src/util/util/networking/abuseipdb/AbuseIpDbClient.ts
Normal file
65
src/util/util/networking/abuseipdb/AbuseIpDbClient.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Config, DateBuilder } from "@spacebar/util";
|
||||
import { AbuseIpDbBlacklistResponse, AbuseIpDbCheckResponse } from "./AbuseIpDbSampleResponses";
|
||||
|
||||
export default class AbuseIpDbClient {
|
||||
private static ipCheckCache: Map<
|
||||
string,
|
||||
{
|
||||
data: AbuseIpDbCheckResponse;
|
||||
expires: number;
|
||||
}
|
||||
> = new Map();
|
||||
|
||||
private static blacklistCache: {
|
||||
data: AbuseIpDbBlacklistResponse;
|
||||
expires: number;
|
||||
} | null = null;
|
||||
|
||||
static async checkIpAddress(ip: string): Promise<AbuseIpDbCheckResponse | null> {
|
||||
const { ipdataApiKey } = Config.get().security;
|
||||
if (!ipdataApiKey) return null;
|
||||
if (this.ipCheckCache.get(ip)?.expires ?? 0 > Date.now()) return this.ipCheckCache.get(ip)!.data;
|
||||
|
||||
console.log(`[AbuseIPDB] Checking IP address ${ip}...`);
|
||||
const resp = (await (await fetch(`https://api.abuseipdb.com/api/v2/check?ipAddress=${ip}`)).json()) as Promise<AbuseIpDbCheckResponse>;
|
||||
this.ipCheckCache.set(ip, {
|
||||
data: await resp,
|
||||
expires: new DateBuilder().addHours(12).buildTimestamp(),
|
||||
});
|
||||
return await resp;
|
||||
}
|
||||
|
||||
static async getBlacklist(): Promise<AbuseIpDbBlacklistResponse | null> {
|
||||
const { abuseIpDbApiKey, abuseipdbBlacklistRatelimit } = Config.get().security;
|
||||
if (!abuseIpDbApiKey) return null;
|
||||
if (this.blacklistCache?.expires ?? 0 > Date.now()) return this.blacklistCache!.data;
|
||||
|
||||
console.log("[AbuseIPDB] Fetching blacklist...");
|
||||
const resp = (await (
|
||||
await fetch(`https://api.abuseipdb.com/api/v2/blacklist`, {
|
||||
headers: {
|
||||
Key: abuseIpDbApiKey,
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
).json()) as Promise<AbuseIpDbBlacklistResponse>;
|
||||
|
||||
this.blacklistCache = {
|
||||
data: await resp,
|
||||
expires: new DateBuilder().addHours(Math.ceil(24 / abuseipdbBlacklistRatelimit)).buildTimestamp(),
|
||||
};
|
||||
|
||||
return await resp;
|
||||
}
|
||||
|
||||
static async isIpBlacklisted(ip: string): Promise<boolean> {
|
||||
const { abuseipdbConfidenceScoreTreshold } = Config.get().security;
|
||||
const blacklist = await this.getBlacklist();
|
||||
if (!blacklist) return false;
|
||||
|
||||
const entry = blacklist.data.find((x) => x.ipAddress === ip);
|
||||
if (!entry) return false;
|
||||
|
||||
return entry.abuseConfidenceScore >= abuseipdbConfidenceScoreTreshold;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export type AbuseIpDbCheckResponse = typeof abuseIpDbCheckResponseSample;
|
||||
export type AbuseIpDbBlacklistResponse = typeof abuseIpDbBlacklistResponseSample;
|
||||
|
||||
const abuseIpDbCheckResponseSample = {
|
||||
data: {
|
||||
ipAddress: "118.25.6.39",
|
||||
isPublic: true,
|
||||
ipVersion: 4,
|
||||
isWhitelisted: false,
|
||||
abuseConfidenceScore: 100,
|
||||
countryCode: "CN",
|
||||
countryName: "China",
|
||||
usageType: "Data Center/Web Hosting/Transit",
|
||||
isp: "Tencent Cloud Computing (Beijing) Co. Ltd",
|
||||
domain: "tencent.com",
|
||||
hostnames: [],
|
||||
isTor: false,
|
||||
totalReports: 1,
|
||||
numDistinctUsers: 1,
|
||||
lastReportedAt: "2018-12-20T20:55:14+00:00",
|
||||
reports: [
|
||||
{
|
||||
reportedAt: "2018-12-20T20:55:14+00:00",
|
||||
comment: "Dec 20 20:55:14 srv206 sshd[13937]: Invalid user oracle from 118.25.6.39",
|
||||
categories: [18, 22],
|
||||
reporterId: 1,
|
||||
reporterCountryCode: "US",
|
||||
reporterCountryName: "United States",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const abuseIpDbBlacklistResponseSample = {
|
||||
meta: {
|
||||
generatedAt: "2020-09-24T19:54:11+00:00",
|
||||
},
|
||||
data: [
|
||||
{
|
||||
ipAddress: "5.188.10.179",
|
||||
abuseConfidenceScore: 100,
|
||||
lastReportedAt: "2020-09-24T19:17:02+00:00",
|
||||
},
|
||||
{
|
||||
ipAddress: "185.222.209.14",
|
||||
abuseConfidenceScore: 100,
|
||||
lastReportedAt: "2020-09-24T19:17:02+00:00",
|
||||
},
|
||||
{
|
||||
ipAddress: "191.96.249.183",
|
||||
abuseConfidenceScore: 100,
|
||||
lastReportedAt: "2020-09-24T19:17:01+00:00",
|
||||
},
|
||||
],
|
||||
};
|
||||
18
src/util/util/networking/abuseipdb/index.ts
Normal file
18
src/util/util/networking/abuseipdb/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export * from "./AbuseIpDbClient";
|
||||
19
src/util/util/networking/index.ts
Normal file
19
src/util/util/networking/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export * from "./abuseipdb";
|
||||
export * from "./ipdata";
|
||||
35
src/util/util/networking/ipdata/IpDataClient.ts
Normal file
35
src/util/util/networking/ipdata/IpDataClient.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Config, DateBuilder } from "@spacebar/util";
|
||||
import { IpDataIpLookupResponse } from "./IpDataSampleResponses";
|
||||
|
||||
export default class IpDataClient {
|
||||
private static ipInfoCache: Map<
|
||||
string,
|
||||
{
|
||||
data: IpDataIpLookupResponse;
|
||||
expires: number;
|
||||
}
|
||||
> = new Map();
|
||||
|
||||
static async getIpInfo(ip: string): Promise<IpDataIpLookupResponse | null> {
|
||||
const { ipdataApiKey } = Config.get().security;
|
||||
if (!ipdataApiKey) return null;
|
||||
if (this.ipInfoCache.get(ip)?.expires ?? 0 > Date.now()) return this.ipInfoCache.get(ip)!.data;
|
||||
|
||||
console.log(`[IpData] Fetching info for IP address ${ip}...`);
|
||||
const resp = (await (await fetch(`https://eu-api.ipdata.co/${ip}?api-key=${ipdataApiKey}`)).json()) as Promise<IpDataIpLookupResponse>;
|
||||
this.ipInfoCache.set(ip, {
|
||||
data: await resp,
|
||||
expires: new DateBuilder().addHours(12).buildTimestamp(),
|
||||
});
|
||||
return await resp;
|
||||
}
|
||||
|
||||
//TODO add function that support both ip and domain names
|
||||
static isProxy(data: IpDataIpLookupResponse) {
|
||||
if (!data || !data.asn || !data.threat) return false;
|
||||
if (data.asn.type !== "isp") return true;
|
||||
if (Object.values(data.threat).some((x) => x)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
79
src/util/util/networking/ipdata/IpDataSampleResponses.ts
Normal file
79
src/util/util/networking/ipdata/IpDataSampleResponses.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export type IpDataIpLookupResponse = typeof ipDataSampleIpLookupResponse;
|
||||
|
||||
const ipDataSampleIpLookupResponse = {
|
||||
ip: "",
|
||||
is_eu: true,
|
||||
city: "",
|
||||
region: "",
|
||||
region_code: "",
|
||||
country_name: "",
|
||||
country_code: "",
|
||||
continent_name: "",
|
||||
continent_code: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
postal: "",
|
||||
calling_code: "",
|
||||
flag: "",
|
||||
emoji_flag: "",
|
||||
emoji_unicode: "",
|
||||
asn: {
|
||||
asn: "",
|
||||
name: "",
|
||||
domain: "",
|
||||
route: "",
|
||||
type: "isp",
|
||||
},
|
||||
languages: [
|
||||
{
|
||||
name: "",
|
||||
native: "",
|
||||
},
|
||||
],
|
||||
currency: {
|
||||
name: "",
|
||||
code: "",
|
||||
symbol: "",
|
||||
native: "",
|
||||
plural: "",
|
||||
},
|
||||
time_zone: {
|
||||
name: "",
|
||||
abbr: "",
|
||||
offset: "",
|
||||
is_dst: true,
|
||||
current_time: "",
|
||||
},
|
||||
threat: {
|
||||
is_tor: false,
|
||||
is_icloud_relay: false,
|
||||
is_proxy: false,
|
||||
is_datacenter: false,
|
||||
is_anonymous: false,
|
||||
is_known_attacker: false,
|
||||
is_known_abuser: false,
|
||||
is_threat: false,
|
||||
is_bogon: false,
|
||||
blocklists: [],
|
||||
},
|
||||
count: 0,
|
||||
status: 200,
|
||||
};
|
||||
18
src/util/util/networking/ipdata/index.ts
Normal file
18
src/util/util/networking/ipdata/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export * from "./IpDataClient";
|
||||
Reference in New Issue
Block a user