134 lines
3.9 KiB
TypeScript
134 lines
3.9 KiB
TypeScript
// Test script to probe UniFi API endpoints for response shapes
|
|
import axios, { AxiosInstance } from "axios";
|
|
|
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
|
|
const controllerBaseUrl = "https://unifi.totaltech.net";
|
|
const site = "km9b1v8i";
|
|
const username = "admin";
|
|
const password = "Tt$Un1fiIZth3B3$t26";
|
|
|
|
class TestClient {
|
|
private client: AxiosInstance;
|
|
|
|
constructor(baseURL: string) {
|
|
this.client = axios.create({
|
|
baseURL,
|
|
validateStatus: (s) => s >= 200 && s < 400,
|
|
});
|
|
}
|
|
|
|
private persistSession(res: { headers: Record<string, unknown> }): void {
|
|
const raw = res.headers["set-cookie"];
|
|
if (raw) {
|
|
const cookies = (Array.isArray(raw) ? raw : [raw]) as string[];
|
|
const cookieString = cookies.map((c) => c.split(";")[0]).join("; ");
|
|
this.client.defaults.headers.common["Cookie"] = cookieString;
|
|
}
|
|
const csrf = res.headers["x-csrf-token"];
|
|
if (typeof csrf === "string") {
|
|
this.client.defaults.headers.common["X-CSRF-Token"] = csrf;
|
|
}
|
|
}
|
|
|
|
async login(): Promise<void> {
|
|
try {
|
|
const res = await this.client.post("/api/auth/login", {
|
|
username,
|
|
password,
|
|
});
|
|
console.log("Login OK (UniFi OS)", res.status);
|
|
this.persistSession(res);
|
|
} catch (e) {
|
|
const res = await this.client.post("/api/login", { username, password });
|
|
console.log("Login OK (legacy)", res.status);
|
|
this.persistSession(res);
|
|
}
|
|
}
|
|
|
|
async tryGet(label: string, paths: string[]): Promise<any> {
|
|
for (const path of paths) {
|
|
try {
|
|
const res = await this.client.get(path);
|
|
const data = res.data?.data ?? res.data;
|
|
console.log(`\n=== ${label} (${path}) ===`);
|
|
console.log(JSON.stringify(data, null, 2));
|
|
return data;
|
|
} catch (e: any) {
|
|
console.log(` Failed ${path}: ${e.response?.status ?? e.message}`);
|
|
}
|
|
}
|
|
console.log(` Could not fetch ${label} from any path`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const client = new TestClient(controllerBaseUrl);
|
|
await client.login();
|
|
|
|
// 1. WLAN Groups (AP groups in UniFi)
|
|
await client.tryGet("WLAN Groups", [
|
|
`/proxy/network/api/s/${site}/rest/wlangroup`,
|
|
`/api/s/${site}/rest/wlangroup`,
|
|
]);
|
|
|
|
// 2. User Groups (bandwidth/speed limit profiles)
|
|
await client.tryGet("User Groups (Speed Profiles)", [
|
|
`/proxy/network/api/s/${site}/rest/usergroup`,
|
|
`/api/s/${site}/rest/usergroup`,
|
|
]);
|
|
|
|
// 3. Devices - APs only (compact)
|
|
const devices = await client.tryGet("Devices", [
|
|
`/proxy/network/api/s/${site}/stat/device`,
|
|
]);
|
|
if (devices) {
|
|
const aps = devices.filter((d: any) => d.type === "uap");
|
|
console.log(`\n=== APs (${aps.length}) - compact ===`);
|
|
aps.forEach((ap: any) => {
|
|
console.log(
|
|
JSON.stringify({
|
|
_id: ap._id,
|
|
name: ap.name,
|
|
mac: ap.mac,
|
|
model: ap.model,
|
|
radio_table: ap.radio_table?.map((r: any) => ({
|
|
radio: r.radio,
|
|
name: r.name,
|
|
})),
|
|
wlangroup_id_ng: ap.wlangroup_id_ng,
|
|
wlangroup_id_na: ap.wlangroup_id_na,
|
|
vap_table_count: ap.vap_table?.length,
|
|
}),
|
|
);
|
|
});
|
|
}
|
|
|
|
// 4. One full WLAN to see private_preshared_keys structure
|
|
const wlans = await client.tryGet("WLANs", [
|
|
`/proxy/network/api/s/${site}/rest/wlanconf`,
|
|
]);
|
|
if (wlans) {
|
|
// Log just the PPSK-related fields from each WLAN
|
|
console.log("\n=== PPSK fields per WLAN ===");
|
|
wlans.forEach((w: any) => {
|
|
console.log(
|
|
JSON.stringify({
|
|
name: w.name,
|
|
_id: w._id,
|
|
private_preshared_keys_enabled: w.private_preshared_keys_enabled,
|
|
private_preshared_keys: w.private_preshared_keys,
|
|
ap_group_ids: w.ap_group_ids,
|
|
ap_group_mode: w.ap_group_mode,
|
|
wlan_band: w.wlan_band,
|
|
wlan_bands: w.wlan_bands,
|
|
usergroup_id: w.usergroup_id,
|
|
}),
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
main().catch((e) => console.error(e));
|