"use strict"; const defaultValue = require("default-value"); const numberDerivedEvents = require("../number-derived-events"); function mapLevels(eventContent) { if (eventContent != null) { return { defaultRequiredPowerLevels: { stateChange: defaultValue(eventContent.state_default, 50), message: defaultValue(eventContent.events_default, 0), }, requiredPowerLevels: { kick: defaultValue(eventContent.kick, 50), ban: defaultValue(eventContent.ban, 50), invite: defaultValue(eventContent.invite, 50), redact: defaultValue(eventContent.redact, 50) }, requiredEventPowerLevels: eventContent.events, requiredNotificationPowerLevels: { room: 50, ... eventContent.notifications }, defaultUserPowerLevel: defaultValue(eventContent.users_default, 0), currentPowerLevels: eventContent.users }; } else { return { defaultRequiredPowerLevels: { stateChange: 0, message: 0, }, requiredPowerLevels: { kick: 50, ban: 50, invite: 50, redact: 50 }, requiredEventPowerLevels: {}, requiredNotificationPowerLevels: { room: 50 }, defaultUserPowerLevel: 0, currentPowerLevels: {} }; } } // FIXME: Option for parsing as a whole, rather than as a diff? Maybe package `mapLevels` as a separate `map-power-levels-event-full` package or so? // FIXME: Do above + emit as a whole event, for later use in powerlevel-modifying event creation; same for ACLs (maybe build an abstraction for automatically tracking this stuff internally?) -- and make sure to document that the user should use either the full event OR the derived event, not both, for the same purpose! module.exports = function mapPowerLevelsEvent(event, _context) { let oldState = mapLevels(event.unsigned.prev_content); let newState = mapLevels(event.content); let deltaEvents = []; if (oldState.defaultUserPowerLevel !== newState.defaultUserPowerLevel) { deltaEvents.push({ type: "defaultUserPowerLevelChanged", sender: event.sender, oldLevel: oldState.defaultUserPowerLevel, newLevel: newState.defaultUserPowerLevel }); } for (let [ eventCategory, newLevel ] of Object.entries(newState.defaultRequiredPowerLevels)) { let oldLevel = oldState.defaultRequiredPowerLevels[eventCategory]; if (newLevel !== oldLevel) { deltaEvents.push({ type: "defaultRequiredPowerLevelChanged", sender: event.sender, eventCategory: eventCategory, newLevel: newLevel, oldLevel: oldLevel }); } } for (let [ action, newLevel ] of Object.entries(newState.requiredPowerLevels)) { let oldLevel = oldState.requiredPowerLevels[action]; if (newLevel !== oldLevel) { deltaEvents.push({ type: "requiredPowerLevelChanged", sender: event.sender, action: action, newLevel: newLevel, oldLevel: oldLevel }); } } for (let [ eventType, newLevel ] of Object.entries(newState.requiredEventPowerLevels)) { let oldLevel = oldState.requiredEventPowerLevels[eventType]; // FIXME: Default power level? if (newLevel !== oldLevel) { deltaEvents.push({ type: "requiredEventPowerLevelChanged", sender: event.sender, eventType: eventType, newLevel: newLevel, oldLevel: oldLevel }); } } for (let [ notificationType, newLevel ] of Object.entries(newState.requiredNotificationPowerLevels)) { let oldLevel = oldState.requiredNotificationPowerLevels[notificationType]; if (newLevel !== oldLevel) { deltaEvents.push({ type: "requiredNotificationPowerLevelChanged", sender: event.sender, notificationType: notificationType, newLevel: newLevel, oldLevel: oldLevel }); } } for (let [ matrixID, newLevel ] of Object.entries(newState.currentPowerLevels)) { let oldLevel = oldState.currentPowerLevels[matrixID]; if (newLevel !== oldLevel) { deltaEvents.push({ type: "userPowerLevelChanged", sender: event.sender, user: matrixID, newLevel: defaultValue(newLevel, newState.defaultUserPowerLevel), oldLevel: defaultValue(oldLevel, oldState.defaultUserPowerLevel), newLevelIsExplicit: (newLevel != null), oldLevelIsExplicit: (oldLevel != null) }); } } numberDerivedEvents(event.event_id, deltaEvents); return deltaEvents; };