guilds.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. const cheerio = require('cheerio');
  2. const {defaultPermissions} = require('../util/default.json');
  3. const Lang = require('./i18n.js');
  4. const {settingsData, createNotice} = require('./util.js');
  5. const forms = {
  6. settings: require('./settings.js').get,
  7. verification: require('./verification.js').get,
  8. rcscript: require('./rcscript.js').get
  9. };
  10. const DiscordOauth2 = require('discord-oauth2');
  11. const oauth = new DiscordOauth2( {
  12. clientId: process.env.bot,
  13. clientSecret: process.env.secret,
  14. redirectUri: process.env.dashboard
  15. } );
  16. const file = require('fs').readFileSync('./dashboard/index.html');
  17. /**
  18. * Let a user view settings
  19. * @param {import('http').ServerResponse} res - The server response
  20. * @param {String} state - The user state
  21. * @param {URL} reqURL - The used url
  22. * @param {String} [action] - The action the user made
  23. * @param {String[]} [actionArgs] - The arguments for the action
  24. */
  25. function dashboard_guilds(res, state, reqURL, action, actionArgs) {
  26. reqURL.pathname = reqURL.pathname.replace( /^(\/(?:guild\/\d+(?:\/(?:settings|verification|rcscript)(?:\/(?:\d+|new))?)?)?)(?:\/.*)?$/, '$1' );
  27. var args = reqURL.pathname.split('/');
  28. args = reqURL.pathname.split('/');
  29. var settings = settingsData.get(state);
  30. if ( reqURL.searchParams.get('owner') && process.env.owner.split('|').includes(settings.user.id) ) {
  31. args[0] = 'owner';
  32. }
  33. var dashboardLang = new Lang(settings.user.locale);
  34. var $ = cheerio.load(file);
  35. $('head title').text(dashboardLang.get('general.title'));
  36. $('.channel#settings div').text(dashboardLang.get('general.settings'));
  37. $('.channel#verification div').text(dashboardLang.get('general.verification'));
  38. $('.channel#rcscript div').text(dashboardLang.get('general.rcscript'));
  39. $('#selector span').text(dashboardLang.get('general.selector'));
  40. $('#support span').text(dashboardLang.get('general.support'));
  41. $('#logout').attr('alt', dashboardLang.get('general.logout'));
  42. $('.guild#invite a').attr('alt', dashboardLang.get('general.invite'));
  43. $('.guild#refresh a').attr('alt', dashboardLang.get('general.refresh'));
  44. if ( process.env.READONLY ) createNotice($, 'readonly', dashboardLang);
  45. if ( action ) createNotice($, action, dashboardLang, actionArgs);
  46. $('head').append(
  47. $('<script>').text(`history.replaceState(null, null, '${reqURL.pathname}');`)
  48. );
  49. $('#logout img').attr('src', settings.user.avatar);
  50. $('#logout span').text(`${settings.user.username} #${settings.user.discriminator}`);
  51. $('.guild#invite a').attr('href', oauth.generateAuthUrl( {
  52. scope: ['identify', 'guilds', 'bot'],
  53. permissions: defaultPermissions, state
  54. } ));
  55. $('.guild#refresh a').attr('href', '/refresh?return=' + reqURL.pathname);
  56. if ( settings.guilds.isMember.size ) {
  57. $('<div class="guild">').append(
  58. $('<div class="separator">')
  59. ).insertBefore('.guild#last-separator');
  60. settings.guilds.isMember.forEach( guild => {
  61. $('<div class="guild">').attr('id', guild.id).append(
  62. $('<div class="bar">'),
  63. $('<a>').attr('href', `/guild/${guild.id}/settings`).attr('alt', guild.name).append(
  64. ( guild.icon ?
  65. $('<img class="avatar">').attr('src', `${guild.icon}?size=64`).attr('alt', guild.name)
  66. : $('<div class="avatar noicon">').text(guild.acronym) )
  67. )
  68. ).insertBefore('.guild#last-separator');
  69. } );
  70. }
  71. if ( settings.guilds.notMember.size ) {
  72. $('<div class="guild">').append(
  73. $('<div class="separator">')
  74. ).insertBefore('.guild#last-separator');
  75. settings.guilds.notMember.forEach( guild => {
  76. $('<div class="guild">').attr('id', guild.id).append(
  77. $('<div class="bar">'),
  78. $('<a>').attr('href', `/guild/${guild.id}`).attr('alt', guild.name).append(
  79. ( guild.icon ?
  80. $('<img class="avatar">').attr('src', `${guild.icon}?size=64`).attr('alt', guild.name)
  81. : $('<div class="avatar noicon">').text(guild.acronym) )
  82. )
  83. ).insertBefore('.guild#last-separator');
  84. } );
  85. }
  86. let id = args[2];
  87. $(`.guild#${id}`).addClass('selected');
  88. if ( settings.guilds.isMember.has(id) ) {
  89. let guild = settings.guilds.isMember.get(id);
  90. $('head title').text(`${guild.name} – ` + $('head title').text());
  91. $('<script>').text(`
  92. const isPatreon = ${guild.patreon};
  93. const i18n = ${JSON.stringify(dashboardLang.get('indexjs'))};
  94. `).insertBefore('script#indexjs');
  95. $('.channel#settings').attr('href', `/guild/${guild.id}/settings`);
  96. $('.channel#verification').attr('href', `/guild/${guild.id}/verification`);
  97. $('.channel#rcscript').attr('href', `/guild/${guild.id}/rcscript`);
  98. if ( args[3] === 'settings' ) return forms.settings(res, $, guild, args, dashboardLang);
  99. if ( args[3] === 'verification' ) return forms.verification(res, $, guild, args, dashboardLang);
  100. if ( args[3] === 'rcscript' ) return forms.rcscript(res, $, guild, args, dashboardLang);
  101. return forms.settings(res, $, guild, args, dashboardLang);
  102. }
  103. else if ( settings.guilds.notMember.has(id) ) {
  104. let guild = settings.guilds.notMember.get(id);
  105. $('head title').text(`${guild.name} – ` + $('head title').text());
  106. res.setHeader('Set-Cookie', [`guild="${guild.id}/settings"; HttpOnly; Path=/`]);
  107. let url = oauth.generateAuthUrl( {
  108. scope: ['identify', 'guilds', 'bot'],
  109. permissions: defaultPermissions,
  110. guildId: guild.id, state
  111. } );
  112. $('#channellist').empty();
  113. $('<a class="channel channel-header">').attr('href', url).append(
  114. $('<img>').attr('src', '/src/settings.svg'),
  115. $('<div>').text(dashboardLang.get('general.invite'))
  116. ).appendTo('#channellist');
  117. $('#text .description').append(
  118. $('<p>').html(dashboardLang.get('selector.invite', true, $('<code>').text(guild.name), $('<a>').attr('href', url))),
  119. $('<a id="login-button">').attr('href', url).text(dashboardLang.get('general.invite')).prepend(
  120. $('<img alt="Discord">').attr('src', 'https://discord.com/assets/f8389ca1a741a115313bede9ac02e2c0.svg')
  121. )
  122. );
  123. }
  124. else if ( args[0] === 'owner' ) {
  125. let guild = {
  126. id, name: 'OWNER ACCESS',
  127. acronym: '', userPermissions: 1 << 3,
  128. patreon: true, botPermissions: 1 << 3,
  129. channels: [], roles: []
  130. };
  131. $('head title').text(`${guild.name} – ` + $('head title').text());
  132. $('<script>').text(`
  133. const isPatreon = ${guild.patreon};
  134. const i18n = ${JSON.stringify(dashboardLang.get('indexjs'))};
  135. `).insertBefore('script#indexjs');
  136. $('.channel#settings').attr('href', `/guild/${guild.id}/settings?owner=true`);
  137. $('.channel#verification').attr('href', `/guild/${guild.id}/verification?owner=true`);
  138. $('.channel#rcscript').attr('href', `/guild/${guild.id}/rcscript?owner=true`);
  139. if ( args[3] === 'settings' ) return forms.settings(res, $, guild, args, dashboardLang);
  140. if ( args[3] === 'verification' ) return forms.verification(res, $, guild, args, dashboardLang);
  141. if ( args[3] === 'rcscript' ) return forms.rcscript(res, $, guild, args, dashboardLang);
  142. return forms.settings(res, $, guild, args, dashboardLang);
  143. }
  144. else {
  145. $('head title').text(dashboardLang.get('selector.title') + ' – ' + $('head title').text());
  146. $('#channellist').empty();
  147. $('<p>').html(dashboardLang.get('selector.desc', true, $('<code>'))).appendTo('#text .description');
  148. if ( settings.guilds.isMember.size ) {
  149. $('<h2 id="with-wikibot">').text(dashboardLang.get('selector.with')).appendTo('#text');
  150. $('<a class="channel">').attr('href', '#with-wikibot').append(
  151. $('<img>').attr('src', '/src/channel.svg'),
  152. $('<div>').text(dashboardLang.get('selector.with'))
  153. ).appendTo('#channellist');
  154. $('<div class="server-selector" id="isMember">').appendTo('#text');
  155. settings.guilds.isMember.forEach( guild => {
  156. $('<a class="server">').attr('href', `/guild/${guild.id}/settings`).append(
  157. ( guild.icon ?
  158. $('<img class="avatar">').attr('src', `${guild.icon}?size=256`).attr('alt', guild.name)
  159. : $('<div class="avatar noicon">').text(guild.acronym) ),
  160. $('<div class="server-name description">').text(guild.name)
  161. ).appendTo('.server-selector#isMember');
  162. } );
  163. }
  164. if ( settings.guilds.notMember.size ) {
  165. $('<h2 id="without-wikibot">').text(dashboardLang.get('selector.without')).appendTo('#text');
  166. $('<a class="channel">').attr('href', '#without-wikibot').append(
  167. $('<img>').attr('src', '/src/channel.svg'),
  168. $('<div>').text(dashboardLang.get('selector.without'))
  169. ).appendTo('#channellist');
  170. $('<div class="server-selector" id="notMember">').appendTo('#text');
  171. settings.guilds.notMember.forEach( guild => {
  172. $('<a class="server">').attr('href', `/guild/${guild.id}`).append(
  173. ( guild.icon ?
  174. $('<img class="avatar">').attr('src', `${guild.icon}?size=256`).attr('alt', guild.name)
  175. : $('<div class="avatar noicon">').text(guild.acronym) ),
  176. $('<div class="server-name description">').text(guild.name)
  177. ).appendTo('.server-selector#notMember');
  178. } );
  179. }
  180. if ( !settings.guilds.count ) {
  181. let url = oauth.generateAuthUrl( {
  182. scope: ['identify', 'guilds'],
  183. prompt: 'consent', state
  184. } );
  185. $('<a class="channel channel-header">').attr('href', url).append(
  186. $('<img>').attr('src', '/src/settings.svg'),
  187. $('<div>').text(dashboardLang.get('selector.switch'))
  188. ).appendTo('#channellist');
  189. $('#text .description').append(
  190. $('<p>').html(dashboardLang.get('selector.none', true, $('<code>'))),
  191. $('<a id="login-button">').attr('href', url).text(dashboardLang.get('selector.switch')).prepend(
  192. $('<img alt="Discord">').attr('src', 'https://discord.com/assets/f8389ca1a741a115313bede9ac02e2c0.svg')
  193. )
  194. );
  195. }
  196. }
  197. let body = $.html();
  198. res.writeHead(200, {'Content-Length': Buffer.byteLength(body)});
  199. res.write( body );
  200. return res.end();
  201. }
  202. module.exports = dashboard_guilds;