Skip to content

Commit

Permalink
Upgraded VPN blocker with self-clearing cache.
Browse files Browse the repository at this point in the history
  • Loading branch information
vck3000 committed Jan 26, 2024
1 parent 8b8579d commit 10d5934
Showing 1 changed file with 48 additions and 5 deletions.
53 changes: 48 additions & 5 deletions src/util/vpnDetection.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,65 @@
import { RequestHandler } from 'express';

const VPN_TIMEOUT = 1000 * 60 * 60 * 12; // 12 hours

let whitelistedUsernames: string[] = [];
if (process.env.WHITELISTED_VPN_USERNAMES) {
whitelistedUsernames = process.env.WHITELISTED_VPN_USERNAMES.split(',');
}

const vpnCache: Map<string, boolean> = new Map();
class VpnEntry {
// Default it to True in case it fails.
private isVpn = true;
private isSet = false;
private timeCreated: Date;

constructor(timeCreated: Date) {
this.timeCreated = timeCreated;
}

isTimedOut(newTime: Date): boolean {
// + on a date object implicitly casts it to a number
const timeDiffMillis = +newTime - +this.timeCreated;

return timeDiffMillis > VPN_TIMEOUT;
}

getIsVpn(): boolean {
return this.isVpn;
}

setIsVpn(isVpn: boolean): void {
if (this.isSet) {
throw new Error(
'VpnEntry has already been set. Should not never be set again.',
);
}

this.isVpn = isVpn;
this.isSet = true;
}
}

type IP = string;

const vpnCache: Map<IP, VpnEntry> = new Map();

const isVPN = async (ip: string): Promise<boolean> => {
// Temporarily disable VPN checking
return false;

if (vpnCache.has(ip)) {
return vpnCache.get(ip);
// Clear the cache entry if it's timed out.
if (vpnCache.get(ip).isTimedOut(new Date())) {
vpnCache.delete(ip);
}
// Otherwise we have a valid entry. Directly return.
else {
return vpnCache.get(ip).getIsVpn();
}
}

// Default it to True in case it fails.
vpnCache.set(ip, true);
vpnCache.set(ip, new VpnEntry(new Date()));
console.log(`Checking VPN status of ip: ${ip}`);
console.log(`VPN Cache size: ${vpnCache.size}`);

Expand All @@ -35,7 +78,7 @@ const isVPN = async (ip: string): Promise<boolean> => {

const result: boolean = data.security.vpn;

vpnCache.set(ip, result);
vpnCache.get(ip).setIsVpn(result);

return result;
};
Expand Down

0 comments on commit 10d5934

Please sign in to comment.