Version
This commit is contained in:
+54
-41
@@ -1,6 +1,7 @@
|
||||
import { prisma, unifi, unifiUsername, unifiPassword } from "../constants";
|
||||
import GenericError from "../Errors/GenericError";
|
||||
import { UnifiSite } from "../../generated/prisma/client";
|
||||
import { events } from "../modules/globalEvents";
|
||||
|
||||
let loggedIn = false;
|
||||
|
||||
@@ -16,6 +17,24 @@ async function ensureLoggedIn(): Promise<void> {
|
||||
loggedIn = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a UniFi API call with automatic re-authentication on failure.
|
||||
* If the call fails and we were previously logged in (i.e. session likely
|
||||
* expired), resets the login state, re-authenticates, and retries once.
|
||||
*/
|
||||
async function withReauth<T>(fn: () => Promise<T>): Promise<T> {
|
||||
await ensureLoggedIn();
|
||||
try {
|
||||
return await fn();
|
||||
} catch (e) {
|
||||
if (!loggedIn) throw e;
|
||||
events.emit("unifi:reauth");
|
||||
loggedIn = false;
|
||||
await ensureLoggedIn();
|
||||
return fn();
|
||||
}
|
||||
}
|
||||
|
||||
export const unifiSites = {
|
||||
/**
|
||||
* Fetch a UniFi site record from the database by its internal ID.
|
||||
@@ -96,12 +115,14 @@ export const unifiSites = {
|
||||
* Creates new records for sites not yet tracked, updates names for existing ones.
|
||||
*/
|
||||
async syncSites(): Promise<UnifiSite[]> {
|
||||
await ensureLoggedIn();
|
||||
events.emit("unifi:sites:sync:started");
|
||||
|
||||
// Fetch all sites from the controller
|
||||
const allSites = await unifi.getAllSites();
|
||||
const allSites = await withReauth(() => unifi.getAllSites());
|
||||
|
||||
const results: UnifiSite[] = [];
|
||||
let created = 0;
|
||||
let updated = 0;
|
||||
|
||||
for (const site of allSites) {
|
||||
const existing = await prisma.unifiSite.findFirst({
|
||||
@@ -109,22 +130,30 @@ export const unifiSites = {
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
const updated = await prisma.unifiSite.update({
|
||||
const updatedSite = await prisma.unifiSite.update({
|
||||
where: { id: existing.id },
|
||||
data: { name: site.description },
|
||||
});
|
||||
results.push(updated);
|
||||
results.push(updatedSite);
|
||||
updated++;
|
||||
} else {
|
||||
const created = await prisma.unifiSite.create({
|
||||
const createdSite = await prisma.unifiSite.create({
|
||||
data: {
|
||||
name: site.description,
|
||||
siteId: site.name,
|
||||
},
|
||||
});
|
||||
results.push(created);
|
||||
results.push(createdSite);
|
||||
created++;
|
||||
}
|
||||
}
|
||||
|
||||
events.emit("unifi:sites:sync:completed", {
|
||||
total: results.length,
|
||||
created,
|
||||
updated,
|
||||
});
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
@@ -132,24 +161,21 @@ export const unifiSites = {
|
||||
* Get live site overview from the UniFi controller.
|
||||
*/
|
||||
async getSiteOverview(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getSiteOverview(siteId);
|
||||
return withReauth(() => unifi.getSiteOverview(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get live devices from the UniFi controller for a site.
|
||||
*/
|
||||
async getDevices(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getDevices(siteId);
|
||||
return withReauth(() => unifi.getDevices(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get live WiFi networks (WLANs) from the UniFi controller for a site.
|
||||
*/
|
||||
async getWlanConf(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getWlanConf(siteId);
|
||||
return withReauth(() => unifi.getWlanConf(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -160,25 +186,21 @@ export const unifiSites = {
|
||||
wlanId: string,
|
||||
updates: Parameters<typeof unifi.updateWlanConf>[2],
|
||||
) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.updateWlanConf(siteId, wlanId, updates);
|
||||
return withReauth(() => unifi.updateWlanConf(siteId, wlanId, updates));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get live network configurations from the UniFi controller for a site.
|
||||
*/
|
||||
async getNetworks(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getNetworks(siteId);
|
||||
return withReauth(() => unifi.getNetworks(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new site on the UniFi controller and track it in the database.
|
||||
*/
|
||||
async createSite(description: string): Promise<UnifiSite> {
|
||||
await ensureLoggedIn();
|
||||
|
||||
const created = await unifi.createSite(description);
|
||||
const created = await withReauth(() => unifi.createSite(description));
|
||||
|
||||
return prisma.unifiSite.create({
|
||||
data: {
|
||||
@@ -192,8 +214,7 @@ export const unifiSites = {
|
||||
* Get WLAN groups from the UniFi controller for a site.
|
||||
*/
|
||||
async getWlanGroups(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getWlanGroups(siteId);
|
||||
return withReauth(() => unifi.getWlanGroups(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -203,16 +224,14 @@ export const unifiSites = {
|
||||
siteId: string,
|
||||
input: Parameters<typeof unifi.createWlanGroup>[1],
|
||||
) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.createWlanGroup(siteId, input);
|
||||
return withReauth(() => unifi.createWlanGroup(siteId, input));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get user groups (speed profiles) from the UniFi controller for a site.
|
||||
*/
|
||||
async getUserGroups(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getUserGroups(siteId);
|
||||
return withReauth(() => unifi.getUserGroups(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -222,16 +241,14 @@ export const unifiSites = {
|
||||
siteId: string,
|
||||
input: Parameters<typeof unifi.createUserGroup>[1],
|
||||
) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.createUserGroup(siteId, input);
|
||||
return withReauth(() => unifi.createUserGroup(siteId, input));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get AP groups from the UniFi controller for a site.
|
||||
*/
|
||||
async getApGroups(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getApGroups(siteId);
|
||||
return withReauth(() => unifi.getApGroups(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -243,40 +260,37 @@ export const unifiSites = {
|
||||
deviceMacs: string[],
|
||||
forWlanconf: boolean = false,
|
||||
) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.createApGroup(siteId, name, deviceMacs, forWlanconf);
|
||||
return withReauth(() =>
|
||||
unifi.createApGroup(siteId, name, deviceMacs, forWlanconf),
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update an existing AP group's device MACs on the UniFi controller.
|
||||
*/
|
||||
async updateApGroup(siteId: string, groupId: string, deviceMacs: string[]) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.updateApGroup(siteId, groupId, deviceMacs);
|
||||
return withReauth(() => unifi.updateApGroup(siteId, groupId, deviceMacs));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get access points only from the UniFi controller for a site.
|
||||
*/
|
||||
async getAccessPoints(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getAccessPoints(siteId);
|
||||
return withReauth(() => unifi.getAccessPoints(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get WiFi SSID limits per AP per radio band.
|
||||
*/
|
||||
async getWifiLimits(siteId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getWifiLimits(siteId);
|
||||
return withReauth(() => unifi.getWifiLimits(siteId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get private pre-shared keys for a specific WLAN.
|
||||
*/
|
||||
async getPrivatePSKs(siteId: string, wlanId: string) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.getPrivatePSKs(siteId, wlanId);
|
||||
return withReauth(() => unifi.getPrivatePSKs(siteId, wlanId));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -287,7 +301,6 @@ export const unifiSites = {
|
||||
wlanId: string,
|
||||
psk: Parameters<typeof unifi.createPrivatePSK>[2],
|
||||
) {
|
||||
await ensureLoggedIn();
|
||||
return unifi.createPrivatePSK(siteId, wlanId, psk);
|
||||
return withReauth(() => unifi.createPrivatePSK(siteId, wlanId, psk));
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user