From 42b331135d2f444db0c49520456d325ab38617e9 Mon Sep 17 00:00:00 2001 From: bbedward Date: Mon, 8 Sep 2025 22:16:17 -0400 Subject: [PATCH 1/2] allow overriding ooye data directory --- scripts/backfill.js | 4 +++- scripts/check-migrate.js | 5 ++--- scripts/migrate-from-old-bridge.js | 3 ++- scripts/remove-old-bridged-users.js | 4 ++-- scripts/save-channel-names-to-db.js | 4 ++-- scripts/save-event-types-to-db.js | 4 ++-- scripts/setup.js | 3 ++- scripts/start-server.js | 4 ++-- scripts/wal.js | 4 ++-- src/db/database.js | 16 ++++++++++++++++ start.js | 4 ++-- 11 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 src/db/database.js diff --git a/scripts/backfill.js b/scripts/backfill.js index 12d9da3..0e0e4c6 100644 --- a/scripts/backfill.js +++ b/scripts/backfill.js @@ -12,6 +12,7 @@ if (!channelID) { const assert = require("assert/strict") const sqlite = require("better-sqlite3") +const path = require("path") const backfill = new sqlite("scripts/backfill.db") backfill.prepare("CREATE TABLE IF NOT EXISTS backfill (channel_id TEXT NOT NULL, message_id INTEGER NOT NULL, PRIMARY KEY (channel_id, message_id))").run() @@ -19,9 +20,10 @@ const HeatSync = require("heatsync") const {reg} = require("../src/matrix/read-registration") const passthrough = require("../src/passthrough") +const {getDatabase} = require("../src/db/database") const sync = new HeatSync({watchFS: false}) -const db = new sqlite("ooye.db") +const db = getDatabase() Object.assign(passthrough, {sync, db}) const DiscordClient = require("../src/d2m/discord-client") diff --git a/scripts/check-migrate.js b/scripts/check-migrate.js index 04a4402..dd31ec6 100755 --- a/scripts/check-migrate.js +++ b/scripts/check-migrate.js @@ -4,10 +4,9 @@ // Trigger the database migration flow and exit after committing. // You can use this to run migrations locally and check the result using sqlitebrowser. -const sqlite = require("better-sqlite3") - const passthrough = require("../src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const migrate = require("../src/db/migrate") Object.assign(passthrough, {db}) diff --git a/scripts/migrate-from-old-bridge.js b/scripts/migrate-from-old-bridge.js index 36cf884..5a71ab0 100755 --- a/scripts/migrate-from-old-bridge.js +++ b/scripts/migrate-from-old-bridge.js @@ -16,7 +16,8 @@ const oldAT = reg.old_bridge.as_token const newAT = reg.as_token const oldDB = new sqlite(reg.old_bridge.database) -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() db.exec(`CREATE TABLE IF NOT EXISTS half_shot_migration ( discord_channel TEXT NOT NULL, diff --git a/scripts/remove-old-bridged-users.js b/scripts/remove-old-bridged-users.js index d8910bd..8252893 100644 --- a/scripts/remove-old-bridged-users.js +++ b/scripts/remove-old-bridged-users.js @@ -3,8 +3,8 @@ const HeatSync = require("heatsync") const sync = new HeatSync({watchFS: false}) -const sqlite = require("better-sqlite3") -const db = new sqlite("db/ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const passthrough = require("../src/passthrough") Object.assign(passthrough, {db, sync}) diff --git a/scripts/save-channel-names-to-db.js b/scripts/save-channel-names-to-db.js index 1f36a73..e90e567 100755 --- a/scripts/save-channel-names-to-db.js +++ b/scripts/save-channel-names-to-db.js @@ -1,12 +1,12 @@ #!/usr/bin/env node // @ts-check -const sqlite = require("better-sqlite3") const HeatSync = require("heatsync") const {reg} = require("../src/matrix/read-registration") const passthrough = require("../src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const sync = new HeatSync({watchFS: false}) diff --git a/scripts/save-event-types-to-db.js b/scripts/save-event-types-to-db.js index edfbb9c..dd84866 100755 --- a/scripts/save-event-types-to-db.js +++ b/scripts/save-event-types-to-db.js @@ -1,11 +1,11 @@ #!/usr/bin/env node // @ts-check -const sqlite = require("better-sqlite3") const HeatSync = require("heatsync") const passthrough = require("../src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const sync = new HeatSync({watchFS: false}) diff --git a/scripts/setup.js b/scripts/setup.js index 6bff293..b980ef1 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -34,7 +34,8 @@ if (fs.existsSync("db")) { } const passthrough = require("../src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const migrate = require("../src/db/migrate") const sync = new HeatSync({watchFS: false}) diff --git a/scripts/start-server.js b/scripts/start-server.js index 0d4753a..86e11ca 100755 --- a/scripts/start-server.js +++ b/scripts/start-server.js @@ -4,13 +4,13 @@ const {createServer} = require("http") const EventEmitter = require("events") const {createApp, createRouter, toNodeListener} = require("h3") -const sqlite = require("better-sqlite3") const migrate = require("../src/db/migrate") const HeatSync = require("heatsync") const {reg} = require("../src/matrix/read-registration") const passthrough = require("../src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("../src/db/database") +const db = getDatabase() const sync = new HeatSync() diff --git a/scripts/wal.js b/scripts/wal.js index 625f2ba..3f8cec9 100755 --- a/scripts/wal.js +++ b/scripts/wal.js @@ -1,7 +1,7 @@ #!/usr/bin/env node // @ts-check -const sqlite = require("better-sqlite3") -const db = new sqlite("ooye.db", {fileMustExist: true}) +const {getDatabase} = require("../src/db/database") +const db = getDatabase({fileMustExist: true}) db.pragma("journal_mode = wal") db.close() diff --git a/src/db/database.js b/src/db/database.js new file mode 100644 index 0000000..861fda8 --- /dev/null +++ b/src/db/database.js @@ -0,0 +1,16 @@ +// @ts-check + +const sqlite = require("better-sqlite3") +const path = require("path") + +/** + * Create a new SQLite database instance + * @param {import("better-sqlite3").Options} [options] - SQLite options + * @returns {import("better-sqlite3").Database} Database instance + */ +function getDatabase(options = {}) { + const dataDir = process.env.OOYE_DATA_DIR || process.cwd() + return new sqlite(path.join(dataDir, "ooye.db"), options) +} + +module.exports = {getDatabase} \ No newline at end of file diff --git a/start.js b/start.js index ca6212b..66fb920 100755 --- a/start.js +++ b/start.js @@ -2,13 +2,13 @@ // @ts-check const fs = require("fs") -const sqlite = require("better-sqlite3") const migrate = require("./src/db/migrate") const HeatSync = require("heatsync") const {reg} = require("./src/matrix/read-registration") const passthrough = require("./src/passthrough") -const db = new sqlite("ooye.db") +const {getDatabase} = require("./src/db/database") +const db = getDatabase() const sync = new HeatSync({watchFunction: fs.watchFile}) From e19703ef03d471f7ce9f2cb441eaf928a9bd72ba Mon Sep 17 00:00:00 2001 From: bbedward Date: Mon, 8 Sep 2025 22:21:13 -0400 Subject: [PATCH 2/2] configurable read_only_room_events_default_power --- src/d2m/actions/create-room.js | 8 +++++--- src/d2m/actions/register-user.js | 2 +- src/matrix/read-registration.js | 3 ++- src/types.d.ts | 1 + 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/d2m/actions/create-room.js b/src/d2m/actions/create-room.js index ff5782d..07c7237 100644 --- a/src/d2m/actions/create-room.js +++ b/src/d2m/actions/create-room.js @@ -40,7 +40,9 @@ const PRIVACY_ENUMS = { const DEFAULT_PRIVACY_LEVEL = 0 -const READ_ONLY_ROOM_EVENTS_DEFAULT_POWER = 50 +function getReadOnlyRoomEventsDefaultPower() { + return reg.ooye.read_only_room_events_default_power ?? 50 +} /** @type {Map>} channel ID -> Promise */ const inflightRoomCreate = new Map() @@ -148,7 +150,7 @@ async function channelToKState(channel, guild, di) { "m.room.join_rules/": join_rules, /** @type {Ty.Event.M_Power_Levels} */ "m.room.power_levels/": { - events_default: everyoneCanSend ? 0 : READ_ONLY_ROOM_EVENTS_DEFAULT_POWER, + events_default: everyoneCanSend ? 0 : getReadOnlyRoomEventsDefaultPower(), events: { "m.reaction": 0, "m.room.redaction": 0 // only affects redactions of own events, required to be able to un-react @@ -559,7 +561,7 @@ async function createAllForGuild(guildID) { } module.exports.DEFAULT_PRIVACY_LEVEL = DEFAULT_PRIVACY_LEVEL -module.exports.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER = READ_ONLY_ROOM_EVENTS_DEFAULT_POWER +module.exports.getReadOnlyRoomEventsDefaultPower = getReadOnlyRoomEventsDefaultPower module.exports.PRIVACY_ENUMS = PRIVACY_ENUMS module.exports.createRoom = createRoom module.exports.ensureRoom = ensureRoom diff --git a/src/d2m/actions/register-user.js b/src/d2m/actions/register-user.js index 674853a..8f2a9b5 100644 --- a/src/d2m/actions/register-user.js +++ b/src/d2m/actions/register-user.js @@ -165,7 +165,7 @@ function memberToPowerLevel(user, member, guild, channel) { /* PL 50 = if room is read-only but the user has been specially allowed to send messages */ const everyoneCanSend = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages) const userCanSend = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.SendMessages) - if (!everyoneCanSend && userCanSend) return createRoom.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER + if (!everyoneCanSend && userCanSend) return createRoom.getReadOnlyRoomEventsDefaultPower() /* PL 20 = Mention Everyone for technical reasons. */ const everyoneCanMentionEveryone = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone) const userCanMentionEveryone = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.MentionEveryone) diff --git a/src/matrix/read-registration.js b/src/matrix/read-registration.js index d126851..6c713ba 100644 --- a/src/matrix/read-registration.js +++ b/src/matrix/read-registration.js @@ -57,7 +57,8 @@ function getTemplateRegistration(serverName) { max_file_size: 5000000, content_length_workaround: false, include_user_id_in_mxid: false, - invite: [] + invite: [], + read_only_room_events_default_power: 50 } } } diff --git a/src/types.d.ts b/src/types.d.ts index 37da633..e2f45ae 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -31,6 +31,7 @@ export type AppServiceRegistrationConfig = { discord_origin?: string discord_cdn_origin?: string, web_password: string + read_only_room_events_default_power?: number } old_bridge?: { as_token: string