You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
2.0 KiB
65 lines
2.0 KiB
import PromiseRouter from "express-promise-router"; |
|
|
|
import ApiError from "@common/ApiError"; |
|
import { ErrorCode } from "@common/ErrorCode"; |
|
import { DEVICE_PREFIX } from "@common/sprinklersRpc/mqtt"; |
|
import { DeviceToken, SuperuserToken } from "@common/TokenClaims"; |
|
import { verifyToken } from "@server/authentication"; |
|
import { ServerState } from "@server/state"; |
|
|
|
export const SUPERUSER = "sprinklers3"; |
|
|
|
export function mosquitto(state: ServerState) { |
|
const router = PromiseRouter(); |
|
|
|
router.post("/auth", async (req, res) => { |
|
const body = req.body; |
|
const { username, password, topic, acc } = body; |
|
if (typeof username !== "string" || typeof password !== "string") { |
|
throw new ApiError( |
|
"Must specify a username and password", |
|
ErrorCode.BadRequest |
|
); |
|
} |
|
if (username === SUPERUSER) { |
|
await verifyToken<SuperuserToken>(password, "superuser"); |
|
return res.status(200).send({ username }); |
|
} |
|
const claims = await verifyToken<DeviceToken>(password, "device"); |
|
if (claims.aud !== username) { |
|
throw new ApiError("Username does not match token", ErrorCode.BadRequest); |
|
} |
|
res.status(200).send({ |
|
username, |
|
id: claims.id |
|
}); |
|
}); |
|
|
|
router.post("/superuser", async (req, res) => { |
|
const { username } = req.body; |
|
if (typeof username !== "string") { |
|
throw new ApiError("Must specify a username", ErrorCode.BadRequest); |
|
} |
|
if (username !== SUPERUSER) { |
|
return res.status(403).send(); |
|
} |
|
res.status(200).send(); |
|
}); |
|
|
|
router.post("/acl", async (req, res) => { |
|
const { username, topic, clientid, acc } = req.body; |
|
if (typeof username !== "string" || typeof topic !== "string") { |
|
throw new ApiError( |
|
"username and topic must be specified as strings", |
|
ErrorCode.BadRequest |
|
); |
|
} |
|
const prefix = DEVICE_PREFIX + "/" + username; |
|
if (!topic.startsWith(prefix)) { |
|
throw new ApiError(`device ${username} cannot access topic ${topic}`); |
|
} |
|
res.status(200).send(); |
|
}); |
|
|
|
return router; |
|
}
|
|
|