SubscribeMany.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import Job, { JobOptions } from "@/Job";
  2. import EventsModule from "@/modules/EventsModule";
  3. const channelRegex =
  4. /^(?<moduleName>[a-z]+)\.(?<modelName>[A-z]+)\.(?<event>[A-z]+):?(?<modelId>[A-z0-9]+)?$/;
  5. export default class SubscribeMany extends Job {
  6. protected static _hasPermission = true;
  7. public constructor(payload?: unknown, options?: JobOptions) {
  8. super(EventsModule, payload, options);
  9. }
  10. protected override async _validate() {
  11. if (typeof this._payload !== "object" || this._payload === null)
  12. throw new Error("Payload must be an object");
  13. if (!Array.isArray(this._payload.channels))
  14. throw new Error("Channels must be an array");
  15. this._payload.channels.forEach((channel: unknown) => {
  16. if (typeof channel !== "string")
  17. throw new Error("Channel must be a string");
  18. });
  19. }
  20. protected override async _authorize() {
  21. const permissions = this._payload.channels.map((channel: string) => {
  22. const { moduleName, modelName, event, modelId } =
  23. channelRegex.exec(channel)?.groups ?? {};
  24. let permission = `event.${channel}`;
  25. if (
  26. moduleName === "data" &&
  27. modelName &&
  28. (modelId || event === "created")
  29. ) {
  30. if (event === "created")
  31. permission = `event.model.${modelName}.created`;
  32. else permission = `data.${modelName}.findById.${modelId}`;
  33. }
  34. return permission;
  35. });
  36. await this._context.assertPermissions(permissions);
  37. }
  38. protected async _execute() {
  39. const socketId = this._context.getSocketId();
  40. if (!socketId) throw new Error("No socketId specified");
  41. await EventsModule.subscribeManySocket(
  42. this._payload.channels,
  43. socketId
  44. );
  45. }
  46. }