118 lines
4.5 KiB
TypeScript
118 lines
4.5 KiB
TypeScript
import { createRoute } from "../../../../modules/api-utils/createRoute";
|
|
import { unifiSites } from "../../../../managers/unifiSites";
|
|
import { apiResponse } from "../../../../modules/api-utils/apiResponse";
|
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
|
import { authMiddleware } from "../../../middleware/authorization";
|
|
import { toWlanConfUpdate } from "../../../../modules/unifi-api/unifiTypes";
|
|
import { z } from "zod";
|
|
|
|
/* PATCH /v1/unifi/site/:id/wifi/:wlanId */
|
|
export default createRoute(
|
|
"patch",
|
|
["/site/:id/wifi/:wlanId"],
|
|
async (c) => {
|
|
const site = await unifiSites.fetch(c.req.param("id"));
|
|
const wlanId = c.req.param("wlanId");
|
|
|
|
const body = await c.req.json();
|
|
const schema = z
|
|
.object({
|
|
name: z.string().optional(),
|
|
passphrase: z.string().optional(),
|
|
enabled: z.boolean().optional(),
|
|
security: z.enum(["wpapsk", "wpaeap", "open", "osen"]).optional(),
|
|
wpaMode: z.enum(["wpa2", "wpa3", "wpa2wpa3"]).optional(),
|
|
wpaEnc: z.enum(["ccmp", "gcmp", "ccmp-gcmp"]).optional(),
|
|
hideSSID: z.boolean().optional(),
|
|
macFilterEnabled: z.boolean().optional(),
|
|
macFilterPolicy: z.enum(["allow", "deny"]).optional(),
|
|
isGuest: z.boolean().optional(),
|
|
l2Isolation: z.boolean().optional(),
|
|
fastRoamingEnabled: z.boolean().optional(),
|
|
bssTransition: z.boolean().optional(),
|
|
uapsdEnabled: z.boolean().optional(),
|
|
groupRekey: z.number().optional(),
|
|
dtimMode: z.enum(["default", "custom"]).optional(),
|
|
dtimNg: z.number().optional(),
|
|
dtimNa: z.number().optional(),
|
|
minrateNgEnabled: z.boolean().optional(),
|
|
minrateNaEnabled: z.boolean().optional(),
|
|
radiusDasEnabled: z.boolean().optional(),
|
|
radiusMacAuthEnabled: z.boolean().optional(),
|
|
pmfMode: z.enum(["disabled", "optional", "required"]).optional(),
|
|
band: z.enum(["both", "2g", "5g"]).optional(),
|
|
usergroupId: z.string().optional(),
|
|
proxyArp: z.boolean().optional(),
|
|
mcastenhanceEnabled: z.boolean().optional(),
|
|
macFilterList: z.array(z.string()).optional(),
|
|
no2ghzOui: z.boolean().optional(),
|
|
apGroupIds: z.array(z.string()).optional(),
|
|
apGroupMode: z.enum(["all", "groups", "devices"]).optional(),
|
|
deviceMacs: z.array(z.string()).optional(),
|
|
})
|
|
.strict();
|
|
|
|
const parsed = schema.parse(body);
|
|
|
|
// If deviceMacs is provided, manage the devices_ap_group:
|
|
// - If already in devices mode with a for_wlanconf group, update that group
|
|
// - Otherwise create a new for_wlanconf group and switch to devices mode
|
|
if (parsed.deviceMacs && parsed.deviceMacs.length > 0) {
|
|
const wlans = await unifiSites.getWlanConf(site.siteId);
|
|
const currentWlan = wlans.find((w) => w.id === wlanId);
|
|
|
|
let existingGroupId: string | undefined;
|
|
if (
|
|
currentWlan?.apGroupMode === "devices" &&
|
|
currentWlan.apGroupIds.length > 0
|
|
) {
|
|
// Check if the current group is a for_wlanconf group we can update
|
|
const apGroups = await unifiSites.getApGroups(site.siteId);
|
|
const currentGroup = apGroups.find(
|
|
(g) => g.id === currentWlan.apGroupIds[0] && g.forWlanconf,
|
|
);
|
|
if (currentGroup) existingGroupId = currentGroup.id;
|
|
}
|
|
|
|
if (existingGroupId) {
|
|
// Update the existing for_wlanconf group's device list
|
|
await unifiSites.updateApGroup(
|
|
site.siteId,
|
|
existingGroupId,
|
|
parsed.deviceMacs,
|
|
);
|
|
parsed.apGroupMode = "devices";
|
|
parsed.apGroupIds = [existingGroupId];
|
|
} else {
|
|
// Create a new for_wlanconf group
|
|
const apGroup = await unifiSites.createApGroup(
|
|
site.siteId,
|
|
"devices_ap_group",
|
|
parsed.deviceMacs,
|
|
true, // for_wlanconf must be true for devices mode
|
|
);
|
|
parsed.apGroupMode = "devices";
|
|
parsed.apGroupIds = [apGroup.id];
|
|
}
|
|
}
|
|
|
|
// Remove deviceMacs before converting — it's not a UniFi field
|
|
const { deviceMacs: _, ...updateInput } = parsed;
|
|
const updates = toWlanConfUpdate(updateInput);
|
|
|
|
const result = await unifiSites.updateWlanConf(
|
|
site.siteId,
|
|
wlanId,
|
|
updates,
|
|
);
|
|
const response = apiResponse.successful(
|
|
"UniFi WiFi Network Updated Successfully!",
|
|
result,
|
|
);
|
|
return c.json(response, response.status as ContentfulStatusCode);
|
|
},
|
|
authMiddleware({
|
|
permissions: ["unifi.access", "unifi.site.wifi", "unifi.site.wifi.update"],
|
|
}),
|
|
);
|