From 2afa151657062ce8df30c6ff64878d798189d8ec Mon Sep 17 00:00:00 2001 From: ame Date: Mon, 22 Apr 2024 23:46:32 -0500 Subject: long time no commit --- commands/mod/add.js | 54 ++++++++ commands/mod/confirm.js | 70 ++++++++-- commands/mod/defaults/add.js.json | 2 + commands/mod/whois.js | 4 + commands/util/say.js | 82 ++++++++++- commands/util/status.js | 2 +- commands/util/ticket-create.js | 4 +- events/defaults/member-add.js.json | 1 + events/defaults/member-update.js.json | 1 + events/defaults/ready.js.json | 6 +- events/interaction.js | 1 + events/member-add.js | 26 ++++ events/member-update.js | 69 ++++++++++ html/settings.html | 251 ++++++++++++++++++++++++++++++++++ i.js | 1 + src/settings.js | 3 + src/util.js | 6 +- src/webui.js | 79 +++++++++-- 18 files changed, 625 insertions(+), 37 deletions(-) create mode 100644 commands/mod/add.js create mode 100644 commands/mod/defaults/add.js.json create mode 100644 events/defaults/member-add.js.json create mode 100644 events/defaults/member-update.js.json create mode 100644 events/member-add.js create mode 100644 events/member-update.js create mode 100644 i.js diff --git a/commands/mod/add.js b/commands/mod/add.js new file mode 100644 index 0000000..b9ac0ab --- /dev/null +++ b/commands/mod/add.js @@ -0,0 +1,54 @@ +const fs = require('fs') +const path = require("path"); +let config_loc = __filename+".json" +const { PermissionsBitField } = require('discord.js'); +let config = JSON.parse(fs.readFileSync(config_loc)) +const { EmbedBuilder, ActionRowBuilder,ButtonBuilder,ButtonStyle } = require("discord.js"); +const settings = require("../../src/settings") + +module.exports = { + name : "add", + command: ["add"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + + }, + s_options:[{type:"sub",name:"button",options:[ + {type:"string",name:"message",desc:"message id to edit",required:true,autocomplete:false}, + {type:"string",name:"label",desc:"text on the button",required:true,autocomplete:false}, + {type:"string",name:"custom-id",desc:"custom id to do custom things",required:true,autocomplete:false}, + {type:"string",name:"style",desc:"button type",required:true,autocomplete:["Primary","Secondary","Success","Danger","Link"]} + ]}], + async s_main (client,Discord,interaction){ + let action = interaction.options.getSubcommand() + if(action == "button"){ + this.exec_button(client, interaction) + //await interaction.reply({ content:'sent', ephemeral: true }) + //interaction.deleteReply() + } + + + }, + + async exec_button(client,interaction){ + interaction.channel.messages.fetch(interaction.options.getString("message")) + .then(msg => { + if(msg.author.id != "762561860150362142") + return interaction.reply({ content:'message must be owned by me', ephemeral: true }) + const button = new ButtonBuilder() + .setCustomId(interaction.options.getString("custom-id")) + .setLabel(interaction.options.getString("label")) + .setStyle(ButtonStyle[interaction.options.getString("style")]) + + const row = new ActionRowBuilder() + .addComponents(button); + + msg.edit({components:[row]}) + interaction.reply({ content:'success', ephemeral: true }) + }) .catch(e => { + interaction.reply({ content:'unable to add anything, are you in the same channel?', ephemeral: true }) + }) + }, +} \ No newline at end of file diff --git a/commands/mod/confirm.js b/commands/mod/confirm.js index a0e6714..cbf3846 100644 --- a/commands/mod/confirm.js +++ b/commands/mod/confirm.js @@ -18,21 +18,37 @@ module.exports = { s_options:[ {type:"user",name:"user",desc:"message to be sent",required:true,autocomplete:false}, {type:"string",name:"ban-reason",desc:"ban reason to be sent to the user",required:true,autocomplete:false}, - {type:"string",name:"details",desc:"staff note (mod side only)",required:false,autocomplete:false}, + {type:"string",name:"staff-note",desc:"viewable only to staff",required:false,autocomplete:false}, {type:"boolean",name:"send-appeal",desc:"whether to send your user id for appealing (default : false)", required:false,autocomplete:false}, {type:"boolean",name:"open-thread",desc:"open a thread for discussion (default : false)", required:false,autocomplete:false}, + //{type:"boolean",name:"delete-messages",desc:"delete recent messages from user (default : true)", required:false,autocomplete:false}, ], - s_main(client,Discord,interaction){ + async s_main(client,Discord,interaction){ + + await interaction.guild.members.fetch() + await interaction.guild.channels.fetch() + + + /* + interaction.channel.messages.fetch({limit:100}).then(m => { + m.forEach(message => console.log(message.id)) + })*/ + + this.exec(client, { message : interaction, user : interaction.guild.members.cache.get(interaction.options.getUser("user").id), reason : interaction.options.getString("ban-reason"), - details : interaction.options.getString("details"), + details : interaction.options.getString("staff-note"), appeal : interaction.options.getBoolean("send-appeal"), thread : interaction.options.getBoolean("open-thread"), + //del_messages : interaction.options.getBoolean("delete-messages") ?? true, }) }, async exec(client,param){ + if(!param.user){ + return param.message.reply({content:"user not found",ephemeral: true }) + } let embed = new EmbedBuilder() .setTitle("Waiting for Confirmation") .setThumbnail(param.user.displayAvatarURL()) @@ -50,11 +66,22 @@ module.exports = { .setCustomId('confirm') .setLabel('Confirm') .setStyle(ButtonStyle.Primary) + + const cancel_button = new ButtonBuilder() + .setCustomId('cancel') + .setLabel('Cancel') + .setStyle(ButtonStyle.Danger) + const row = new ActionRowBuilder() - .addComponents(confirm_button); + .addComponents(confirm_button, cancel_button); let confirms = [param.message.author.id] - let mess = await param.message.reply({embeds:[embed],components:[row]}) + //await param.message.deferReply(); + //param.message.deferUpdate() + let mess = await param.message.deferReply({ fetchReply: true }) + param.message.editReply({embeds:[embed],components:[row]}) + //await param.message.editReply({embeds:[embed],components:[row]}) + //if(mess.partial) mess = mess.fetch() if(param.thread){ let th = await client.channels.cache.get(param.message.channelId).threads.create({ @@ -66,9 +93,11 @@ module.exports = { } async function rec_read(){ - const collectorFilter = i => i.user.id != param.message.author.id && !confirms.includes(i.user.id); + const collectorFilter = i => true;//i.user.id != param.message.author.id && !confirms.includes(i.user.id); try { const confirmation = await mess.awaitMessageComponent({ filter: collectorFilter, time: 60000000 }); + //confirmation.deferReply(); + confirmation.deferUpdate() if(confirmation.customId == "confirm"){ confirms.push(confirmation.author.id) let comb_mod = "" @@ -76,10 +105,10 @@ module.exports = { comb_mod += "<@" + mod + ">" if(mod != confirms[confirms.length-1]) comb_mod += "," } - embed.setFooter({text:confirms.length - 1 + "/2 confirmations"}) + embed.setFooter({text:confirms.length - 1 + "/1 confirmations"}) embed.data.fields[0].value = comb_mod - if(confirms.length >= 3){ + if(confirms.length >= 2){ let ban_embed = new EmbedBuilder() .setTitle("Banned from Supernoobs") .setFooter({text:"You have been banned from this server. Maybe in another life, we could have been friends. But not in this one. 💔"}) @@ -88,21 +117,36 @@ module.exports = { if(param.appeal) ban_embed.addFields({name : "Appeal id", value : "" + param.message.author.id}) let user = await param.message.client.users.cache.get(param.user.id); let could_send = true + let could_ban = true + let could_del = true + embed.setTitle("Ban Confirmed, Awaiting User Cleanup"); + mess.edit({embeds:[embed],components:[]}) try { await user.send({embeds:[ban_embed]}) } catch (e) { + console.log(e) could_send = false; } - await param.user.ban(); - + try{ + user = param.message.guild.members.cache.get(user.id) + await user.ban({deleteMessageSeconds: 60 * 60 * 24 * 7, reason: param.reason}) + } catch (e) { + console.log(e) + could_ban = false; + } - embed.setTitle("Ban Confirmed" + (!could_send?" | Unable to Message":"")); + embed.setTitle("Ban Confirmed" + (!could_send?" | Unable to Message":"") + (!could_ban?" | Unable to Ban":"") + (!could_del?" | Unable to Delete Msgs":"")); mess.edit({embeds:[embed],components:[]}) } else { mess.edit({embeds:[embed]}) rec_read() - confirmation.deferUpdate() + //confirmation.deferUpdate() } + } else if(confirmation.customId == "cancel") { + embed.setFooter({text:"canceled"}) + embed.setTitle("Ban Request Rejected") + embed.addFields({name:"Removed By Staff:",value:"<@!"+param.message.author.id+">", inline : true}) + mess.edit({embeds:[embed],components:[]}) } } catch (e) { console.log(e) @@ -110,4 +154,4 @@ module.exports = { } await rec_read(); } -}; \ No newline at end of file +}; diff --git a/commands/mod/defaults/add.js.json b/commands/mod/defaults/add.js.json new file mode 100644 index 0000000..e11116a --- /dev/null +++ b/commands/mod/defaults/add.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Add an element to sns-chan's message","restrict":[],"restricted":[], +"usage":"{command}"} \ No newline at end of file diff --git a/commands/mod/whois.js b/commands/mod/whois.js index 6ffd8e6..48f3fdf 100644 --- a/commands/mod/whois.js +++ b/commands/mod/whois.js @@ -62,7 +62,11 @@ module.exports = { this.p_role(client,Discord,interaction,role) if(user!=null){ await interaction.guild.members.fetch() + let _user = user user = interaction.guild.members.cache.get(user.id) + if(!user){ + return interaction.reply({content:"<@"+_user.id+"> not found (have they left?)",ephemeral: true}) + } this.p_user(client,Discord,interaction,user) } }, diff --git a/commands/util/say.js b/commands/util/say.js index 17af382..1966512 100644 --- a/commands/util/say.js +++ b/commands/util/say.js @@ -3,6 +3,27 @@ const path = require("path"); let config_loc = __filename+".json" const { PermissionsBitField } = require('discord.js'); let config = JSON.parse(fs.readFileSync(config_loc)) +const { EmbedBuilder, ActionRowBuilder,ButtonBuilder,ButtonStyle } = require("discord.js"); +const settings = require("../../src/settings") + +/*let presets = { + "ticket-create": function(client, info){ + let embed = new EmbedBuilder() + .setColor(settings.defaultColor) + .setTitle("create a ticket") + .setDescription("test") + + const create = new ButtonBuilder() + .setCustomId('new-private-thread') + .setLabel('Create Ticket') + .setStyle(ButtonStyle.Primary) + + const row = new ActionRowBuilder() + .addComponents(create); + + info.id.send({embeds:[embed],components:[row]}) + } +}*/ module.exports = { name : "say", command: ["say"], @@ -21,16 +42,63 @@ module.exports = { } this.exec(client,{id:id,echo:echo}) }, - s_options:[{type:"string",name:"echo",desc:"message to be said",required:true,autocomplete:false}, - {type:"channel",name:"channel",desc:"channel to be sent to",required:false,autocomplete:false}], + s_options:[{type:"sub",name:"text",options:[{type:"string",name:"echo",desc:"message to be said",required:true,autocomplete:false}, + {type:"channel",name:"channel",desc:"channel to be sent to",required:false,autocomplete:false}]}, + //{type:"sub",name:"preset",options:[{type:"string",name:"pre",desc:"preset message",required:true,autocomplete:Object.keys(presets)}]}, + {type:"sub", name:"embed",options:[ + {type:"string",name:"hex-color",desc:"hex color on left side of embed",required:false,autocomplete:false}, + {type:"string",name:"title",desc:"embed title",required:false,autocomplete:false}, + {type:"string",name:"url",desc:"embed url",required:false,autocomplete:false}, + {type:"string",name:"description",desc:"embed body",required:false,autocomplete:false}, + {type:"string",name:"thumbnail",desc:"embed thumbnail",required:false,autocomplete:false}, + {type:"string",name:"image",desc:"embed image",required:false,autocomplete:false}, + {type:"string",name:"footer",desc:"footer text",required:false,autocomplete:false}, + ]}], async s_main (client,Discord,interaction){ - this.exec(client, - {echo:interaction.options.getString("echo"), - id:interaction.options.getChannel("channel") ?? interaction.channel}) - await interaction.reply({ content:'sent', ephemeral: true }) - interaction.deleteReply() + let action = interaction.options.getSubcommand() + if(action == "text"){ + this.exec(client, + {echo:interaction.options.getString("echo"), + id:interaction.options.getChannel("channel") ?? interaction.channel}) + await interaction.reply({ content:'sent', ephemeral: true }) + interaction.deleteReply() + } else if(action == "embed"){ + this.embed_exec(client, {msg:interaction,id:interaction.channel}) + } + + }, + async exec(client,info){ return info.id.send(info.echo) + }, + + async embed_exec(client, info){ + let interaction = info.msg + let opt; + try{ + let embed = new EmbedBuilder() + .setColor(interaction.options.getString("hex-color") ?? settings.defaultColor) + if((opt = interaction.options.getString("title")) != null) + embed.setTitle(opt) + if((opt = interaction.options.getString("url")) != null) + embed.setURL(opt) + if((opt = interaction.options.getString("description")) != null) + embed.setDescription(opt) + if((opt = interaction.options.getString("thumbnail")) != null) + embed.setThumbnail(opt) + if((opt = interaction.options.getString("image")) != null) + embed.setImage(opt) + if((opt = interaction.options.getString("image")) != null) + embed.setImage(opt) + if((opt = interaction.options.getString("footer"))) + embed.setFooter({text:opt}) + info.id.send({embeds:[embed]}) + await interaction.reply({ content:'sent', ephemeral: true }) + interaction.deleteReply() + } catch(e){ + await interaction.reply({ content:'invalid configuration', ephemeral: true }) + } + } } \ No newline at end of file diff --git a/commands/util/status.js b/commands/util/status.js index db78408..b64a81b 100644 --- a/commands/util/status.js +++ b/commands/util/status.js @@ -38,7 +38,7 @@ module.exports = { const vote = new ButtonBuilder() .setLabel('Vote') .setStyle(ButtonStyle.Link) - .setURL('https://top.gg/servers/486957006628847626/vote') + .setURL('https://discords.com/servers/486957006628847626/upvote') // /*const twitter = new ButtonBuilder() //0% chance i will call this 𝕏 .setLabel('Twitter') diff --git a/commands/util/ticket-create.js b/commands/util/ticket-create.js index 3264568..614af71 100644 --- a/commands/util/ticket-create.js +++ b/commands/util/ticket-create.js @@ -4,8 +4,8 @@ let config_loc = __filename+".json" const { PermissionsBitField, ChannelType } = require('discord.js'); let config = JSON.parse(fs.readFileSync(config_loc)) module.exports = { - name : "ticket-create", - command: ["ticket-create"], + name : "thread-create", + command: ["thread-create"], mod_only: false, config:config, config_loc:config_loc, diff --git a/events/defaults/member-add.js.json b/events/defaults/member-add.js.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/events/defaults/member-add.js.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/events/defaults/member-update.js.json b/events/defaults/member-update.js.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/events/defaults/member-update.js.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/events/defaults/ready.js.json b/events/defaults/ready.js.json index 4ee756c..fc6ae30 100644 --- a/events/defaults/ready.js.json +++ b/events/defaults/ready.js.json @@ -1,5 +1,5 @@ { - "status":{"value":"dm to report an issue"}, - "type":{"value":"Playing","options":["Listening","Playing","Streaming","Watching"]}, + "status":{"value":"discord.gg/supernoobs"}, + "type":{"value":"Custom","options":["Listening","Playing","Streaming","Watching", "Custom"]}, "timed_interval":{"value":5000} -} \ No newline at end of file +} diff --git a/events/interaction.js b/events/interaction.js index a9a174f..e384dcc 100644 --- a/events/interaction.js +++ b/events/interaction.js @@ -13,6 +13,7 @@ module.exports = { await db._raw.sync() let config = JSON.parse(fs.readFileSync(config_loc)) client.on("interactionCreate", async(interaction) => { + if(interaction.guild==null)return if(!settings["allowed-servers"].includes(interaction.guild.id)) return console.log("denied interaction from (guild)"+interaction.guild.id) diff --git a/events/member-add.js b/events/member-add.js new file mode 100644 index 0000000..6392c4c --- /dev/null +++ b/events/member-add.js @@ -0,0 +1,26 @@ +const { ActivityType , PermissionsBitField} = require("discord.js"); +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder } = require("discord.js"); +let db = require("../src/db") +let settings = require("../src/settings") +let message_update = require("./member-update") +let config_loc = __filename+".json" +module.exports = { + name : "guildMemberAdd", + config_loc : config_loc, + async main (client,Discord){ + client.on("guildMemberAdd",(m)=>{ + //global.channels.general.send("Welcome to the server <@"+m.id+">!") + if(global.notif == null) + global.notif = {} + if(global.notif.voted == null) + global.notif.joined = global.notif.voted = [] + + global.notif.joined.push(m.id) + + message_update.build_message(m.id, "joined") + }) + + }, +} \ No newline at end of file diff --git a/events/member-update.js b/events/member-update.js new file mode 100644 index 0000000..bbdc889 --- /dev/null +++ b/events/member-update.js @@ -0,0 +1,69 @@ +const { ActivityType , PermissionsBitField, ActionRowBuilder,ButtonBuilder,ButtonStyle } = require("discord.js"); +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder } = require("discord.js"); +let db = require("../src/db") +let settings = require("../src/settings") +let config_loc = __filename+".json" +module.exports = { + name : "guildMemberUpdate", + config_loc : config_loc, + build_message(p, t){ + global.channels["general"].messages.fetch({limit : 1}).then(async messages => { + let message = messages.first(); + if(message.id == global.notif.id){ + //edit + let mess = ""; + //TODO: this can be a single loop + if(global.notif.voted.length != 0){ + for(let i = 0; i != global.notif.voted.length - 1; i++){ + mess += "<@"+global.notif.voted[i]+">, "; + } + if(global.notif.voted.length > 1) mess += " and" + mess += " <@"+global.notif.voted[global.notif.voted.length - 1]+"> just voted! You can too by clicking [here](https://discords.com/servers/486957006628847626/upvote)" + } + + if(global.notif.joined.length != 0){ + if(global.notif.voted.length != 0) mess += " and\n" + mess += "Welcome to the server " + for(let i = 0; i != global.notif.joined.length - 1; i++){ + mess += "<@"+global.notif.joined[i]+">, "; + } + if(global.notif.joined.length > 1) mess += " and" + mess += " <@"+global.notif.joined[global.notif.joined.length - 1]+">!" + } + message.edit({content: mess, flags:[4096]}) + } else { + global.notif.voted = [] + global.notif.joined = [] + global.notif[t] = [p] + + if(t == "voted"){ + global.notif.id = await global.channels["general"].send({content:`<@${p}> just voted! You can too by clicking [here](https://discords.com/servers/486957006628847626/upvote).`, + flags: [ 4096 ]}) + } else if(t == "joined"){ + global.notif.id = await global.channels["general"].send({content:`Welcome to the server <@${p}>!`, + flags: [ 4096 ]}) + } + } + }) + }, + async main (client,Discord){ + client.on("guildMemberUpdate",(oldMember, newMember)=>{ + if(!oldMember.roles.cache.has("761225110060662854") && + newMember.roles.cache.has("761225110060662854")){ + + if(global.notif == null) + global.notif = {} + if(global.notif.voted == null) + global.notif.joined = global.notif.voted = [] + + global.notif.voted.push(newMember.id) + + this.build_message(newMember.id, "voted") + + + } + }) + }, +} \ No newline at end of file diff --git a/html/settings.html b/html/settings.html index e69de29..787fd17 100644 --- a/html/settings.html +++ b/html/settings.html @@ -0,0 +1,251 @@ + + + + + + + + + + + + sns-chan + + + + + + + + + + + + + + diff --git a/i.js b/i.js new file mode 100644 index 0000000..4acb17f --- /dev/null +++ b/i.js @@ -0,0 +1 @@ +require("./src/webui") \ No newline at end of file diff --git a/src/settings.js b/src/settings.js index 87ba87b..6baea47 100644 --- a/src/settings.js +++ b/src/settings.js @@ -11,6 +11,9 @@ module.exports = { }, "748790869938929737":{ name: "logging", + }, + "825023574221783102":{ + name: "general" } } } diff --git a/src/util.js b/src/util.js index 48cfa55..68f2c56 100644 --- a/src/util.js +++ b/src/util.js @@ -1,9 +1,9 @@ const rem_emp = function (e) {return e !== "";} - +const { ActivityType , PermissionsBitField} = require("discord.js"); module.exports = { is_mod(member){ return member.permissions!=null&& - (member.roles.cache.has("586781513471885323")||user.permissions?.has(PermissionsBitField.Flags.KickMembers)) + (member.roles.cache.has("814558111234654258")||member.roles.cache.has("586781513471885323")||member.permissions?.has(PermissionsBitField.Flags.KickMembers)) }, generate_id(){ let config = JSON.parse(fs.readFileSync(config_loc)) @@ -118,4 +118,4 @@ module.exports = { return target; } -} \ No newline at end of file +} diff --git a/src/webui.js b/src/webui.js index 8a9fa56..999de2f 100644 --- a/src/webui.js +++ b/src/webui.js @@ -1,7 +1,8 @@ -const key = process.env.WEBUI_KEY +const key = "0d68ac83-4214-4eb3-8b3e-fe4463f43d9d" const bodyParser = require("body-parser"); const express = require('express'); +const fs = require('fs'); let db = require("../src/db"); const path = require("path") const Tickets = db.Tickets @@ -9,7 +10,8 @@ const Tickets = db.Tickets const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); -const port = 7001; +const port = 7003; + app.get('/tickets', async (req, res) => { res.sendFile(path.join(__dirname+'/../html/tickets.html')) }) @@ -28,13 +30,74 @@ app.post('/tickets/edit', async (req, res) => { res.send('failed') }) -app.get('/settings', async (req, res) => { + + + +let root_path = path.join(__dirname+"/../") +let settings_dirs = [ + path.join(__dirname+"/../events"), +] + +fs.readdirSync(path.join(__dirname+"/../commands/")).forEach(async file => { + let full_path = path.join(__dirname+"/../commands/"+file) + let stat = fs.statSync(full_path); + if(stat.isDirectory()){ + settings_dirs.push(full_path) + } +}) + +let clean_settings_dirs = []; +for(let i = 0; i != settings_dirs.length; i++){ + clean_settings_dirs[i] = settings_dirs[i].slice(root_path.length) +} + +//console.log(settings_dirs) +let settings_full = {}; + +for(let dir of settings_dirs){ + let fdir = dir.slice(root_path.length); + + fs.readdirSync(dir).forEach(async file => { + let full_path = path.join(dir+"/"+file) + let stat = fs.statSync(full_path); + if(!stat.isDirectory() && file.endsWith(".js.json")){ + if(settings_full[fdir] == null){ + settings_full[fdir] = [] + } + + settings_full[fdir].push(file.slice(0,-8)) + } + + }) +} + +console.log(settings_full) +app.get('/settings/', async (req, res) => { res.sendFile(path.join(__dirname+'/../html/settings.html')) }) -app.post('/settings/data', async (req, res) => { - if(req.body.key == key) - res.send('todo:P') - else - res.send('failed') + +app.post('/settings/data/', async (req, res) => { + if(req.body.key != key) + return res.send('failed') + let data = {data:settings_full,sel:"null"} + res.send(JSON.stringify(data)) }) + + +for(let ddir in settings_full){ + for(let dir of settings_full[ddir]){ + let at = ddir + "/" + dir + app.post('/settings/'+at+'/data', async (req, res) => { + if(req.body.key != key) + return res.send('failed') + let c = fs.readFileSync(path.join(__dirname+"/../"+at+".js.json")) + let data = {data:settings_full,sel:c.toString()} + res.send(JSON.stringify(data)) + }) + console.log('/settings/'+at) + app.get('/settings/'+at, async (req, res) => { + res.sendFile(path.join(__dirname+'/../html/settings.html')) + }) + } +} app.listen(port, () => console.log(`listening at http://localhost:${port}`)); -- cgit v1.2.3