diff --git a/.gitignore b/.gitignore index 9c175d8..3781b9b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,6 @@ node_modules config.js registration.yaml coverage -db/ooye.db* +src/db/ooye.db* test/res/* !test/res/lottie* diff --git a/package.json b/package.json index 8c800e1..8fccd08 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,6 @@ "addbot": "node addbot.js", "test": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap test/test.js | tap-dot", "test-slow": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap --no-worker test/test.js -- --slow | tap-dot", - "cover": "c8 --skip-full -x db/migrations -x matrix/file.js -x matrix/api.js -x matrix/mreq.js -x d2m/converters/rlottie-wasm.js -r html -r text supertape --no-check-assertions-count --format fail --no-worker test/test.js -- --slow" + "cover": "c8 -o test/coverage --skip-full -x db/migrations -x matrix/file.js -x matrix/api.js -x matrix/mreq.js -x d2m/converters/rlottie-wasm.js -r html -r text supertape --no-check-assertions-count --format fail --no-worker test/test.js -- --slow" } } diff --git a/d2m/actions/add-reaction.js b/src/d2m/actions/add-reaction.js similarity index 100% rename from d2m/actions/add-reaction.js rename to src/d2m/actions/add-reaction.js diff --git a/d2m/actions/announce-thread.js b/src/d2m/actions/announce-thread.js similarity index 100% rename from d2m/actions/announce-thread.js rename to src/d2m/actions/announce-thread.js diff --git a/d2m/actions/create-room.js b/src/d2m/actions/create-room.js similarity index 100% rename from d2m/actions/create-room.js rename to src/d2m/actions/create-room.js diff --git a/d2m/actions/create-room.test.js b/src/d2m/actions/create-room.test.js similarity index 99% rename from d2m/actions/create-room.test.js rename to src/d2m/actions/create-room.test.js index d4391a9..a1766dd 100644 --- a/d2m/actions/create-room.test.js +++ b/src/d2m/actions/create-room.test.js @@ -4,7 +4,7 @@ const mixin = require("@cloudrac3r/mixin-deep") const {channelToKState, _convertNameAndTopic} = require("./create-room") const {kstateStripConditionals} = require("../../matrix/kstate") const {test} = require("supertape") -const testData = require("../../test/data") +const testData = require("../../../test/data") const passthrough = require("../../passthrough") const {db} = passthrough diff --git a/d2m/actions/create-space.js b/src/d2m/actions/create-space.js similarity index 100% rename from d2m/actions/create-space.js rename to src/d2m/actions/create-space.js diff --git a/d2m/actions/create-space.test.js b/src/d2m/actions/create-space.test.js similarity index 95% rename from d2m/actions/create-space.test.js rename to src/d2m/actions/create-space.test.js index c4111db..cb4d90a 100644 --- a/d2m/actions/create-space.test.js +++ b/src/d2m/actions/create-space.test.js @@ -4,7 +4,7 @@ const mixin = require("@cloudrac3r/mixin-deep") const {guildToKState, ensureSpace} = require("./create-space") const {kstateStripConditionals, kstateUploadMxc} = require("../../matrix/kstate") const {test} = require("supertape") -const testData = require("../../test/data") +const testData = require("../../../test/data") const passthrough = require("../../passthrough") const {db} = passthrough diff --git a/d2m/actions/delete-message.js b/src/d2m/actions/delete-message.js similarity index 100% rename from d2m/actions/delete-message.js rename to src/d2m/actions/delete-message.js diff --git a/d2m/actions/edit-message.js b/src/d2m/actions/edit-message.js similarity index 100% rename from d2m/actions/edit-message.js rename to src/d2m/actions/edit-message.js diff --git a/d2m/actions/expression.js b/src/d2m/actions/expression.js similarity index 98% rename from d2m/actions/expression.js rename to src/d2m/actions/expression.js index b7b5d5a..b81f4ed 100644 --- a/d2m/actions/expression.js +++ b/src/d2m/actions/expression.js @@ -66,7 +66,7 @@ async function stickersToState(stickers) { while (shortcodes.includes(shortcode)) shortcode = shortcode + "~" shortcodes.push(shortcode) - result.images[shortcodes] = { + result.images[shortcode] = { info: { mimetype: file.stickerFormat.get(sticker.format_type)?.mime || "image/png" }, diff --git a/d2m/actions/lottie.js b/src/d2m/actions/lottie.js similarity index 100% rename from d2m/actions/lottie.js rename to src/d2m/actions/lottie.js diff --git a/d2m/actions/register-pk-user.js b/src/d2m/actions/register-pk-user.js similarity index 100% rename from d2m/actions/register-pk-user.js rename to src/d2m/actions/register-pk-user.js diff --git a/d2m/actions/register-user.js b/src/d2m/actions/register-user.js similarity index 100% rename from d2m/actions/register-user.js rename to src/d2m/actions/register-user.js diff --git a/d2m/actions/register-user.test.js b/src/d2m/actions/register-user.test.js similarity index 97% rename from d2m/actions/register-user.test.js rename to src/d2m/actions/register-user.test.js index 96c73aa..353c89f 100644 --- a/d2m/actions/register-user.test.js +++ b/src/d2m/actions/register-user.test.js @@ -1,6 +1,6 @@ const {_memberToStateContent} = require("./register-user") const {test} = require("supertape") -const testData = require("../../test/data") +const testData = require("../../../test/data") test("member2state: without member nick or avatar", async t => { t.deepEqual( diff --git a/d2m/actions/remove-reaction.js b/src/d2m/actions/remove-reaction.js similarity index 100% rename from d2m/actions/remove-reaction.js rename to src/d2m/actions/remove-reaction.js diff --git a/d2m/actions/retrigger.js b/src/d2m/actions/retrigger.js similarity index 100% rename from d2m/actions/retrigger.js rename to src/d2m/actions/retrigger.js diff --git a/d2m/actions/send-message.js b/src/d2m/actions/send-message.js similarity index 100% rename from d2m/actions/send-message.js rename to src/d2m/actions/send-message.js diff --git a/d2m/actions/speedbump.js b/src/d2m/actions/speedbump.js similarity index 100% rename from d2m/actions/speedbump.js rename to src/d2m/actions/speedbump.js diff --git a/d2m/actions/update-pins.js b/src/d2m/actions/update-pins.js similarity index 100% rename from d2m/actions/update-pins.js rename to src/d2m/actions/update-pins.js diff --git a/d2m/converters/edit-to-changes.js b/src/d2m/converters/edit-to-changes.js similarity index 100% rename from d2m/converters/edit-to-changes.js rename to src/d2m/converters/edit-to-changes.js diff --git a/d2m/converters/edit-to-changes.test.js b/src/d2m/converters/edit-to-changes.test.js similarity index 99% rename from d2m/converters/edit-to-changes.test.js rename to src/d2m/converters/edit-to-changes.test.js index effb777..b561bb1 100644 --- a/d2m/converters/edit-to-changes.test.js +++ b/src/d2m/converters/edit-to-changes.test.js @@ -1,6 +1,6 @@ const {test} = require("supertape") const {editToChanges} = require("./edit-to-changes") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") test("edit2changes: edit by webhook", async t => { diff --git a/d2m/converters/emoji-to-key.js b/src/d2m/converters/emoji-to-key.js similarity index 100% rename from d2m/converters/emoji-to-key.js rename to src/d2m/converters/emoji-to-key.js diff --git a/d2m/converters/emoji-to-key.test.js b/src/d2m/converters/emoji-to-key.test.js similarity index 94% rename from d2m/converters/emoji-to-key.test.js rename to src/d2m/converters/emoji-to-key.test.js index 5af046c..544eada 100644 --- a/d2m/converters/emoji-to-key.test.js +++ b/src/d2m/converters/emoji-to-key.test.js @@ -2,7 +2,7 @@ const {test} = require("supertape") const {emojiToKey} = require("./emoji-to-key") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") test("emoji2key: unicode emoji works", async t => { diff --git a/d2m/converters/lottie.js b/src/d2m/converters/lottie.js similarity index 100% rename from d2m/converters/lottie.js rename to src/d2m/converters/lottie.js diff --git a/d2m/converters/lottie.test.js b/src/d2m/converters/lottie.test.js similarity index 100% rename from d2m/converters/lottie.test.js rename to src/d2m/converters/lottie.test.js diff --git a/d2m/converters/message-to-event.embeds.test.js b/src/d2m/converters/message-to-event.embeds.test.js similarity index 99% rename from d2m/converters/message-to-event.embeds.test.js rename to src/d2m/converters/message-to-event.embeds.test.js index 05e3b5d..ef7e9b8 100644 --- a/d2m/converters/message-to-event.embeds.test.js +++ b/src/d2m/converters/message-to-event.embeds.test.js @@ -1,6 +1,6 @@ const {test} = require("supertape") const {messageToEvent} = require("./message-to-event") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") test("message2event embeds: nothing but a field", async t => { diff --git a/d2m/converters/message-to-event.js b/src/d2m/converters/message-to-event.js similarity index 100% rename from d2m/converters/message-to-event.js rename to src/d2m/converters/message-to-event.js diff --git a/d2m/converters/message-to-event.pk.test.js b/src/d2m/converters/message-to-event.pk.test.js similarity index 98% rename from d2m/converters/message-to-event.pk.test.js rename to src/d2m/converters/message-to-event.pk.test.js index c490469..ce83d54 100644 --- a/d2m/converters/message-to-event.pk.test.js +++ b/src/d2m/converters/message-to-event.pk.test.js @@ -1,6 +1,6 @@ const {test} = require("supertape") const {messageToEvent} = require("./message-to-event") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") /** diff --git a/d2m/converters/message-to-event.test.js b/src/d2m/converters/message-to-event.test.js similarity index 99% rename from d2m/converters/message-to-event.test.js rename to src/d2m/converters/message-to-event.test.js index 02fb4bb..3df1130 100644 --- a/d2m/converters/message-to-event.test.js +++ b/src/d2m/converters/message-to-event.test.js @@ -1,6 +1,6 @@ const {test} = require("supertape") const {messageToEvent} = require("./message-to-event") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") /** diff --git a/d2m/converters/pins-to-list.js b/src/d2m/converters/pins-to-list.js similarity index 100% rename from d2m/converters/pins-to-list.js rename to src/d2m/converters/pins-to-list.js diff --git a/d2m/converters/pins-to-list.test.js b/src/d2m/converters/pins-to-list.test.js similarity index 89% rename from d2m/converters/pins-to-list.test.js rename to src/d2m/converters/pins-to-list.test.js index 8a6daea..7ee89b6 100644 --- a/d2m/converters/pins-to-list.test.js +++ b/src/d2m/converters/pins-to-list.test.js @@ -1,5 +1,5 @@ const {test} = require("supertape") -const data = require("../../test/data") +const data = require("../../../test/data") const {pinsToList} = require("./pins-to-list") test("pins2list: converts known IDs, ignores unknown IDs", t => { diff --git a/d2m/converters/remove-reaction.js b/src/d2m/converters/remove-reaction.js similarity index 100% rename from d2m/converters/remove-reaction.js rename to src/d2m/converters/remove-reaction.js diff --git a/d2m/converters/remove-reaction.test.js b/src/d2m/converters/remove-reaction.test.js similarity index 100% rename from d2m/converters/remove-reaction.test.js rename to src/d2m/converters/remove-reaction.test.js diff --git a/d2m/converters/rlottie-wasm.js b/src/d2m/converters/rlottie-wasm.js similarity index 100% rename from d2m/converters/rlottie-wasm.js rename to src/d2m/converters/rlottie-wasm.js diff --git a/d2m/converters/rlottie-wasm.license b/src/d2m/converters/rlottie-wasm.license similarity index 100% rename from d2m/converters/rlottie-wasm.license rename to src/d2m/converters/rlottie-wasm.license diff --git a/d2m/converters/rlottie-wasm.wasm b/src/d2m/converters/rlottie-wasm.wasm old mode 100755 new mode 100644 similarity index 100% rename from d2m/converters/rlottie-wasm.wasm rename to src/d2m/converters/rlottie-wasm.wasm diff --git a/d2m/converters/thread-to-announcement.js b/src/d2m/converters/thread-to-announcement.js similarity index 100% rename from d2m/converters/thread-to-announcement.js rename to src/d2m/converters/thread-to-announcement.js diff --git a/d2m/converters/thread-to-announcement.test.js b/src/d2m/converters/thread-to-announcement.test.js similarity index 99% rename from d2m/converters/thread-to-announcement.test.js rename to src/d2m/converters/thread-to-announcement.test.js index 3bbca20..471cd94 100644 --- a/d2m/converters/thread-to-announcement.test.js +++ b/src/d2m/converters/thread-to-announcement.test.js @@ -1,6 +1,6 @@ const {test} = require("supertape") const {threadToAnnouncement} = require("./thread-to-announcement") -const data = require("../../test/data") +const data = require("../../../test/data") const Ty = require("../../types") /** diff --git a/d2m/converters/user-to-mxid.js b/src/d2m/converters/user-to-mxid.js similarity index 100% rename from d2m/converters/user-to-mxid.js rename to src/d2m/converters/user-to-mxid.js diff --git a/d2m/converters/user-to-mxid.test.js b/src/d2m/converters/user-to-mxid.test.js similarity index 98% rename from d2m/converters/user-to-mxid.test.js rename to src/d2m/converters/user-to-mxid.test.js index 5787b64..86f151b 100644 --- a/d2m/converters/user-to-mxid.test.js +++ b/src/d2m/converters/user-to-mxid.test.js @@ -1,7 +1,7 @@ const {test} = require("supertape") const tryToCatch = require("try-to-catch") const assert = require("assert") -const data = require("../../test/data") +const data = require("../../../test/data") const {userToSimName} = require("./user-to-mxid") test("user2name: cannot create user for a webhook", async t => { diff --git a/d2m/discord-client.js b/src/d2m/discord-client.js similarity index 100% rename from d2m/discord-client.js rename to src/d2m/discord-client.js diff --git a/d2m/discord-packets.js b/src/d2m/discord-packets.js similarity index 100% rename from d2m/discord-packets.js rename to src/d2m/discord-packets.js diff --git a/d2m/event-dispatcher.js b/src/d2m/event-dispatcher.js similarity index 100% rename from d2m/event-dispatcher.js rename to src/d2m/event-dispatcher.js diff --git a/db/migrate.js b/src/db/migrate.js similarity index 100% rename from db/migrate.js rename to src/db/migrate.js diff --git a/db/migrations/.baby b/src/db/migrations/.baby similarity index 100% rename from db/migrations/.baby rename to src/db/migrations/.baby diff --git a/db/migrations/0001-schema.sql b/src/db/migrations/0001-schema.sql similarity index 100% rename from db/migrations/0001-schema.sql rename to src/db/migrations/0001-schema.sql diff --git a/db/migrations/0002-optimise-profile-content.sql b/src/db/migrations/0002-optimise-profile-content.sql similarity index 100% rename from db/migrations/0002-optimise-profile-content.sql rename to src/db/migrations/0002-optimise-profile-content.sql diff --git a/db/migrations/0002-optimise-profile-content.up.js b/src/db/migrations/0002-optimise-profile-content.up.js similarity index 100% rename from db/migrations/0002-optimise-profile-content.up.js rename to src/db/migrations/0002-optimise-profile-content.up.js diff --git a/db/migrations/0003-distinguish-column-names.sql b/src/db/migrations/0003-distinguish-column-names.sql similarity index 100% rename from db/migrations/0003-distinguish-column-names.sql rename to src/db/migrations/0003-distinguish-column-names.sql diff --git a/db/migrations/0004-auto-emoji-guild.sql b/src/db/migrations/0004-auto-emoji-guild.sql similarity index 100% rename from db/migrations/0004-auto-emoji-guild.sql rename to src/db/migrations/0004-auto-emoji-guild.sql diff --git a/db/migrations/0005-clear-member-cache.sql b/src/db/migrations/0005-clear-member-cache.sql similarity index 100% rename from db/migrations/0005-clear-member-cache.sql rename to src/db/migrations/0005-clear-member-cache.sql diff --git a/db/migrations/0006-add-privacy-to-space.sql b/src/db/migrations/0006-add-privacy-to-space.sql similarity index 100% rename from db/migrations/0006-add-privacy-to-space.sql rename to src/db/migrations/0006-add-privacy-to-space.sql diff --git a/db/migrations/0007-split-part-and-reaction-part.sql b/src/db/migrations/0007-split-part-and-reaction-part.sql similarity index 100% rename from db/migrations/0007-split-part-and-reaction-part.sql rename to src/db/migrations/0007-split-part-and-reaction-part.sql diff --git a/db/migrations/0008-add-last-bridged-pin-timestamp.sql b/src/db/migrations/0008-add-last-bridged-pin-timestamp.sql similarity index 100% rename from db/migrations/0008-add-last-bridged-pin-timestamp.sql rename to src/db/migrations/0008-add-last-bridged-pin-timestamp.sql diff --git a/db/migrations/0009-add-speedbump-id.sql b/src/db/migrations/0009-add-speedbump-id.sql similarity index 100% rename from db/migrations/0009-add-speedbump-id.sql rename to src/db/migrations/0009-add-speedbump-id.sql diff --git a/db/migrations/0010-add-sim-proxy.sql b/src/db/migrations/0010-add-sim-proxy.sql similarity index 100% rename from db/migrations/0010-add-sim-proxy.sql rename to src/db/migrations/0010-add-sim-proxy.sql diff --git a/db/migrations/0011-move-bridge-bot-to-real-id.up.js b/src/db/migrations/0011-move-bridge-bot-to-real-id.up.js similarity index 91% rename from db/migrations/0011-move-bridge-bot-to-real-id.up.js rename to src/db/migrations/0011-move-bridge-bot-to-real-id.up.js index 1808fcd..6bcf2c7 100644 --- a/db/migrations/0011-move-bridge-bot-to-real-id.up.js +++ b/src/db/migrations/0011-move-bridge-bot-to-real-id.up.js @@ -10,7 +10,7 @@ */ module.exports = async function(db) { - const config = require("../../config") + const config = require("../../../config") const id = Buffer.from(config.discordToken.split(".")[0], "base64").toString() db.prepare("UPDATE OR REPLACE sim SET user_id = ? WHERE user_id = '0'").run(id) } diff --git a/db/migrations/0012-add-member-power.sql b/src/db/migrations/0012-add-member-power.sql similarity index 100% rename from db/migrations/0012-add-member-power.sql rename to src/db/migrations/0012-add-member-power.sql diff --git a/src/db/migrations/0013-media-proxy.sql b/src/db/migrations/0013-media-proxy.sql new file mode 100644 index 0000000..d55f059 --- /dev/null +++ b/src/db/migrations/0013-media-proxy.sql @@ -0,0 +1,8 @@ +BEGIN TRANSACTION; + +CREATE TABLE "media_proxy" ( + "permitted_hash" INTEGER NOT NULL, + PRIMARY KEY("permitted_hash") +) WITHOUT ROWID; + +COMMIT; diff --git a/db/orm-defs.d.ts b/src/db/orm-defs.d.ts similarity index 100% rename from db/orm-defs.d.ts rename to src/db/orm-defs.d.ts diff --git a/db/orm-defs.js b/src/db/orm-defs.js similarity index 100% rename from db/orm-defs.js rename to src/db/orm-defs.js diff --git a/db/orm.js b/src/db/orm.js similarity index 100% rename from db/orm.js rename to src/db/orm.js diff --git a/db/orm.test.js b/src/db/orm.test.js similarity index 98% rename from db/orm.test.js rename to src/db/orm.test.js index 3d4e8ef..a53cc66 100644 --- a/db/orm.test.js +++ b/src/db/orm.test.js @@ -1,7 +1,7 @@ // @ts-check const {test} = require("supertape") -const data = require("../test/data") +const data = require("../../test/data") const {db, select, from} = require("../passthrough") diff --git a/discord/discord-command-handler.js b/src/discord/discord-command-handler.js similarity index 97% rename from discord/discord-command-handler.js rename to src/discord/discord-command-handler.js index a434bf9..f0a4b49 100644 --- a/discord/discord-command-handler.js +++ b/src/discord/discord-command-handler.js @@ -4,13 +4,15 @@ const assert = require("assert").strict const util = require("util") const DiscordTypes = require("discord-api-types/v10") const {reg} = require("../matrix/read-registration") -const {addbot} = require("../addbot") +const {addbot} = require("../../addbot") const {discord, sync, db, select} = require("../passthrough") /** @type {import("../matrix/api")}) */ const api = sync.require("../matrix/api") /** @type {import("../matrix/file")} */ const file = sync.require("../matrix/file") +/** @type {import("../m2d/converters/utils")} */ +const mxUtils = sync.require("../m2d/converters/utils") /** @type {import("../d2m/actions/create-space")} */ const createSpace = sync.require("../d2m/actions/create-space") /** @type {import("./utils")} */ @@ -91,9 +93,8 @@ const commands = [{ // Current avatar const avatarEvent = await api.getStateEvent(roomID, "m.room.avatar", "") - const avatarURLParts = avatarEvent?.url.match(/^mxc:\/\/([^/]+)\/(\w+)$/) let currentAvatarMessage = - ( avatarURLParts ? `Current room-specific avatar: ${reg.ooye.server_origin}/_matrix/media/r0/download/${avatarURLParts[1]}/${avatarURLParts[2]}` + ( avatarEvent.url ? `Current room-specific avatar: ${mxUtils.getPublicUrlForMxc(avatarEvent.url)}` : "No avatar. Now's your time to strike. Use `//icon` again with a link or upload to set the room-specific avatar.") // Next potential avatar diff --git a/discord/interactions/bridge.js b/src/discord/interactions/bridge.js similarity index 100% rename from discord/interactions/bridge.js rename to src/discord/interactions/bridge.js diff --git a/discord/interactions/invite.js b/src/discord/interactions/invite.js similarity index 100% rename from discord/interactions/invite.js rename to src/discord/interactions/invite.js diff --git a/discord/interactions/matrix-info.js b/src/discord/interactions/matrix-info.js similarity index 100% rename from discord/interactions/matrix-info.js rename to src/discord/interactions/matrix-info.js diff --git a/discord/interactions/permissions.js b/src/discord/interactions/permissions.js similarity index 100% rename from discord/interactions/permissions.js rename to src/discord/interactions/permissions.js diff --git a/discord/interactions/reactions.js b/src/discord/interactions/reactions.js similarity index 100% rename from discord/interactions/reactions.js rename to src/discord/interactions/reactions.js diff --git a/discord/register-interactions.js b/src/discord/register-interactions.js similarity index 98% rename from discord/register-interactions.js rename to src/discord/register-interactions.js index 026ac7a..c66bef3 100644 --- a/discord/register-interactions.js +++ b/src/discord/register-interactions.js @@ -2,7 +2,7 @@ const DiscordTypes = require("discord-api-types/v10") const {discord, sync, db, select} = require("../passthrough") -const {id} = require("../addbot") +const {id} = require("../../addbot") const matrixInfo = sync.require("./interactions/matrix-info.js") const invite = sync.require("./interactions/invite.js") diff --git a/discord/utils.js b/src/discord/utils.js similarity index 100% rename from discord/utils.js rename to src/discord/utils.js diff --git a/discord/utils.test.js b/src/discord/utils.test.js similarity index 98% rename from discord/utils.test.js rename to src/discord/utils.test.js index 815c0a1..7c5f0c8 100644 --- a/discord/utils.test.js +++ b/src/discord/utils.test.js @@ -1,6 +1,6 @@ const DiscordTypes = require("discord-api-types/v10") const {test} = require("supertape") -const data = require("../test/data") +const data = require("../../test/data") const utils = require("./utils") test("is webhook message: identifies bot interaction response as not a message", t => { diff --git a/m2d/actions/add-reaction.js b/src/m2d/actions/add-reaction.js similarity index 100% rename from m2d/actions/add-reaction.js rename to src/m2d/actions/add-reaction.js diff --git a/m2d/actions/channel-webhook.js b/src/m2d/actions/channel-webhook.js similarity index 100% rename from m2d/actions/channel-webhook.js rename to src/m2d/actions/channel-webhook.js diff --git a/m2d/actions/emoji-sheet.js b/src/m2d/actions/emoji-sheet.js similarity index 100% rename from m2d/actions/emoji-sheet.js rename to src/m2d/actions/emoji-sheet.js diff --git a/m2d/actions/redact.js b/src/m2d/actions/redact.js similarity index 100% rename from m2d/actions/redact.js rename to src/m2d/actions/redact.js diff --git a/m2d/actions/send-event.js b/src/m2d/actions/send-event.js similarity index 100% rename from m2d/actions/send-event.js rename to src/m2d/actions/send-event.js diff --git a/m2d/converters/emoji-sheet.js b/src/m2d/converters/emoji-sheet.js similarity index 96% rename from m2d/converters/emoji-sheet.js rename to src/m2d/converters/emoji-sheet.js index 4d9cc07..db5b06f 100644 --- a/m2d/converters/emoji-sheet.js +++ b/src/m2d/converters/emoji-sheet.js @@ -81,9 +81,10 @@ async function convertImageStream(streamIn, stopStream) { giframe.feed(chunk) }) const frame = await giframe.getFrame() + const pixels = Uint8Array.from(frame.pixels) stopStream() - const buffer = await sharp(frame.pixels, {raw: {width: frame.width, height: frame.height, channels: 4}}) + const buffer = await sharp(pixels, {raw: {width: frame.width, height: frame.height, channels: 4}}) .resize(SIZE, SIZE, {fit: "contain", background: {r: 0, g: 0, b: 0, alpha: 0}}) .png({compressionLevel: 0}) .toBuffer({resolveWithObject: true}) diff --git a/m2d/converters/emoji-sheet.test.js b/src/m2d/converters/emoji-sheet.test.js similarity index 100% rename from m2d/converters/emoji-sheet.test.js rename to src/m2d/converters/emoji-sheet.test.js diff --git a/m2d/converters/emoji.js b/src/m2d/converters/emoji.js similarity index 100% rename from m2d/converters/emoji.js rename to src/m2d/converters/emoji.js diff --git a/m2d/converters/event-to-message.js b/src/m2d/converters/event-to-message.js similarity index 99% rename from m2d/converters/event-to-message.js rename to src/m2d/converters/event-to-message.js index 5234755..76a32bc 100644 --- a/m2d/converters/event-to-message.js +++ b/src/m2d/converters/event-to-message.js @@ -15,6 +15,8 @@ const {sync, db, discord, select, from} = passthrough const mxUtils = sync.require("../converters/utils") /** @type {import("../../discord/utils")} */ const dUtils = sync.require("../../discord/utils") +/** @type {import("../../matrix/file")} */ +const file = sync.require("../../matrix/file") /** @type {import("./emoji-sheet")} */ const emojiSheet = sync.require("./emoji-sheet") diff --git a/m2d/converters/event-to-message.test.js b/src/m2d/converters/event-to-message.test.js similarity index 99% rename from m2d/converters/event-to-message.test.js rename to src/m2d/converters/event-to-message.test.js index d6a20cd..b674845 100644 --- a/m2d/converters/event-to-message.test.js +++ b/src/m2d/converters/event-to-message.test.js @@ -3,7 +3,7 @@ const fs = require("fs") const {test} = require("supertape") const {eventToMessage} = require("./event-to-message") const {convertImageStream} = require("./emoji-sheet") -const data = require("../../test/data") +const data = require("../../../test/data") const {MatrixServerError} = require("../../matrix/mreq") const {select, discord} = require("../../passthrough") diff --git a/m2d/converters/utils.js b/src/m2d/converters/utils.js similarity index 85% rename from m2d/converters/utils.js rename to src/m2d/converters/utils.js index 437b5c0..c1f5f01 100644 --- a/m2d/converters/utils.js +++ b/src/m2d/converters/utils.js @@ -1,8 +1,13 @@ // @ts-check +const assert = require("assert").strict + +const passthrough = require("../../passthrough") +const {db} = passthrough + const {reg} = require("../../matrix/read-registration") const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex)) -const assert = require("assert").strict + /** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore let hasher = null // @ts-ignore @@ -35,16 +40,6 @@ function eventSenderIsFromDiscord(sender) { return false } -/** - * @param {string} mxc - * @returns {string?} - */ -function getPublicUrlForMxc(mxc) { - const avatarURLParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/) - if (avatarURLParts) return `${reg.ooye.server_origin}/_matrix/media/r0/download/${avatarURLParts[1]}/${avatarURLParts[2]}` - else return null -} - /** * Event IDs are really big and have more entropy than we need. * If we want to store the event ID in the database, we can store a more compact version by hashing it with this. @@ -213,6 +208,32 @@ async function getViaServersQuery(roomID, api) { return qs } +/** + * Since the introduction of authenticated media, this can no longer just be the /_matrix/media/r0/download URL + * because Discord and Discord users cannot use those URLs. Media now has to be proxied through the bridge. + * To avoid the bridge acting as a proxy for *any* media, there is a list of permitted media stored in the database. + * (The other approach would be signing the URLs with a MAC (or similar) and adding the signature, but I'm not a + * cryptographer, so I don't want to.) To reduce database disk space usage, instead of storing each permitted URL, + * we just store its xxhash as a signed (as in +/-, not signature) 64-bit integer, which fits in an SQLite integer field. + * @see https://matrix.org/blog/2024/06/26/sunsetting-unauthenticated-media/ background + * @see https://matrix.org/blog/2024/06/20/matrix-v1.11-release/ implementation details + * @see https://www.sqlite.org/fileformat2.html#record_format SQLite integer field size + * @param {string} mxc + * @returns {string?} + */ +function getPublicUrlForMxc(mxc) { + assert(hasher, "xxhash is not ready yet") + const avatarURLParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/) + if (!avatarURLParts) return null + + const serverAndMediaID = `${avatarURLParts[1]}/${avatarURLParts[2]}` + const unsignedHash = hasher.h64(serverAndMediaID) + const signedHash = unsignedHash - 0x8000000000000000n // shifting down to signed 64-bit range + db.prepare("INSERT OR IGNORE INTO media_proxy (permitted_hash) VALUES (?)").run(signedHash) + + return `${reg.ooye.bridge_origin}/download/matrix/${serverAndMediaID}` +} + module.exports.BLOCK_ELEMENTS = BLOCK_ELEMENTS module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord module.exports.getPublicUrlForMxc = getPublicUrlForMxc diff --git a/m2d/converters/utils.test.js b/src/m2d/converters/utils.test.js similarity index 100% rename from m2d/converters/utils.test.js rename to src/m2d/converters/utils.test.js diff --git a/m2d/event-dispatcher.js b/src/m2d/event-dispatcher.js similarity index 100% rename from m2d/event-dispatcher.js rename to src/m2d/event-dispatcher.js diff --git a/matrix/api.js b/src/matrix/api.js similarity index 100% rename from matrix/api.js rename to src/matrix/api.js diff --git a/matrix/api.test.js b/src/matrix/api.test.js similarity index 100% rename from matrix/api.test.js rename to src/matrix/api.test.js diff --git a/matrix/appservice.js b/src/matrix/appservice.js similarity index 100% rename from matrix/appservice.js rename to src/matrix/appservice.js diff --git a/matrix/file.js b/src/matrix/file.js similarity index 100% rename from matrix/file.js rename to src/matrix/file.js diff --git a/matrix/file.test.js b/src/matrix/file.test.js similarity index 100% rename from matrix/file.test.js rename to src/matrix/file.test.js diff --git a/matrix/kstate.js b/src/matrix/kstate.js similarity index 100% rename from matrix/kstate.js rename to src/matrix/kstate.js diff --git a/matrix/kstate.test.js b/src/matrix/kstate.test.js similarity index 100% rename from matrix/kstate.test.js rename to src/matrix/kstate.test.js diff --git a/matrix/matrix-command-handler.js b/src/matrix/matrix-command-handler.js similarity index 100% rename from matrix/matrix-command-handler.js rename to src/matrix/matrix-command-handler.js diff --git a/matrix/mreq.js b/src/matrix/mreq.js similarity index 100% rename from matrix/mreq.js rename to src/matrix/mreq.js diff --git a/matrix/power.js b/src/matrix/power.js similarity index 100% rename from matrix/power.js rename to src/matrix/power.js diff --git a/matrix/power.test.js b/src/matrix/power.test.js similarity index 100% rename from matrix/power.test.js rename to src/matrix/power.test.js diff --git a/matrix/read-registration.js b/src/matrix/read-registration.js similarity index 100% rename from matrix/read-registration.js rename to src/matrix/read-registration.js diff --git a/matrix/read-registration.test.js b/src/matrix/read-registration.test.js similarity index 100% rename from matrix/read-registration.test.js rename to src/matrix/read-registration.test.js diff --git a/matrix/txnid.js b/src/matrix/txnid.js similarity index 100% rename from matrix/txnid.js rename to src/matrix/txnid.js diff --git a/matrix/txnid.test.js b/src/matrix/txnid.test.js similarity index 100% rename from matrix/txnid.test.js rename to src/matrix/txnid.test.js diff --git a/passthrough.js b/src/passthrough.js similarity index 100% rename from passthrough.js rename to src/passthrough.js diff --git a/stdin.js b/src/stdin.js similarity index 93% rename from stdin.js rename to src/stdin.js index 5e23f72..cabd8ce 100644 --- a/stdin.js +++ b/src/stdin.js @@ -2,12 +2,12 @@ const repl = require("repl") const util = require("util") -const {addbot} = require("./addbot") +const {addbot} = require("../addbot") const passthrough = require("./passthrough") const {discord, config, sync, db} = passthrough -const data = sync.require("./test/data") +const data = sync.require("../test/data") const createSpace = sync.require("./d2m/actions/create-space") const createRoom = sync.require("./d2m/actions/create-room") const registerUser = sync.require("./d2m/actions/register-user") @@ -32,7 +32,6 @@ if (process.stdin.isTTY) { } else { Object.assign(passthrough.repl.context, extraContext) } - // @ts-expect-error Says exit isn't assignable to a string sync.addTemporaryListener(passthrough.repl, "exit", () => process.exit()) }) } diff --git a/types.d.ts b/src/types.d.ts similarity index 99% rename from types.d.ts rename to src/types.d.ts index 8eeda6c..93bfc75 100644 --- a/types.d.ts +++ b/src/types.d.ts @@ -21,6 +21,7 @@ export type AppServiceRegistrationConfig = { max_file_size: number server_name: string server_origin: string + bridge_origin: string content_length_workaround: boolean include_user_id_in_mxid: boolean invite: string[] diff --git a/types.js b/src/types.js similarity index 100% rename from types.js rename to src/types.js diff --git a/start.js b/start.js index 1ece1dd..d6bd4c9 100644 --- a/start.js +++ b/start.js @@ -1,32 +1,32 @@ // @ts-check const sqlite = require("better-sqlite3") -const migrate = require("./db/migrate") +const migrate = require("./src/db/migrate") const HeatSync = require("heatsync") const config = require("./config") -const passthrough = require("./passthrough") -const db = new sqlite("db/ooye.db") +const passthrough = require("./src/passthrough") +const db = new sqlite("src/db/ooye.db") /** @type {import("heatsync").default} */ // @ts-ignore const sync = new HeatSync() Object.assign(passthrough, {config, sync, db}) -const DiscordClient = require("./d2m/discord-client") +const DiscordClient = require("./src/d2m/discord-client") const discord = new DiscordClient(config.discordToken, "full") passthrough.discord = discord -const {as} = require("./matrix/appservice") +const {as} = require("./src/matrix/appservice") passthrough.as = as -const orm = sync.require("./db/orm") +const orm = sync.require("./src/db/orm") passthrough.from = orm.from passthrough.select = orm.select -const power = require("./matrix/power.js") -sync.require("./m2d/event-dispatcher") +const power = require("./src/matrix/power.js") +sync.require("./src/m2d/event-dispatcher") ;(async () => { await migrate.migrate(db) @@ -34,5 +34,5 @@ sync.require("./m2d/event-dispatcher") console.log("Discord gateway started") await power.applyPower() - require("./stdin") + require("./src/stdin") })() diff --git a/test/test.js b/test/test.js index 1941ea2..c898ad1 100644 --- a/test/test.js +++ b/test/test.js @@ -4,7 +4,7 @@ const fs = require("fs") const {join} = require("path") const stp = require("stream").promises const sqlite = require("better-sqlite3") -const migrate = require("../db/migrate") +const migrate = require("../src/db/migrate") const HeatSync = require("heatsync") const {test} = require("supertape") const data = require("./data") @@ -14,15 +14,16 @@ const fetch = require("node-fetch") const {green} = require("colorette") const config = require("../config") -const passthrough = require("../passthrough") +const passthrough = require("../src/passthrough") const db = new sqlite(":memory:") -const {reg} = require("../matrix/read-registration") +const {reg} = require("../src/matrix/read-registration") reg.ooye.server_origin = "https://matrix.cadence.moe" // so that tests will pass even when hard-coded reg.ooye.server_name = "cadence.moe" reg.id = "baby" // don't actually take authenticated actions on the server reg.as_token = "baby" reg.hs_token = "baby" +reg.ooye.bridge_origin = "https://bridge.example.org" reg.ooye.invite = [] const sync = new HeatSync({watchFS: false}) @@ -47,11 +48,11 @@ const discord = { Object.assign(passthrough, { discord, config, sync, db }) -const orm = sync.require("../db/orm") +const orm = sync.require("../src/db/orm") passthrough.from = orm.from passthrough.select = orm.select -const file = sync.require("../matrix/file") +const file = sync.require("../src/matrix/file") /* c8 ignore next */ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not allowed to upload files during testing.\nURL: ${url}`) } @@ -112,28 +113,28 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not db.exec(fs.readFileSync(join(__dirname, "ooye-test-data.sql"), "utf8")) - require("../db/orm.test") - require("../discord/utils.test") - require("../matrix/kstate.test") - require("../matrix/api.test") - require("../matrix/file.test") - //require("../matrix/power.test") - require("../matrix/read-registration.test") - require("../matrix/txnid.test") - require("../d2m/actions/create-room.test") - require("../d2m/actions/create-space.test") - require("../d2m/actions/register-user.test") - require("../d2m/converters/edit-to-changes.test") - require("../d2m/converters/emoji-to-key.test") - require("../d2m/converters/lottie.test") - require("../d2m/converters/message-to-event.test") - require("../d2m/converters/message-to-event.embeds.test") - require("../d2m/converters/message-to-event.pk.test") - require("../d2m/converters/pins-to-list.test") - require("../d2m/converters/remove-reaction.test") - require("../d2m/converters/thread-to-announcement.test") - require("../d2m/converters/user-to-mxid.test") - require("../m2d/converters/event-to-message.test") - require("../m2d/converters/utils.test") - require("../m2d/converters/emoji-sheet.test") + require("../src/db/orm.test") + require("../src/discord/utils.test") + require("../src/matrix/kstate.test") + require("../src/matrix/api.test") + require("../src/matrix/file.test") + require("../src/matrix/power.test") + require("../src/matrix/read-registration.test") + require("../src/matrix/txnid.test") + require("../src/d2m/actions/create-room.test") + require("../src/d2m/actions/create-space.test") + require("../src/d2m/actions/register-user.test") + require("../src/d2m/converters/edit-to-changes.test") + require("../src/d2m/converters/emoji-to-key.test") + require("../src/d2m/converters/lottie.test") + require("../src/d2m/converters/message-to-event.test") + require("../src/d2m/converters/message-to-event.embeds.test") + require("../src/d2m/converters/message-to-event.pk.test") + require("../src/d2m/converters/pins-to-list.test") + require("../src/d2m/converters/remove-reaction.test") + require("../src/d2m/converters/thread-to-announcement.test") + require("../src/d2m/converters/user-to-mxid.test") + require("../src/m2d/converters/event-to-message.test") + require("../src/m2d/converters/utils.test") + require("../src/m2d/converters/emoji-sheet.test") })()