@seriousme/opifex
Version:
MQTT client & server for Deno & NodeJS
57 lines • 2.02 kB
JavaScript
import { PacketType, } from "../deps.js";
/**
* @constant {number} SubscriptionFailure
* @description Code indicating a failed subscription attempt
*/
const SubscriptionFailure = 0x80;
/**
* Checks if a client is authorized to subscribe to a topic
* @param ctx - The connection context
* @param topicFilter - The topic filter to check authorization for
* @returns True if authorized, false otherwise
*/
function authorizedToSubscribe(ctx, topicFilter) {
if (ctx.handlers.isAuthorizedToSubscribe) {
return ctx.handlers.isAuthorizedToSubscribe(ctx, topicFilter);
}
return true;
}
/**
* @function handleSubscribe
* @description Processes an MQTT SUBSCRIBE packet
* @param {Context} ctx - The connection context
* @param {SubscribePacket} packet - The SUBSCRIBE packet received from the client
* @returns {Promise<void>}
* @throws {Error} If subscription processing fails
* @remarks The order of return codes in the SUBACK Packet MUST match the order of Topic Filters in the SUBSCRIBE Packet [MQTT-3.9.3-1]
*/
export async function handleSubscribe(ctx, packet) {
/*
* The order of return codes in the SUBACK Packet MUST match the order of
* Topic Filters in the SUBSCRIBE Packet [MQTT-3.9.3-1].
*/
const validSubscriptions = [];
const returnCodes = packet.subscriptions.map((sub) => {
if (ctx.store) {
if (!authorizedToSubscribe(ctx, sub.topicFilter)) {
return SubscriptionFailure;
}
ctx.persistence.subscribe(ctx.store, sub.topicFilter, sub.qos);
validSubscriptions.push(sub);
return sub.qos;
}
return SubscriptionFailure;
});
await ctx.send({
type: PacketType.suback,
id: packet.id,
returnCodes: returnCodes,
});
/*
* send any retained messages that match these subscriptions
*/
if (ctx.store) {
ctx.persistence.handleRetained(ctx.store.clientId);
}
}
//# sourceMappingURL=handleSubscribe.js.map