diff --git a/README.md b/README.md index 5e69fa701fa8442977e7b904b3b84b5630ed46e2..c83620ae37be26a05c40dc5d696514c51982d2f5 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ should show up in the network list on Riot and other clients. * Create a new application via https://discordapp.com/developers/applications * Make sure to create a bot user. Fill in ``config.yaml`` -* Run ``npm run getbotlink`` to get a authorisation link. +* Run ``npm run addbot`` to get a authorisation link. * Give this link to owners of the guilds you plan to bridge. * Finally, you can join a room with ``#_discord_guildid_channelid`` * These can be taken from the url ("/$GUILDID/$CHANNELID") when you are in a channel. diff --git a/package.json b/package.json index 866d79cea6d801b7629302e9e7a6c59e62f3058e..1f2129c9f2cd246465a0b465f831b6d8f0a5a49f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "coverage": "istanbul --include-all-sources cover -x build/src/discordas.js _mocha -- build/test/ -R spec", "build": "tsc", "start": "npm run-script build && node ./build/src/discordas.js -p 9005 -c config.yaml", - "getbotlink": "node ./build/tools/addbot.js", + "addbot": "node ./build/tools/addbot.js", "adminme": "node ./build/tools/adminme.js", "usertool": "node ./build/tools/userClientTools.js", "directoryfix": "node ./build/tools/addRoomsToDirectory.js", diff --git a/src/clientfactory.ts b/src/clientfactory.ts index bd76fe528bcc8c5b4208c5ab5e7f1224ffc514af..54e2694ca422b4a611867f2eccb2c21dee170303 100644 --- a/src/clientfactory.ts +++ b/src/clientfactory.ts @@ -83,12 +83,12 @@ export class DiscordClientFactory { return this.clients.get(userId) as DiscordClient; } - const discordIds = await this.store.get_user_discord_ids(userId); + const discordIds = await this.store.getUserDiscordIds(userId); if (discordIds.length === 0) { return this.botClient; } // TODO: Select a profile based on preference, not the first one. - const token = await this.store.get_token(discordIds[0]); + const token = await this.store.getToken(discordIds[0]); const client = new DiscordClient({ fetchAllMembers: true, messageCacheLifetime: 5, diff --git a/src/db/connector.ts b/src/db/connector.ts index e6bc7a0f601708bb3ed04fbe30563d938c8e787c..64fd220ee0efaa856cd7f3e9cb6862d8f0603fbb 100644 --- a/src/db/connector.ts +++ b/src/db/connector.ts @@ -26,7 +26,7 @@ export interface ISqlRow { export interface IDatabaseConnector { Open(): void; - Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow>; + Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow|null>; All(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow[]>; Run(sql: string, parameters?: ISqlCommandParameters): Promise<void>; Close(): Promise<void>; diff --git a/src/db/dbdataemoji.ts b/src/db/dbdataemoji.ts index 5f211a595842d17df9c56235dda3cb2bccdd690b..9b076b6c407c9fb41291a6a42d80111203623c7c 100644 --- a/src/db/dbdataemoji.ts +++ b/src/db/dbdataemoji.ts @@ -43,7 +43,7 @@ export class DbEmoji implements IDbData { mxc: params.mxc_url, }); this.Result = Boolean(row); // check if row exists - if (this.Result) { + if (this.Result && row) { this.EmojiId = row.emoji_id as string; this.Name = row.name as string; this.Animated = Boolean(row.animated); diff --git a/src/db/postgres.ts b/src/db/postgres.ts index a7635eb9c80ba374ac38441b022e3eeb77199355..0b41112e95378845c20e3d9d18a84705f5f6e549 100644 --- a/src/db/postgres.ts +++ b/src/db/postgres.ts @@ -44,7 +44,7 @@ export class Postgres implements IDatabaseConnector { this.db = pgp(this.connectionString); } - public async Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow> { + public async Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow|null> { log.silly("Get:", sql); return this.db.oneOrNone(Postgres.ParameterizeSql(sql), parameters); } @@ -63,7 +63,7 @@ export class Postgres implements IDatabaseConnector { public async Run(sql: string, parameters?: ISqlCommandParameters): Promise<void> { log.silly("Run:", sql); - return this.db.oneOrNone(Postgres.ParameterizeSql(sql), parameters); + return this.db.oneOrNone(Postgres.ParameterizeSql(sql), parameters).then(() => {}); } public async Close(): Promise<void> { diff --git a/src/db/schema/v1.ts b/src/db/schema/v1.ts index 63c04471dccfd60e48dfc493bfcd9f3b13a8fe15..f7737ddf17bbbeb167809947b093612fc58dca26 100644 --- a/src/db/schema/v1.ts +++ b/src/db/schema/v1.ts @@ -19,12 +19,12 @@ import {DiscordStore} from "../../store"; export class Schema implements IDbSchema { public description = "Schema, Client Auth Table"; public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE schema ( version INTEGER UNIQUE NOT NULL );`, "schema"); await store.db.Exec("INSERT INTO schema VALUES (0);"); - await store.create_table(` + await store.createTable(` CREATE TABLE user_tokens ( userId TEXT UNIQUE NOT NULL, token TEXT UNIQUE NOT NULL diff --git a/src/db/schema/v2.ts b/src/db/schema/v2.ts index ce566f99189618da9642bad7b410ef5f61e34b7f..4a6ff55c4fc8f309b64a3f9831849352e0927c07 100644 --- a/src/db/schema/v2.ts +++ b/src/db/schema/v2.ts @@ -20,13 +20,13 @@ export class Schema implements IDbSchema { public description = "Create DM Table, User Options"; public async run(store: DiscordStore): Promise<void> { await Promise.all([ - store.create_table(` + store.createTable(` CREATE TABLE dm_rooms ( discord_id TEXT NOT NULL, channel_id TEXT NOT NULL, room_id TEXT UNIQUE NOT NULL );`, "dm_rooms"), - store.create_table(` + store.createTable(` CREATE TABLE client_options ( discord_id TEXT UNIQUE NOT NULL, options INTEGER NOT NULL diff --git a/src/db/schema/v3.ts b/src/db/schema/v3.ts index c879aea95f56ade449161be22bcedc0a0dafbb9b..a24a13943ea97285fdccd25b7456d98b518e2043 100644 --- a/src/db/schema/v3.ts +++ b/src/db/schema/v3.ts @@ -24,13 +24,13 @@ const log = new Log("SchemaV3"); export class Schema implements IDbSchema { public description = "user_tokens split into user_id_discord_id"; public async run(store: DiscordStore): Promise<void> { - await Promise.all([store.create_table(` + await Promise.all([store.createTable(` CREATE TABLE user_id_discord_id ( discord_id TEXT NOT NULL, user_id TEXT NOT NULL, PRIMARY KEY(discord_id, user_id) );`, "user_id_discord_id"), - store.create_table(` + store.createTable(` CREATE TABLE discord_id_token ( discord_id TEXT UNIQUE NOT NULL, token TEXT NOT NULL, @@ -39,7 +39,7 @@ export class Schema implements IDbSchema { )]); // Backup before moving data. - await store.backup_database(); + await store.backupDatabase(); // Move old data to new tables. await this.moveUserIds(store); diff --git a/src/db/schema/v4.ts b/src/db/schema/v4.ts index 8787f455d7b3ab28e8294a1b936f6ed741385227..6a44d19a9719593f15da96a3727fa96fac5adef2 100644 --- a/src/db/schema/v4.ts +++ b/src/db/schema/v4.ts @@ -20,7 +20,7 @@ import {DiscordStore} from "../../store"; export class Schema implements IDbSchema { public description = "create guild emoji table"; public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE guild_emoji ( emoji_id TEXT NOT NULL, guild_id TEXT NOT NULL, diff --git a/src/db/schema/v5.ts b/src/db/schema/v5.ts index e9fa7fe4be01134da08ed78a3d58a9d58233992a..675bbfaa69b11808b05dac85c0b1565b4ace2dc1 100644 --- a/src/db/schema/v5.ts +++ b/src/db/schema/v5.ts @@ -20,7 +20,7 @@ import {DiscordStore} from "../../store"; export class Schema implements IDbSchema { public description = "create event_store table"; public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE event_store ( matrix_id TEXT NOT NULL, discord_id TEXT NOT NULL, diff --git a/src/db/schema/v6.ts b/src/db/schema/v6.ts index 02659d9d4a0bb7e96c32a41d1d5224230128e1af..ce9f8f0fe0a1cbc1e7195f718b336dad0a418648 100644 --- a/src/db/schema/v6.ts +++ b/src/db/schema/v6.ts @@ -23,13 +23,13 @@ export class Schema implements IDbSchema { await store.db.Run( `DROP TABLE IF EXISTS event_store;`, ); - await store.create_table(` + await store.createTable(` CREATE TABLE event_store ( matrix_id TEXT NOT NULL, discord_id TEXT NOT NULL, PRIMARY KEY(matrix_id, discord_id) );`, "event_store"); - await store.create_table(` + await store.createTable(` CREATE TABLE discord_msg_store ( msg_id TEXT NOT NULL, guild_id TEXT NOT NULL, diff --git a/src/db/schema/v7.ts b/src/db/schema/v7.ts index fa025f280cdf2ff6d9527645e6fb8e2430af3fa4..879b34e1ecde331c5839f8275b58a301dfc0336b 100644 --- a/src/db/schema/v7.ts +++ b/src/db/schema/v7.ts @@ -23,7 +23,7 @@ const log = new Log("SchemaV7"); export class Schema implements IDbSchema { public description = "create guild emoji table"; public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE emoji ( emoji_id TEXT NOT NULL, name TEXT NOT NULL, diff --git a/src/db/schema/v8.ts b/src/db/schema/v8.ts index 96890f97322fb1b7b407a93d9c09d6ddc977e525..de611de92a16e18fd383ed252d983e9cf094b072 100644 --- a/src/db/schema/v8.ts +++ b/src/db/schema/v8.ts @@ -31,7 +31,7 @@ export class Schema implements IDbSchema { } public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE remote_room_data ( room_id TEXT NOT NULL, discord_guild TEXT NOT NULL, @@ -48,7 +48,7 @@ export class Schema implements IDbSchema { PRIMARY KEY(room_id) );`, "remote_room_data"); - await store.create_table(` + await store.createTable(` CREATE TABLE room_entries ( id TEXT NOT NULL, matrix_id TEXT, diff --git a/src/db/schema/v9.ts b/src/db/schema/v9.ts index 59aa65c4e2ead21845cdfd4af07b01f8ec51affb..3fddce0ffb4cb32640dfbd4715738d1e7a78d24c 100644 --- a/src/db/schema/v9.ts +++ b/src/db/schema/v9.ts @@ -32,7 +32,7 @@ export class Schema implements IDbSchema { } public async run(store: DiscordStore): Promise<void> { - await store.create_table(` + await store.createTable(` CREATE TABLE remote_user_guild_nicks ( remote_id TEXT NOT NULL, guild_id TEXT NOT NULL, @@ -40,7 +40,7 @@ export class Schema implements IDbSchema { PRIMARY KEY(remote_id, guild_id) );`, "remote_user_guild_nicks"); - await store.create_table(` + await store.createTable(` CREATE TABLE remote_user_data ( remote_id TEXT NOT NULL, displayname TEXT, @@ -49,7 +49,7 @@ export class Schema implements IDbSchema { PRIMARY KEY(remote_id) );`, "remote_user_data"); - await store.create_table(` + await store.createTable(` CREATE TABLE user_entries ( matrix_id TEXT, remote_id TEXT, diff --git a/src/db/sqlite3.ts b/src/db/sqlite3.ts index c7a706e742baedee76e940c67eba9491b865c901..9076798fe57a9661b80ae610ef9ea8276577ddf7 100644 --- a/src/db/sqlite3.ts +++ b/src/db/sqlite3.ts @@ -30,7 +30,7 @@ export class SQLite3 implements IDatabaseConnector { this.db = new Database(this.filename); } - public async Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow> { + public async Get(sql: string, parameters?: ISqlCommandParameters): Promise<ISqlRow|null> { log.silly("Get:", sql); return this.db.prepare(sql).get(parameters || []); } diff --git a/src/store.ts b/src/store.ts index eb236d6d4d8ebfe42d651881df892d9f1c154edd..ebff5a1e69dac1e9dd202928e3c15422952a3a70 100644 --- a/src/store.ts +++ b/src/store.ts @@ -55,7 +55,7 @@ export class DiscordStore { return this.pUserStore; } - public async backup_database(): Promise<void|{}> { + public async backupDatabase(): Promise<void|{}> { if (this.config.filename == null) { log.warn("Backups not supported on non-sqlite connector"); return; @@ -96,7 +96,7 @@ export class DiscordStore { const SCHEMA_ROOM_STORE_REQUIRED = 8; const SCHEMA_USER_STORE_REQUIRED = 9; log.info("Starting DB Init"); - await this.open_database(); + await this.openDatabase(); let version = await this.getSchemaVersion(); const targetSchema = overrideSchema || CURRENT_SCHEMA; log.info(`Database schema version is ${version}, latest version is ${targetSchema}`); @@ -136,7 +136,7 @@ export class DiscordStore { await this.db.Close(); } - public async create_table(statement: string, tablename: string): Promise<void|Error> { + public async createTable(statement: string, tablename: string): Promise<void|Error> { try { await this.db.Exec(statement); log.info("Created table", tablename); @@ -145,8 +145,8 @@ export class DiscordStore { } } - public async add_user_token(userId: string, discordId: string, token: string): Promise<void> { - log.silly("SQL", "add_user_token => ", userId); + public async addUserToken(userId: string, discordId: string, token: string): Promise<void> { + log.silly("SQL", "addUserToken => ", userId); try { await Promise.all([ this.db.Run( @@ -172,8 +172,8 @@ export class DiscordStore { } } - public async delete_user_token(discordId: string): Promise<void> { - log.silly("SQL", "delete_user_token => ", discordId); + public async deleteUserToken(discordId: string): Promise<void> { + log.silly("SQL", "deleteUserToken => ", discordId); try { await Promise.all([ this.db.Run( @@ -197,8 +197,8 @@ export class DiscordStore { } } - public async get_user_discord_ids(userId: string): Promise<string[]> { - log.silly("SQL", "get_user_discord_ids => ", userId); + public async getUserDiscordIds(userId: string): Promise<string[]> { + log.silly("SQL", "getUserDiscordIds => ", userId); try { const rows = await this.db.All( ` @@ -220,7 +220,7 @@ export class DiscordStore { } } - public async get_token(discordId: string): Promise<string> { + public async getToken(discordId: string): Promise<string> { log.silly("SQL", "discord_id_token => ", discordId); try { const row = await this.db.Get( @@ -238,63 +238,6 @@ export class DiscordStore { throw err; } } - - public async get_dm_room(discordId, discordChannel): Promise<string> { - log.silly("SQL", "get_dm_room => ", discordChannel); // Don't show discordId for privacy reasons - try { - const row = await this.db.Get( - ` - SELECT room_id - FROM dm_rooms - WHERE dm_rooms.discord_id = $discordId - AND dm_rooms.discord_channel = $discordChannel; - ` - , { - discordChannel, - discordId, - }); - return row ? row.room_id as string : ""; - } catch (err) { - log.error("Error getting room_id ", err.Error); - throw err; - } - } - - public async set_dm_room(discordId, discordChannel, roomId): Promise<void> { - log.silly("SQL", "set_dm_room => ", discordChannel); // Don't show discordId for privacy reasons - try { - await this.db.Run( - ` - REPLACE INTO dm_rooms (discord_id,discord_channel,room_id) - VALUES ($discordId,$discordChannel,$roomId); - ` - , { - discordChannel, - discordId, - roomId, - }); - } catch (err) { - log.error("Error executing set_dm_room query ", err.Error); - throw err; - } - } -/* - public async get_all_user_discord_ids(): Promise<any> { - log.silly("SQL", "get_users_tokens"); - try { - const rows = await this.db.All( - ` - SELECT * - FROM get_user_discord_ids - `, - ); - return rows; - } catch (err) { - log.error("Error getting user token ", err.Error); - throw err; - } - } -*/ // tslint:disable-next-line no-any public async Get<T extends IDbData>(dbType: {new(): T; }, params: any): Promise<T|null> { const dType = new dbType(); @@ -329,7 +272,7 @@ export class DiscordStore { let version = 0; try { const versionReply = await this.db.Get(`SELECT version FROM schema`); - version = versionReply.version as number; + version = versionReply!.version as number; } catch (er) { log.warn("Couldn't fetch schema version, defaulting to 0"); } @@ -346,7 +289,7 @@ export class DiscordStore { ); } - private async open_database(): Promise<void|Error> { + private async openDatabase(): Promise<void|Error> { if (this.config.filename) { log.info("Filename present in config, using sqlite"); this.db = new SQLite3(this.config.filename); diff --git a/test/test_clientfactory.ts b/test/test_clientfactory.ts index f31e9eeb5c39ca7d5bd98a9064cf78ab962d2f19..b3d6df755287c1cdfeebd53042c506c68b014a8f 100644 --- a/test/test_clientfactory.ts +++ b/test/test_clientfactory.ts @@ -29,7 +29,7 @@ const DiscordClientFactory = Proxyquire("../src/clientfactory", { }).DiscordClientFactory; const STORE = { - get_token: async (discordid: string) => { + getToken: async (discordid: string) => { if (discordid === "12345") { return "passme"; } else if (discordid === "1234555") { @@ -37,7 +37,7 @@ const STORE = { } throw new Error("Token not found"); }, - get_user_discord_ids: async (userid: string) => { + getUserDiscordIds: async (userid: string) => { if (userid === "@valid:localhost") { return ["12345"]; } else if (userid === "@invalid:localhost") { diff --git a/test/test_store.ts b/test/test_store.ts index cc628bde0871a6c42214fad45e61d46782763bc4..6c286408ef2d516dc2ec1467addfab42029a58c8 100644 --- a/test/test_store.ts +++ b/test/test_store.ts @@ -37,11 +37,11 @@ describe("DiscordStore", () => { return store.init(); }); }); - describe("add_user_token", () => { + describe("addUserToken", () => { it("should not throw when adding an entry", async () => { const store = new DiscordStore(":memory:"); await store.init(); - await store.add_user_token("userid", "token", "discordid"); + await store.addUserToken("userid", "token", "discordid"); }); }); describe("Get|Insert|Update<DbEmoji>", () => { diff --git a/tools/userClientTools.ts b/tools/userClientTools.ts index f043bce3df72c831ab52685e8299e0b92fb63fa0..0aadc222ea6f8f4e4aa73d43429e922de2e8e409 100644 --- a/tools/userClientTools.ts +++ b/tools/userClientTools.ts @@ -108,7 +108,7 @@ Please enter your Discord Token }); } else if (options.remove) { rl.close(); - discordstore.delete_user_token(userid).then(() => { + discordstore.deleteUserToken(userid).then(() => { log.info("Completed successfully"); process.exit(0); }).catch((err) => { @@ -122,5 +122,5 @@ Please enter your Discord Token async function addUserToken(userid: string, token: string): Promise<void> { const clientFactory = new DiscordClientFactory(discordstore); const discordid = await clientFactory.getDiscordId(token); - await discordstore.add_user_token(userid, discordid, token); + await discordstore.addUserToken(userid, discordid, token); }