diff --git a/package.json b/package.json index e7d30f4..db1e496 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dotenv": "^8.2.0", "eris": "^0.13.3", "express-authentication": "^0.3.2", + "mariadb": "^2.4.2", "moment": "^2.27.0", "sequelize": "^6.3.3", "sqlite3": "^5.0.0" diff --git a/src/ajds-core.js b/src/ajds-core.js index 6e699b5..bae5d92 100644 --- a/src/ajds-core.js +++ b/src/ajds-core.js @@ -27,7 +27,7 @@ module.exports.ScoreMember = async function(erismember) if (erismember.bot) { ret.score = 999; - ret.warnins.push({warning:'member is bot', severity: 0}); + ret.warnings.push({warning:'member is bot', severity: 0}); return ret; } @@ -108,3 +108,17 @@ module.exports.NickCheck = function(name) return ret; } + +module.exports.IsIdentifierHarmful = function(ident) +{ + return !(/^[a-zA-Z0-9_ ][a-zA-Z0-9_!?-]{3,999}$/.test(ident)); +} + +module.exports.NeutralizeHarmfulIdentifier = function(ident) +{ + let base = ident.replace(/[^a-zA-Z0-9_ ]/g, ''); + while (base.length < 3) { + base += `UnPingableNick${Math.floor(Math.random()*10 + 0.5)}`; + } + return base; +} diff --git a/src/database.js b/src/database.js index dcbab68..63e08b7 100644 --- a/src/database.js +++ b/src/database.js @@ -2,6 +2,8 @@ const Logger = require('./logger.js'); const Sequelize = require('sequelize'); +let Database; + let Guild; module.exports.setup = async function() @@ -11,17 +13,22 @@ module.exports.setup = async function() if (process.env.NODE_ENV == "production") { Logger.database('Setting up production databse'); + Database = new Sequelize(process.env.DB_DATABASE, process.env.DB_USER, process.env.DB_PASS, { + dialect: 'mariadb', + logging: Logger.database + }); } else { Logger.database('Setting up development databse'); + Database = new Sequelize({ + dialect: 'sqlite', + storage: process.env.DB_DEV_LOCATION, + logging: Logger.database + }); } - const database = new Sequelize({ - dialect: 'sqlite', - storage: process.env.NODE_ENV == "production" ? process.env.DB_LOCATION : process.env.DB_DEV_LOCATION, - logging: Logger.database - }); - Guild = database.define('guild', { + + Guild = Database.define('guild', { id: { type: Sequelize.STRING, primaryKey: true, @@ -30,6 +37,7 @@ module.exports.setup = async function() name: Sequelize.STRING, prefix: Sequelize.STRING, logchannel: Sequelize.STRING, + guildsettings: Sequelize.JSON, logsettings: Sequelize.JSON, // JSON / Array modcases: Sequelize.INTEGER }, { @@ -38,8 +46,8 @@ module.exports.setup = async function() try { - await database.authenticate(); - await database.sync(); + await Database.authenticate(); + await Database.sync(); Logger.info('Database connection has been established successfully.'); } catch (error) { Logger.panic(`Unable to connect to the database: ${errpr}`); @@ -47,7 +55,7 @@ module.exports.setup = async function() } -module.exports.NewGuild = async function(id, name, prefix, logchannel, logsettings, modcases) +module.exports.NewGuild = async function(id, name, prefix, logchannel, guildsettings, logsettings, modcases) { try { let user = await Guild.create({ @@ -55,6 +63,7 @@ module.exports.NewGuild = async function(id, name, prefix, logchannel, logsettin name: name, prefix: prefix, logchannel: logchannel, // -1 if not set + guildsettings: guildsettings, logsettings: logsettings, modcases: modcases }); diff --git a/src/discord-commands.js b/src/discord-commands.js index b4f4cd7..97e15de 100644 --- a/src/discord-commands.js +++ b/src/discord-commands.js @@ -5,7 +5,7 @@ const Discord = require('./discord.js'); const DiscordHelpers = require('./discord-helpers.js'); const DiscordEmbed = require('./discord-embedbuilder.js'); -const CATV = require('./harmful.js'); +const AJDSCore = require('./ajds-core.js'); let Commands = []; @@ -16,7 +16,7 @@ module.exports.registerCommands = async function() Logger.info('Registering commands'); Commands['initserv'] = { command: 'initserv', alias: 'nil', name: 'Initialize Server', desc: 'Initialises a new Guild', callback: InitializeGuild, adminOnly: true }; - Commands['bedecent'] = { command: 'bedecent', alias: 'nil', name: 'Be decent', desc: 'Makes someone\'s nickname decent', callback: NeutralizeBadNickname, adminOnly: true}; + Commands['fixbadnick'] = { command: 'fixbadnick', alias: 'fixnick', name: 'Fix User Nickname', desc: 'Makes someone\'s nickname decent & pingable', callback: NeutralizeBadNickname, adminOnly: true}; Commands['setprefix'] = { command: 'setprefix', alias: 'prefix', name: 'Set Prefix', desc: 'Sets the servers prefix for the guild', callback: SetPrefix, adminOnly: true }; Commands['setfallbackchannel'] = { command: 'setlogchannel', alias: 'setlogchannel', name: 'Set Log Channel', desc: 'Sets the guild log channel to the current channel', callback: SetLogChannel, adminOnly: true }; Commands['me'] = { command: 'me', alias: 'nil', name: 'Me', desc: 'Returns the users profile on the logori site', callback: MeCommand, adminOnly: false}; @@ -50,7 +50,7 @@ module.exports.newMessage = async function(message) } catch (e) { GuildName = 'not defined'; } - Database.NewGuild(message.guildID, GuildName, '*', -1, {}, 0); + Database.NewGuild(message.guildID, GuildName, '*', -1, {}, {}, 0); GuildsAndPrefixs[message.guildID] = '*' } else { @@ -117,7 +117,7 @@ async function InitializeGuild(message, args) const guild = await Discord.bot.getRESTGuild(message.guildID); if (AlreadyGuild == -1) { - Database.NewGuild(guild.id, guild.name, '*', message.channel.id, {}, 0); + Database.NewGuild(guild.id, guild.name, '*', message.channel.id, {}, {}, 0); } else { if (AlreadyGuild.name != guild.name) { @@ -155,7 +155,7 @@ async function SetLogChannel(message, args) const guild = await Discord.bot.getRESTGuild(message.guildID); if (AlreadyGuild == -1) { - Database.NewGuild(guild.id, guild.name, '*', message.channel.id, {}, 0); + Database.NewGuild(guild.id, guild.name, '*', message.channel.id, {}, {}, 0); } else { if (AlreadyGuild.name != guild.name) { @@ -163,7 +163,7 @@ async function SetLogChannel(message, args) } Database.UpdateGuildLogChannel(guild.id, message.channel.id); } - + DiscordHelpers.SendMessageSafe(message.channel.id, 'Logging fallback channel set to this channel'); } @@ -176,7 +176,7 @@ async function NeutralizeBadNickname(message) { if (message.mentions.length < 1) { - Discord.bot.createMessage(message.channel.id, 'You must provide a user'); + DiscordHelpers.SendMessageSafe(message.channel.id, 'You must provide a user'); return; } @@ -185,8 +185,10 @@ async function NeutralizeBadNickname(message) try { await member.edit({ - nick: CATV.neutralizeHarmfulIdentifier(ident) - }); + nick: AJDSCore.NeutralizeHarmfulIdentifier(ident) + }); + + DiscordHelpers.SendMessageSafe(message.channel.id, '`1` Nickname successfully updated'); } - catch (e) {} + catch (e) {} } diff --git a/src/discord-events.js b/src/discord-events.js index 72e48e5..417d521 100644 --- a/src/discord-events.js +++ b/src/discord-events.js @@ -7,7 +7,6 @@ const DiscordHelpers = require('./discord-helpers.js'); const DiscordEmbed = require('./discord-embedbuilder.js'); const ADJSCore = require('./ajds-core.js'); -const CATV = require('./harmful.js'); const Eris = require('eris'); @@ -172,7 +171,7 @@ async function GuildCreate(guild) const AlreadyGuild = await Database.FetchGuild(guild.id); if (AlreadyGuild == -1) { - Database.NewGuild(guild.id, guild.name, '*', -1, {}, 0); + Database.NewGuild(guild.id, guild.name, '*', -1, {}, {}, 0); } else { if (AlreadyGuild.name == guild.name) return; Database.UpdateGuildName(guild.id, guild.name); @@ -559,24 +558,27 @@ async function GuildMemberAdd(guild, member) } } + let HarmfulName = ADJSCore.IsIdentifierHarmful(member.username); + let HarmfulStr; + if (HarmfulName) + { + HarmfulStr = '**Username warning: ** This member\'s username is un-pingable\n' + + try { + await member.edit({ + nick: ADJSCore.NeutralizeHarmfulIdentifier(member.username) + }); + HarmfulStr += '**Action Taken:** This member\'s username was changed. This will soon be a configurable option, but for now you if you would not like this feature, you can turn it off by removing the manage nicknames permission from logori.' + } catch (e) + { } + } + embed.field('​', `**Member:** ${member.mention} **AJDS Results:** *${AJDSScore.literalscore}* - ${WarningString ? WarningString : ''}`); + ${WarningString ? WarningString : ''}\n + ${HarmfulStr ? HarmfulStr : ''}`); - if (CATV.isIdentifierHarmful(member.username)) - { - embed.field('Username harmfulness', `This member's username is considered harmful.`); - - // How to disable this? Just remove nick management permission haha. - try - { - await member.edit({ - nick: CATV.neutralizeHarmfulIdentifier(member.username) - }); - } - catch (e) {} - } // embed.field('​', `${member.mention} is ${AddOrdinalSuffix(DiscordHelpers.GetMemberJoinPos(member.id, guild))} to join`); @@ -606,6 +608,11 @@ async function GuildMemberRemove(guild, member) DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); } +async function GuildMemberUpdate() +{ + +} + async function MessageDelete(message) { const FallbackChannel = await GetLogChannel(message.channel.guild.id); @@ -686,3 +693,5 @@ async function MessageUpdate(message, oldmessage) DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); } + + diff --git a/src/discord.js b/src/discord.js index 7e3436a..5ef4a6a 100644 --- a/src/discord.js +++ b/src/discord.js @@ -14,7 +14,8 @@ module.exports.setup = async function() if (!process.env.BOT_TOKEN) Logger.panic('No BOT_TOKEN in .env file!') - this.bot = new Eris(process.env.BOT_TOKEN, {allowedMentions: false, restMode: true}); + this.bot = new Eris(process.env.NODE_ENV == 'production' ? process.env.BOT_TOKEN : process.env.BOT_DEV_TOKEN, + {allowedMentions: false, restMode: true}); this.bot.on('ready', async () => { Logger.info(`Discord logged in as ${this.bot.user.username}#${this.bot.user.discriminator}`); diff --git a/src/harmful.js b/src/harmful.js deleted file mode 100644 index 46b2e40..0000000 --- a/src/harmful.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - To all of which I do solemnly and sincerely promise and swear, without - any hesitation, mental reservation, or secret evasion of mind in me - whatsoever; binding myself under no less a penalty than that of having - my throat cut across, my tongue torn out, and with my body buried in - the sands of the sea at low-water mark, where the tide ebbs and flows - twice in twenty-four hours, should I ever knowingly or willfully - violate this, my solemn Obligation of a Javascript user. So help - me God and make me steadfast to keep and perform the same. -*/ - -module.exports.isIdentifierHarmful = function(ident) -{ - return !(/^[a-zA-Z0-9_][a-zA-Z0-9_!?-]{3,20}$/.test(ident)); -} - -module.exports.neutralizeHarmfulIdentifier = function(ident) -{ - let base = ident.replace(/[^a-zA-Z0-9_]/g, ''); - if (base.length > 20) base = base.slice(0, 20); - while (base.length < 3) { - base += `${Math.floor(Math.random()*10 + 0.5)}`; - } - return base; -} diff --git a/src/logger.js b/src/logger.js index 9f92a99..2201dcd 100644 --- a/src/logger.js +++ b/src/logger.js @@ -3,13 +3,15 @@ const moment = require('moment'); const fs = require('fs'); let LogLevel = 1; -let Dialect = 'SQLITE'; +let Dialect; let logPath = 'logs.log'; let dateFormat = 'DD-MM-YY HH:mm:ss' module.exports.init = function(path) { if (path) logPath = path; + Dialect = process.env.NODE_ENV == 'production' ? 'MARIADB' : 'SQLITE'; + if (!fs.existsSync(logPath)) { fs.writeFileSync(logPath, ''); }