| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 | const got = require('got').extend( {	throwHttpErrors: false,	timeout: 5000,	headers: {		'User-Agent': 'Wiki-Bot/dashboard (Discord; ' + process.env.npm_package_name + ')'	},	responseType: 'json'} );const sqlite3 = require('sqlite3').verbose();const mode = ( process.env.READONLY ? sqlite3.OPEN_READONLY : sqlite3.OPEN_READWRITE );const db = new sqlite3.Database( './wikibot.db', mode, dberror => {	if ( dberror ) {		console.log( '- Dashboard: Error while connecting to the database: ' + dberror );		return dberror;	}	db.exec( 'PRAGMA foreign_keys = ON;', function (error) {		if ( error ) {			console.log( '- Dashboard: Error while enabling the foreign key constraint: ' + error );		}		console.log( '- Dashboard: Connected to the database.' );	} );} );/** * @typedef Settings * @property {String} state * @property {String} access_token * @property {User} user * @property {Object} guilds * @property {Number} guilds.count * @property {Map<String, Guild>} guilds.isMember * @property {Map<String, Guild>} guilds.notMember *//** * @typedef User * @property {String} id * @property {String} username * @property {String} discriminator * @property {String} avatar * @property {String} locale *//** * @typedef Guild * @property {String} id * @property {String} name * @property {String} acronym * @property {String} [icon] * @property {String} userPermissions * @property {Boolean} [patreon] * @property {String} [botPermissions] * @property {Channel[]} [channels] * @property {Role[]} [roles] *//** * @typedef Channel * @property {String} id * @property {String} name * @property {Boolean} isCategory * @property {Number} userPermissions * @property {Number} botPermissions *//** * @typedef Role * @property {String} id * @property {String} name * @property {Boolean} lower *//** * @type {Map<String, Settings>} */const settingsData = new Map();/** * @type {Map<Number, PromiseConstructor>} */const messages = new Map();var messageId = 1;process.on( 'message', message => {	if ( message.id ) {		if ( message.data.error ) messages.get(message.id).reject(message.data.error);		else messages.get(message.id).resolve(message.data.response);		return messages.delete(message.id);	}	console.log( '- [Dashboard]: Message received!', message );} );/** * Send messages to the manager. * @param {Object} [message] - The message. * @returns {Promise<Object>} */function sendMsg(message) {	var id = messageId++;	var promise = new Promise( (resolve, reject) => {		messages.set(id, {resolve, reject});		process.send( {id, data: message} );	} );	return promise;}/** * Create a red notice * @param {import('cheerio')} $ - The cheerio static * @param {String} notice - The notice to create * @param {import('./i18n.js')} dashboardLang - The user language * @param {String[]} [args] - The arguments for the notice * @returns {import('cheerio')} */function createNotice($, notice, dashboardLang, args = []) {	if ( !notice ) return;	var type = 'info';	var title = $('<b>');	var text = $('<div>');	var note;	switch (notice) {		case 'unauthorized':			type = 'info';			title.text(dashboardLang.get('notice.unauthorized.title'));			text.text(dashboardLang.get('notice.unauthorized.text'));			break;		case 'save':			type = 'success';			title.text(dashboardLang.get('notice.save.title'));			text.text(dashboardLang.get('notice.save.text'));			break;		case 'nosettings':			type = 'info';			title.text(dashboardLang.get('notice.nosettings.title'));			text.text(dashboardLang.get('notice.nosettings.text'));			note = $('<a>').text(dashboardLang.get('notice.nosettings.note')).attr('href', `/guild/${args[0]}/settings`);			break;		case 'logout':			type = 'success';			title.text(dashboardLang.get('notice.logout.title'));			text.text(dashboardLang.get('notice.logout.text'));			break;		case 'refresh':			type = 'success';			title.text(dashboardLang.get('notice.refresh.title'));			text.text(dashboardLang.get('notice.refresh.text'));			break;		case 'missingperm':			type = 'error';			title.text(dashboardLang.get('notice.missingperm.title'));			text.html(dashboardLang.get('notice.missingperm.text', true, $('<code>').text(args[0])));			break;		case 'loginfail':			type = 'error';			title.text(dashboardLang.get('notice.loginfail.title'));			text.text(dashboardLang.get('notice.loginfail.text'));			break;		case 'sysmessage':			type = 'info';			title.text(dashboardLang.get('notice.sysmessage.title'));			text.text(dashboardLang.get('notice.sysmessage.text', true, $('<a target="_blank">').append(				$('<code>').text('MediaWiki:Custom-RcGcDw')			).attr('href', args[1]), $('<code class="user-select">').text(args[0])));			note = $('<a target="_blank">').text(args[1]).attr('href', args[1]);			break;		case 'mwversion':			type = 'error';			title.text(dashboardLang.get('notice.mwversion.title'));			text.text(dashboardLang.get('notice.mwversion.text', false, args[0], args[1]));			note = $('<a target="_blank">').text('https://www.mediawiki.org/wiki/MediaWiki_1.30').attr('href', 'https://www.mediawiki.org/wiki/MediaWiki_1.30');			break;		case 'nochange':			type = 'info';			title.text(dashboardLang.get('notice.nochange.title'));			text.text(dashboardLang.get('notice.nochange.text'));			break;		case 'invalidusergroup':			type = 'error';			title.text(dashboardLang.get('notice.invalidusergroup.title'));			text.text(dashboardLang.get('notice.invalidusergroup.text'));			break;		case 'wikiblocked':			type = 'error';			title.text(dashboardLang.get('notice.wikiblocked.title'));			text.text(dashboardLang.get('notice.wikiblocked.text', false, args[0]));			if ( args[1] ) note = $('<div>').append(				dashboardLang.get('notice.wikiblocked.note', true) + ' ',				$('<code>').text(args[1])			);			break;		case 'savefail':			type = 'error';			title.text(dashboardLang.get('notice.savefail.title'));			text.text(dashboardLang.get('notice.savefail.text'));			break;		case 'movefail':			type = 'info';			title.text(dashboardLang.get('notice.movefail.title'));			text.text(dashboardLang.get('notice.movefail.text'));			note = $('<div>').text(dashboardLang.get('notice.movefail.note'));			break;		case 'refreshfail':			type = 'error';			title.text(dashboardLang.get('notice.refreshfail.title'));			text.text(dashboardLang.get('notice.refreshfail.text'));			break;		case 'error':			type = 'error';			title.text(dashboardLang.get('notice.error.title'));			text.text(dashboardLang.get('notice.error.text'));			break;		case 'readonly':			type = 'info';			title.text(dashboardLang.get('notice.readonly.title'));			text.text(dashboardLang.get('notice.readonly.text'));			break;		default:			return;	}	return $(`<div class="notice notice-${type}">`).append(		title,		text,		note	).appendTo('#text #notices');}/** * HTML escape text * @param {String} text - The text to escape * @returns {String} */function escapeText(text) {	return text.replace( /&/g, '&' ).replace( /</g, '<' ).replace( />/g, '>' );}const permissions = {	ADMINISTRATOR: 1 << 3,	MANAGE_CHANNELS: 1 << 4,	MANAGE_GUILD: 1 << 5,	ADD_REACTIONS: 1 << 6,	VIEW_CHANNEL: 1 << 10,	SEND_MESSAGES: 1 << 11,	MANAGE_MESSAGES: 1 << 13,	EMBED_LINKS: 1 << 14,	ATTACH_FILES: 1 << 15,	READ_MESSAGE_HISTORY: 1 << 16,	USE_EXTERNAL_EMOJIS: 1 << 18,	MANAGE_NICKNAMES: 1 << 27,	MANAGE_ROLES: 1 << 28,	MANAGE_WEBHOOKS: 1 << 29}/** * Check if a permission is included in the BitField * @param {String|Number} all - BitField of multiple permissions * @param {String[]} permission - Name of the permission to check for * @returns {Boolean} */function hasPerm(all = 0, ...permission) {	if ( (all & permissions.ADMINISTRATOR) === permissions.ADMINISTRATOR ) return true;	return permission.map( perm => {		let bit = permissions[perm];		return ( (all & bit) === bit );	} ).every( perm => perm );}module.exports = {got, db, settingsData, sendMsg, createNotice, escapeText, hasPerm};
 |