setup unifi wlans
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
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 { processObjectValuePerms } from "../../../../modules/permission-utils/processObjectPermissions";
|
||||
|
||||
/* GET /v1/unifi/site/:id/wifi */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/wifi"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const wlans = await unifiSites.getWlanConf(site.siteId);
|
||||
|
||||
const processWlans = await Promise.all(
|
||||
wlans.map((wlan) =>
|
||||
processObjectValuePerms(wlan, "unifi.site.wifi.read", c.get("user")),
|
||||
),
|
||||
);
|
||||
|
||||
console.log(processWlans);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"UniFi WiFi Networks Fetched Successfully!",
|
||||
processWlans,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.site.wifi"] }),
|
||||
);
|
||||
@@ -0,0 +1,47 @@
|
||||
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 { z } from "zod";
|
||||
|
||||
/* POST /v1/unifi/site/:id/wifi/:wlanId/ppsk */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/site/:id/wifi/:wlanId/ppsk"],
|
||||
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({
|
||||
key: z.string().min(8, "PSK must be at least 8 characters"),
|
||||
name: z.string().min(1, "Name is required"),
|
||||
mac: z.string().optional(),
|
||||
vlanId: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const parsed = schema.parse(body);
|
||||
const ppsks = await unifiSites.createPrivatePSK(
|
||||
site.siteId,
|
||||
wlanId,
|
||||
parsed,
|
||||
);
|
||||
|
||||
const response = apiResponse.created(
|
||||
"UniFi Private PSK Created Successfully!",
|
||||
ppsks,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: [
|
||||
"unifi.access",
|
||||
"unifi.site.wifi",
|
||||
"unifi.site.wifi.ppsk",
|
||||
"unifi.site.wifi.ppsk.create",
|
||||
],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
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";
|
||||
|
||||
/* GET /v1/unifi/site/:id/wifi/:wlanId/ppsk */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/wifi/:wlanId/ppsk"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const wlanId = c.req.param("wlanId");
|
||||
const ppsks = await unifiSites.getPrivatePSKs(site.siteId, wlanId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Private PSKs Fetched Successfully!",
|
||||
ppsks,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.wifi", "unifi.site.wifi.ppsk"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,117 @@
|
||||
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"],
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user