diff --git a/src/db/migrations/0029-force-guild-ids.js b/src/db/migrations/0029-force-guild-ids.js index 354bc6b..e575783 100644 --- a/src/db/migrations/0029-force-guild-ids.js +++ b/src/db/migrations/0029-force-guild-ids.js @@ -14,8 +14,6 @@ const {discord} = require("../../passthrough") const ones = "₀₁₂₃₄₅₆₇₈₉" const tens = "0123456789" -/* c8 ignore start */ - module.exports = async function(db) { /** @type {{name: string, channel_id: string, thread_parent: string | null}[]} */ const rows = db.prepare("SELECT name, channel_id, thread_parent FROM channel_room WHERE guild_id IS NULL").all() diff --git a/src/db/orm.js b/src/db/orm.js index 4d9b6f1..d14e8ae 100644 --- a/src/db/orm.js +++ b/src/db/orm.js @@ -104,6 +104,21 @@ class From { return r } + /** + * @template {Col} Select + * @param {string} what + * @param {Select} col + */ + pluckAs(what, col) { + /** @type {Pluck} */ + // @ts-ignore + const r = this + r.cols = [`${what} AS ${col}`] + this.makeColsSafe = false + r.isPluck = true + return r + } + /** * @param {string} sql */ diff --git a/src/matrix/kstate.js b/src/matrix/kstate.js index 37eed39..85a2838 100644 --- a/src/matrix/kstate.js +++ b/src/matrix/kstate.js @@ -53,11 +53,11 @@ async function kstateToState(kstate) { kstateStripConditionals(kstate) await kstateUploadMxc(kstate) for (const [k, content] of Object.entries(kstate)) { + if (k === "m.room.create/") continue const slashIndex = k.indexOf("/") assert(slashIndex > 0) const type = k.slice(0, slashIndex) const state_key = k.slice(slashIndex + 1) - if (type === "m.room.create") continue events.push({type, state_key, content}) } return events @@ -94,16 +94,15 @@ function diffKState(actual, target) { if (key === "m.room.power_levels/") { // Special handling for power levels, we want to deep merge the actual and target into the final state. if (!(key in actual)) throw new Error(`want to apply a power levels diff, but original power level data is missing\nstarted with: ${JSON.stringify(actual)}\nwant to apply: ${JSON.stringify(target)}`) - // if the diff includes users, it needs to be cleaned wrt room version 12 - const cleanedTarget = mixin({}, target[key]) - if (target[key].users && Object.keys(target[key].users).length > 0) { - assert("m.room.create/" in actual, `want to apply a power levels diff, but original m.room.create/ is missing\nstarted with: ${JSON.stringify(actual)}\nwant to apply: ${JSON.stringify(target)}`) - assert("m.room.create/outer" in actual, `want to apply a power levels diff, but original m.room.create/outer is missing\nstarted with: ${JSON.stringify(actual)}\nwant to apply: ${JSON.stringify(target)}`) - utils.removeCreatorsFromPowerLevels(actual["m.room.create/outer"], cleanedTarget) - } - const mixedTarget = mixin({}, actual[key], cleanedTarget) + const mixedTarget = mixin({}, actual[key], target[key]) if (!isDeepStrictEqual(actual[key], mixedTarget)) { // they differ. use the newly prepared object as the diff. + // if the diff includes users, it needs to be cleaned wrt room version 12 + if (target[key].users && Object.keys(target[key].users).length > 0) { + if (!("m.room.create/" in actual)) throw new Error(`want to apply a power levels diff, but original m.room.create/ is missing\nstarted with: ${JSON.stringify(actual)}\nwant to apply: ${JSON.stringify(target)}`) + if (!("m.room.create/outer" in actual)) throw new Error(`want to apply a power levels diff, but original m.room.create/outer is missing\nstarted with: ${JSON.stringify(actual)}\nwant to apply: ${JSON.stringify(target)}`) + utils.removeCreatorsFromPowerLevels(actual["m.room.create/outer"], mixedTarget) + } diff[key] = mixedTarget } diff --git a/src/matrix/kstate.test.js b/src/matrix/kstate.test.js index b67a725..ff65e9c 100644 --- a/src/matrix/kstate.test.js +++ b/src/matrix/kstate.test.js @@ -1,5 +1,5 @@ const assert = require("assert") -const {kstateToState, stateToKState, diffKState, kstateStripConditionals, kstateUploadMxc, kstateToCreationContent} = require("./kstate") +const {kstateToState, stateToKState, diffKState, kstateStripConditionals, kstateUploadMxc} = require("./kstate") const {test} = require("supertape") test("kstate strip: strips false conditions", t => { @@ -68,8 +68,6 @@ test("kstateUploadMxc and strip: work together", async t => { test("kstate2state: general", async t => { t.deepEqual(await kstateToState({ - "m.room.create/": {bogus: true}, - "m.room.create/outer": {bogus: true}, "m.room.name/": {name: "test name"}, "m.room.member/@cadence:cadence.moe": {membership: "join"}, "uk.half-shot.bridge/org.matrix.appservice-irc://irc/epicord.net/#general": {creator: "@cadence:cadence.moe"} @@ -100,14 +98,6 @@ test("kstate2state: general", async t => { test("state2kstate: general", t => { t.deepEqual(stateToKState([ - { - type: "m.room.create", - state_key: "", - sender: "@example:matrix.org", - content: { - room_version: "12" - } - }, { type: "m.room.name", state_key: "", @@ -132,9 +122,7 @@ test("state2kstate: general", t => { ]), { "m.room.name/": {name: "test name"}, "m.room.member/@cadence:cadence.moe": {membership: "join"}, - "uk.half-shot.bridge/org.matrix.appservice-irc://irc/epicord.net/#general": {creator: "@cadence:cadence.moe"}, - "m.room.create/": {room_version: "12"}, - "m.room.create/outer": {type: "m.room.create", state_key: "", sender: "@example:matrix.org", content: {room_version: "12"}} + "uk.half-shot.bridge/org.matrix.appservice-irc://irc/epicord.net/#general": {creator: "@cadence:cadence.moe"} }) }) @@ -169,17 +157,6 @@ test("diffKState: detects new properties", t => { test("diffKState: power levels are mixed together", t => { const original = { - "m.room.create/outer": { - type: "m.room.create", - state_key: "", - sender: "@example:matrix.org", - content: { - room_version: "11" - } - }, - "m.room.create/": { - room_version: "11" - }, "m.room.power_levels/": { "ban": 50, "events": { @@ -204,9 +181,6 @@ test("diffKState: power levels are mixed together", t => { "m.room.power_levels/": { "events": { "m.room.avatar": 0 - }, - users: { - "@example:matrix.org": 100 } } }) @@ -227,8 +201,7 @@ test("diffKState: power levels are mixed together", t => { "redact": 50, "state_default": 50, "users": { - "@example:localhost": 100, - "@example:matrix.org": 100 + "@example:localhost": 100 }, "users_default": 0 } @@ -297,154 +270,3 @@ test("diffKState: topic changes if the topic key has changed", t => { } }) }) - -test("diffKState: room v12 creators cannot be introduced into power levels", t => { - const original = { - "m.room.create/outer": { - type: "m.room.create", - state_key: "", - sender: "@example1:matrix.org", - content: { - additional_creators: ["@example2:matrix.org"], - room_version: "12" - } - }, - "m.room.create/": { - room_version: "12" - }, - "m.room.power_levels/": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100 - }, - "events_default": 0, - "invite": 50, - "kick": 50, - "notifications": { - "room": 20 - }, - "redact": 50, - "state_default": 50, - "users": { - "@example:localhost": 100 - }, - "users_default": 0 - } - } - const result = diffKState(original, { - "m.room.create/": { - bogus: true - }, - "m.room.power_levels/": { - events: { - "m.room.avatar": 0 - }, - users: { - "@example1:matrix.org": 100, - "@example2:matrix.org": 100, - "@example3:matrix.org": 100 - } - } - }) - t.deepEqual(result, { - "m.room.power_levels/": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100, - "m.room.avatar": 0 - }, - "events_default": 0, - "invite": 50, - "kick": 50, - "notifications": { - "room": 20 - }, - "redact": 50, - "state_default": 50, - "users": { - "@example:localhost": 100, - "@example3:matrix.org": 100 - }, - "users_default": 0 - } - }) - t.notDeepEqual(original, result) -}) - -test("diffKState: room v12 creators cannot be introduced into power levels - no diff if no changes", t => { - const original = { - "m.room.create/outer": { - type: "m.room.create", - state_key: "", - sender: "@example1:matrix.org", - content: { - additional_creators: ["@example2:matrix.org"], - room_version: "12" - } - }, - "m.room.create/": { - additional_creators: ["@example2:matrix.org"], - room_version: "12" - }, - "m.room.power_levels/": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100 - }, - "events_default": 0, - "invite": 50, - "kick": 50, - "notifications": { - "room": 20 - }, - "redact": 50, - "state_default": 50, - "users": { - "@example:localhost": 100 - }, - "users_default": 0 - } - } - const result = diffKState(original, { - "m.room.power_levels/": { - users: { - "@example1:matrix.org": 100, - "@example2:matrix.org": 100 - } - } - }) - t.deepEqual(result, {}) - t.notDeepEqual(original, result) -}) - -test("kstateToCreationContent: works", t => { - const original = { - "m.room.create/outer": { - type: "m.room.create", - state_key: "", - sender: "@example1:matrix.org", - content: { - additional_creators: ["@example2:matrix.org"], - room_version: "12", - type: "m.space" - } - }, - "m.room.create/": { - additional_creators: ["@example2:matrix.org"], - room_version: "12", - type: "m.space" - } - } - t.deepEqual(kstateToCreationContent(original), { - additional_creators: ["@example2:matrix.org"], - room_version: "12", - type: "m.space" - }) -}) - -test("kstateToCreationContent: works if empty", t => { - t.deepEqual(kstateToCreationContent({}), {}) -})