forked from AlchemillaHQ/adguard-client-updater
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
100 lines (81 loc) · 2.88 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import dotenv from 'dotenv';
import { neigh } from 'ip-wrapper';
import { arraysEqual, isMacAddress, isIp } from './utils.js';
dotenv.config();
const staleIPs = {}; // Object to track stale IPs with TTL
const adguardConfig = {
api: process.env.ADGUARD_API || 'http://127.0.0.1:3000',
username: process.env.ADGUARD_USERNAME || 'admin',
password: process.env.ADGUARD_PASSWORD || 'password'
};
const API_ENDPOINTS = {
CLIENTS: '/control/clients',
CLIENTS_UPDATE: '/control/clients/update'
};
async function adguardFetch(endpoint, method, body) {
try {
const response = await fetch(`http://${adguardConfig.api}${endpoint}`, {
method,
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + Buffer.from(`${adguardConfig.username}:${adguardConfig.password}`).toString('base64')
},
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.text()
} catch (error) {
console.log(error);
throw error;
}
}
async function updateClients() {
try {
let [neighbors, existingClients] = await Promise.all([
neigh.show(),
adguardFetch(API_ENDPOINTS.CLIENTS, 'GET')
]);
existingClients = JSON.parse(existingClients);
const neighborIPsByMAC = neighbors.reduce((acc, neighbor) => {
if (neighbor.lladdr && neighbor.dst) {
acc[neighbor.lladdr] = (acc[neighbor.lladdr] || []);
acc[neighbor.lladdr].push(neighbor.dst);
}
return acc;
}, {});
const clientUpdates = existingClients.clients.map(async (client) => {
const macAddresses = client.ids.filter(id => isMacAddress(id));
if (macAddresses.length === 0) return
const originalClientIps = client.ids.filter(id => isIp(id));
let ipsForClient = [];
macAddresses.forEach(mac => {
if (neighborIPsByMAC[mac]) {
ipsForClient = [...ipsForClient, ...neighborIPsByMAC[mac]];
}
});
const updatedIds = [...new Set([...ipsForClient])];
if (!arraysEqual(originalClientIps, updatedIds)) {
client.ids = [...new Set([...client.ids.filter(id => !isIp(id))]), ...updatedIds];
const updateObj = {
name: client.name,
data: client
};
console.log(`Updating client ${client.name} with new IDs: ${updatedIds}`);
return adguardFetch(API_ENDPOINTS.CLIENTS_UPDATE, 'POST', updateObj);
}
});
const results = await Promise.allSettled(clientUpdates);
results.forEach(result => {
if (result.status === 'rejected') {
console.error('Error updating client', result.reason);
}
});
} catch (error) {
console.error('Unable to update AdGuard clients', error.message);
}
}
console.log('Started AdGuard client updater\n-----------------------------');
await updateClients();
setInterval(updateClients, 60000);