setup unifi wlans
This commit is contained in:
@@ -14,6 +14,9 @@ export default createRoute(
|
||||
async (c) => {
|
||||
const company = await companies.fetch(c.req.param("identifier"));
|
||||
const includeAddress = c.req.query("includeAddress") === "true";
|
||||
const includePrimaryContact =
|
||||
c.req.query("includePrimaryContact") === "true";
|
||||
const includeAllContacts = c.req.query("includeAllContacts") === "true";
|
||||
|
||||
// Check for address-specific permission if includeAddress is requested
|
||||
if (includeAddress) {
|
||||
@@ -27,9 +30,25 @@ export default createRoute(
|
||||
}
|
||||
}
|
||||
|
||||
// Check for contacts permission if includeAllContacts is requested
|
||||
if (includeAllContacts) {
|
||||
const user = c.get("user");
|
||||
if (!user || !(await user.hasPermission("company.fetch.contacts"))) {
|
||||
throw new GenericError({
|
||||
name: "InsufficientPermission",
|
||||
message: "You do not have permission to view company contacts.",
|
||||
status: 403,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Company Fetched Successfully!",
|
||||
company.toJson({ includeAddress }),
|
||||
company.toJson({
|
||||
includeAddress,
|
||||
includePrimaryContact,
|
||||
includeAllContacts,
|
||||
}),
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||
import { unifiSites } from "../../../managers/unifiSites";
|
||||
import { companies } from "../../../managers/companies";
|
||||
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../../middleware/authorization";
|
||||
|
||||
/* GET /v1/company/companies/:identifier/unifi/sites */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/companies/:identifier/unifi/sites"],
|
||||
async (c) => {
|
||||
const company = await companies.fetch(c.req.param("identifier"));
|
||||
const sites = await unifiSites.fetchByCompany(company.id);
|
||||
const response = apiResponse.successful(
|
||||
"Company UniFi Sites Fetched Successfully!",
|
||||
sites,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "company.fetch"],
|
||||
}),
|
||||
);
|
||||
@@ -1,6 +1,7 @@
|
||||
import { default as fetchAll } from "./fetchAll";
|
||||
import { default as fetch } from "./[id]/fetch";
|
||||
import { default as configurations } from "./[id]/configurations";
|
||||
import { default as unifiSites } from "./[id]/unifiSites";
|
||||
import { default as count } from "./count";
|
||||
|
||||
export { configurations, count, fetch, fetchAll };
|
||||
export { configurations, count, fetch, fetchAll, unifiSites };
|
||||
|
||||
@@ -15,19 +15,22 @@ export default createRoute(
|
||||
async (c) => {
|
||||
const body = await c.req.json();
|
||||
|
||||
const fieldSchema: z.ZodType<any> = z.lazy(() =>
|
||||
z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
subFields: z.array(fieldSchema).optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
permissionScope: z.string().min(1, "Permission scope is required"),
|
||||
icon: z.string().optional(),
|
||||
fields: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
}),
|
||||
),
|
||||
fields: z.array(fieldSchema),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
@@ -16,21 +16,22 @@ export default createRoute(
|
||||
const body = await c.req.json();
|
||||
const credentialType = await credentialTypes.fetch(c.req.param("id"));
|
||||
|
||||
const fieldSchema: z.ZodType<any> = z.lazy(() =>
|
||||
z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
subFields: z.array(fieldSchema).optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().optional(),
|
||||
permissionScope: z.string().optional(),
|
||||
icon: z.string().optional(),
|
||||
fields: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
fields: z.array(fieldSchema).optional(),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { credentials } from "../../managers/credentials";
|
||||
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/credential/credentials/:id/sub-credentials */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/credentials/:id/sub-credentials"],
|
||||
|
||||
async (c) => {
|
||||
const parentId = c.req.param("id");
|
||||
const body = await c.req.json();
|
||||
|
||||
const schema = z.object({
|
||||
fieldId: z.string().min(1, "Field ID is required"),
|
||||
name: z.string().min(1, "Name is required"),
|
||||
fields: z.array(
|
||||
z.object({
|
||||
fieldId: z.string(),
|
||||
value: z.string(),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
const subCredential = await credentials.addSubCredential(
|
||||
parentId,
|
||||
data.fieldId,
|
||||
{
|
||||
name: data.name,
|
||||
fields: data.fields,
|
||||
},
|
||||
);
|
||||
|
||||
const response = apiResponse.created(
|
||||
"Sub-Credential Created Successfully!",
|
||||
subCredential.toJson(),
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["credential.fetch", "credential.sub_credentials.create"],
|
||||
}),
|
||||
);
|
||||
@@ -25,6 +25,22 @@ export default createRoute(
|
||||
value: z.string(),
|
||||
}),
|
||||
),
|
||||
subCredentials: z
|
||||
.record(
|
||||
z.string(),
|
||||
z.array(
|
||||
z.object({
|
||||
name: z.string().min(1, "Sub-credential name is required"),
|
||||
fields: z.array(
|
||||
z.object({
|
||||
fieldId: z.string(),
|
||||
value: z.string(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { credentials } from "../../managers/credentials";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
|
||||
/* GET /v1/credential/credentials/:id/sub-credentials */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/credentials/:id/sub-credentials"],
|
||||
|
||||
async (c) => {
|
||||
const parentId = c.req.param("id");
|
||||
|
||||
// Verify the parent credential exists
|
||||
await credentials.fetch(parentId);
|
||||
|
||||
const subCredentials = await credentials.fetchSubCredentials(parentId);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Sub-Credentials Fetched Successfully!",
|
||||
subCredentials.map((sc) => sc.toJson()),
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["credential.fetch", "credential.sub_credentials.fetch"],
|
||||
}),
|
||||
);
|
||||
@@ -8,6 +8,9 @@ import { default as readSecureValues } from "./readSecureValues";
|
||||
import { default as readSecureValue } from "./readSecureValue";
|
||||
import { default as deleteCredential } from "./delete";
|
||||
import { default as valueTypes } from "./valueTypes";
|
||||
import { default as fetchSubCredentials } from "./fetchSubCredentials";
|
||||
import { default as addSubCredential } from "./addSubCredential";
|
||||
import { default as removeSubCredential } from "./removeSubCredential";
|
||||
|
||||
export {
|
||||
valueTypes,
|
||||
@@ -20,4 +23,7 @@ export {
|
||||
readSecureValues,
|
||||
readSecureValue,
|
||||
deleteCredential as delete,
|
||||
fetchSubCredentials,
|
||||
addSubCredential,
|
||||
removeSubCredential,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { credentials } from "../../managers/credentials";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
|
||||
/* DELETE /v1/credential/credentials/:id/sub-credentials/:subId */
|
||||
export default createRoute(
|
||||
"delete",
|
||||
["/credentials/:id/sub-credentials/:subId"],
|
||||
|
||||
async (c) => {
|
||||
const parentId = c.req.param("id");
|
||||
const subId = c.req.param("subId");
|
||||
|
||||
await credentials.removeSubCredential(parentId, subId);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Sub-Credential Removed Successfully!",
|
||||
null,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["credential.fetch", "credential.sub_credentials.delete"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Hono } from "hono";
|
||||
import * as unifiRoutes from "../unifi";
|
||||
|
||||
const unifiRouter = new Hono();
|
||||
Object.values(unifiRoutes).map((r) => unifiRouter.route("/", r));
|
||||
|
||||
export default unifiRouter;
|
||||
@@ -54,6 +54,7 @@ v1.route("/credential", require("./routers/credentialRouter").default);
|
||||
v1.route("/credential-type", require("./routers/credentialTypeRouter").default);
|
||||
v1.route("/role", require("./routers/roleRouter").default);
|
||||
v1.route("/permissions", require("./routers/permissionRouter").default);
|
||||
v1.route("/unifi", require("./routers/unifiRouter").default);
|
||||
app.route("/v1", v1);
|
||||
|
||||
export default app;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { default as fetchAllSites } from "./sites/fetchAll";
|
||||
import { default as syncSites } from "./sites/sync";
|
||||
import { default as createSite } from "./sites/create";
|
||||
import { default as fetchSite } from "./site/fetch";
|
||||
import { default as siteOverview } from "./site/overview";
|
||||
import { default as siteDevices } from "./site/devices";
|
||||
import { default as siteNetworks } from "./site/networks";
|
||||
import { default as siteWifiFetchAll } from "./site/wifi/fetchAll";
|
||||
import { default as siteWifiUpdate } from "./site/wifi/update";
|
||||
import { default as siteWifiPpskFetchAll } from "./site/wifi/ppskFetchAll";
|
||||
import { default as siteWifiPpskCreate } from "./site/wifi/ppskCreate";
|
||||
import { default as siteLink } from "./site/link";
|
||||
import { default as siteUnlink } from "./site/unlink";
|
||||
import { default as siteWlanGroups } from "./site/wlanGroups";
|
||||
import { default as siteWlanGroupsCreate } from "./site/wlanGroupsCreate";
|
||||
import { default as siteAccessPoints } from "./site/accessPoints";
|
||||
import { default as siteApGroups } from "./site/apGroups";
|
||||
import { default as siteWifiLimits } from "./site/wifiLimits";
|
||||
import { default as siteSpeedProfilesFetchAll } from "./site/speedProfilesFetchAll";
|
||||
import { default as siteSpeedProfilesCreate } from "./site/speedProfilesCreate";
|
||||
|
||||
export {
|
||||
fetchAllSites,
|
||||
syncSites,
|
||||
createSite,
|
||||
fetchSite,
|
||||
siteOverview,
|
||||
siteDevices,
|
||||
siteNetworks,
|
||||
siteWifiFetchAll,
|
||||
siteWifiUpdate,
|
||||
siteWifiPpskFetchAll,
|
||||
siteWifiPpskCreate,
|
||||
siteLink,
|
||||
siteUnlink,
|
||||
siteWlanGroups,
|
||||
siteWlanGroupsCreate,
|
||||
siteAccessPoints,
|
||||
siteApGroups,
|
||||
siteWifiLimits,
|
||||
siteSpeedProfilesFetchAll,
|
||||
siteSpeedProfilesCreate,
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
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/access-points */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/access-points"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const accessPoints = await unifiSites.getAccessPoints(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Access Points Fetched Successfully!",
|
||||
accessPoints,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.access-points"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
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/ap-groups */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/ap-groups"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const apGroups = await unifiSites.getApGroups(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi AP Groups Fetched Successfully!",
|
||||
apGroups,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.ap-groups"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
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/devices */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/devices"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const devices = await unifiSites.getDevices(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Devices Fetched Successfully!",
|
||||
devices,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.site.devices"] }),
|
||||
);
|
||||
@@ -0,0 +1,20 @@
|
||||
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 */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Site Fetched Successfully!",
|
||||
site,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.fetch"] }),
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
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/link */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/site/:id/link"],
|
||||
async (c) => {
|
||||
const siteId = c.req.param("id");
|
||||
const body = await c.req.json();
|
||||
const schema = z.object({ companyId: z.string() }).strict();
|
||||
const { companyId } = schema.parse(body);
|
||||
|
||||
const site = await unifiSites.linkToCompany(siteId, companyId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Site Linked to Company Successfully!",
|
||||
site,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.link"] }),
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
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/networks */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/networks"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const networks = await unifiSites.getNetworks(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Networks Fetched Successfully!",
|
||||
networks,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.site.networks"] }),
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
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/overview */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/overview"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const overview = await unifiSites.getSiteOverview(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Site Overview Fetched Successfully!",
|
||||
overview,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.site.overview"] }),
|
||||
);
|
||||
@@ -0,0 +1,40 @@
|
||||
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/speed-profiles */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/site/:id/speed-profiles"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
|
||||
const body = await c.req.json();
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
downloadLimitKbps: z.number().optional(),
|
||||
uploadLimitKbps: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const parsed = schema.parse(body);
|
||||
const profile = await unifiSites.createUserGroup(site.siteId, parsed);
|
||||
|
||||
const response = apiResponse.created(
|
||||
"UniFi Speed Profile Created Successfully!",
|
||||
profile,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: [
|
||||
"unifi.access",
|
||||
"unifi.site.speed-profiles",
|
||||
"unifi.site.speed-profiles.create",
|
||||
],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
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/speed-profiles */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/speed-profiles"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const profiles = await unifiSites.getUserGroups(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Speed Profiles Fetched Successfully!",
|
||||
profiles,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.speed-profiles"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
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";
|
||||
|
||||
/* POST /v1/unifi/site/:id/unlink */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/site/:id/unlink"],
|
||||
async (c) => {
|
||||
const siteId = c.req.param("id");
|
||||
const site = await unifiSites.unlinkFromCompany(siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Site Unlinked from Company Successfully!",
|
||||
site,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.link"] }),
|
||||
);
|
||||
@@ -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"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
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-limits */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/wifi-limits"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const limits = await unifiSites.getWifiLimits(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi WiFi Limits Fetched Successfully!",
|
||||
limits,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.wifi-limits"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
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/wlan-groups */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/site/:id/wlan-groups"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
const wlanGroups = await unifiSites.getWlanGroups(site.siteId);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi WLAN Groups Fetched Successfully!",
|
||||
wlanGroups,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["unifi.access", "unifi.site.wlan-groups"],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,38 @@
|
||||
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/wlan-groups */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/site/:id/wlan-groups"],
|
||||
async (c) => {
|
||||
const site = await unifiSites.fetch(c.req.param("id"));
|
||||
|
||||
const body = await c.req.json();
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const parsed = schema.parse(body);
|
||||
const group = await unifiSites.createWlanGroup(site.siteId, parsed);
|
||||
|
||||
const response = apiResponse.created(
|
||||
"UniFi WLAN Group Created Successfully!",
|
||||
group,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: [
|
||||
"unifi.access",
|
||||
"unifi.site.wlan-groups",
|
||||
"unifi.site.wlan-groups.create",
|
||||
],
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,25 @@
|
||||
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/sites/create */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/sites/create"],
|
||||
async (c) => {
|
||||
const body = await c.req.json();
|
||||
const schema = z.object({ description: z.string().min(1) }).strict();
|
||||
const { description } = schema.parse(body);
|
||||
|
||||
const site = await unifiSites.createSite(description);
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Site Created Successfully!",
|
||||
site,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.create"] }),
|
||||
);
|
||||
@@ -0,0 +1,20 @@
|
||||
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/sites */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/sites"],
|
||||
async (c) => {
|
||||
const sites = await unifiSites.fetchAll();
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Sites Fetched Successfully!",
|
||||
sites,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.fetch.many"] }),
|
||||
);
|
||||
@@ -0,0 +1,20 @@
|
||||
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";
|
||||
|
||||
/* POST /v1/unifi/sites/sync */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/sites/sync"],
|
||||
async (c) => {
|
||||
const sites = await unifiSites.syncSites();
|
||||
const response = apiResponse.successful(
|
||||
"UniFi Sites Synced Successfully!",
|
||||
sites,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["unifi.access", "unifi.sites.sync"] }),
|
||||
);
|
||||
Reference in New Issue
Block a user