dashboard-core/Routes/dashboard.js

889 lines
39 KiB
JavaScript
Raw Normal View History

2023-06-19 12:35:11 +05:00
const { PermissionFlagsBits } = require("discord.js")
const Discord = require("discord.js")
const router = require("express").Router()
module.exports = (app, config, themeConfig) => {
const RL = require("express-rate-limit")
const RateLimits = config.rateLimits || {}
let RateFunctions = {}
const NoRL = (req, res, next) => next()
if (RateLimits.manage) {
RateFunctions.manage = RL.rateLimit({
windowMs: RateLimits.manage.windowMs,
max: RateLimits.manage.max,
message: RateLimits.manage.message,
store: RateLimits.manage.store || new RL.MemoryStore(),
})
}
if (RateLimits.guildPage) {
RateFunctions.guildPage = RL.rateLimit({
windowMs: RateLimits.guildPage.windowMs,
max: RateLimits.guildPage.max,
message: RateLimits.guildPage.message,
store: RateLimits.guildPage.store || new RL.MemoryStore(),
})
}
if (RateLimits.settingsUpdatePostAPI) {
RateFunctions.settingsUpdatePostAPI = RL.rateLimit({
windowMs: RateLimits.settingsUpdatePostAPI.windowMs,
max: RateLimits.settingsUpdatePostAPI.max,
message: RateLimits.settingsUpdatePostAPI.message,
store:
RateLimits.settingsUpdatePostAPI.store || new RL.MemoryStore(),
})
}
router.get(
"/manage",
RateFunctions.manage ? RateFunctions.manage : NoRL,
async (req, res) => {
if (!req.session.user) return res.redirect("/discord?r=/manage")
let customThemeOptions
if (themeConfig?.customThemeOptions?.manage) {
customThemeOptions =
await themeConfig.customThemeOptions.manage({
req: req,
res: res,
config: config,
})
}
res.render("guilds", {
req: req,
bot: config.bot,
themeConfig: req.themeConfig,
customThemeOptions: customThemeOptions || {},
config,
})
}
)
router.get(
"/guild/:id",
RateFunctions.guildPage ? RateFunctions.guildPage : NoRL,
async (req, res) => {
res.redirect("/settings/" + req.params.id)
if (!req.session.user)
return res.redirect("/discord?r=/guild/" + req.params.id)
let customThemeOptions
if (themeConfig?.customThemeOptions?.getGuild) {
customThemeOptions =
await themeConfig.customThemeOptions.getGuild({
req: req,
res: res,
config: config,
guildId: req.params.id,
})
}
let bot = config.bot
if (!bot.guilds.cache.get(req.params.id)) {
try {
await bot.guilds.fetch(req.params.id)
} catch (err) { }
}
if (!bot.guilds.cache.get(req.params.id))
return res.redirect("/manage?error=noPermsToManageGuild")
if (
!bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
) {
try {
await bot.guilds.cache
.get(req.params.id)
.members.fetch(req.session.user.id)
} catch (err) { }
}
for (let PermissionRequired of req.requiredPermissions) {
let converted = PermissionRequired[0]
const DiscordJsVersion = Discord.version.split(".")[0]
if (DiscordJsVersion === "14")
converted = convert14(PermissionRequired[0])
if (
!bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
.permissions.has(converted)
)
return res.redirect("/manage?error=noPermsToManageGuild")
}
if (bot.guilds.cache.get(req.params.id).channels.cache.size < 1) {
try {
await bot.guilds.cache.get(req.params.id).channels.fetch()
} catch (err) { }
}
if (bot.guilds.cache.get(req.params.id).roles.cache.size < 2) {
try {
await bot.guilds.cache.get(req.params.id).roles.fetch()
} catch (err) { }
}
let actual = {}
let canUseList = {}
if (!config.useCategorySet)
for (const s of config.settings) {
if (!canUseList[s.categoryId]) canUseList[s.categoryId] = {}
for (const c of s.categoryOptionsList) {
if (c.allowedCheck) {
const canUse = await c.allowedCheck({
guild: { id: req.params.id },
user: { id: req.session.user.id },
})
if (typeof canUse != "object")
throw new TypeError(
`${s.categoryId} category option with id ${c.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`
)
canUseList[s.categoryId][c.optionId] = canUse
} else {
canUseList[s.categoryId][c.optionId] = {
allowed: true,
errorMessage: null,
}
}
if (c.optionType == "spacer") {
} else {
if (!actual[s.categoryId]) {
actual[s.categoryId] = {}
}
if (!actual[s.categoryId][c.optionId]) {
actual[s.categoryId][c.optionId] =
await c.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(
req.params.id
),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(
req.session.user.id
),
},
})
}
}
}
}
else
for (const category of config.settings) {
if (!canUseList[category.categoryId])
canUseList[category.categoryId] = {}
const catGAS = await category.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id),
},
})
for (const o of catGAS) {
if (!o || !o?.optionId)
console.log(
"WARNING: You haven't set the optionId for a category option in your config. This is required for the category option to work."
)
else {
const option = category.categoryOptionsList.find(
(c) => c.optionId == o.optionId
)
if (option) {
if (option.allowedCheck) {
const canUse = await option.allowedCheck({
guild: {
id: req.params.id,
},
user: {
id: req.session.user.id,
},
})
if (typeof canUse != "object")
throw new TypeError(
`${category.categoryId} category option with id ${option.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`
)
canUseList[category.categoryId][
option.optionId
] = canUse
} else {
canUseList[category.categoryId][
option.optionId
] = {
allowed: true,
errorMessage: null,
}
}
if (option.optionType !== "spacer") {
if (!actual[category.categoryId]) {
actual[category.categoryId] = {}
}
if (
!actual[category.categoryId][
option.optionId
]
) {
actual[category.categoryId][
option.optionId
] = o.data
}
}
} else
console.log(
`WARNING: Option ${o.optionId} in category ${category.categoryId} doesn't exist in your config.`
)
}
}
}
let errors
let success
if (req.session.errors) {
if (String(req.session.errors).includes("%is%")) {
errors = req.session.errors.split("%and%")
}
}
if (req.session.success) {
if (typeof req.session.success == "boolean") {
success = true
} else {
if (String(req.session.success).includes("%is%")) {
success = req.session.success.split("%and%")
}
}
}
req.session.errors = null
req.session.success = null
res.render("guild", {
successes: success,
errors: errors,
settings: config.settings,
actual: actual,
canUseList,
bot: config.bot,
req: req,
guildid: req.params.id,
themeConfig: req.themeConfig,
customThemeOptions: customThemeOptions || {},
config,
})
}
)
router.post(
"/settings/update/:guildId/:categoryId",
RateFunctions.settingsUpdatePostAPI
? RateFunctions.settingsUpdatePostAPI
: NoRL,
async (req, res) => {
if (!req.session.user)
return res.redirect("/discord?r=/guild/" + req.params.guildId)
let customThemeOptions
if (themeConfig?.customThemeOptions?.settingsUpdate) {
customThemeOptions =
await themeConfig.customThemeOptions.settingsUpdate({
req: req,
config: config,
guildId: req.params.id,
categoryId: req.params.categoryId,
})
}
let bot = config.bot
if (!bot.guilds.cache.get(req.params.guildId))
return res.redirect("/manage?error=noPermsToManageGuild")
await bot.guilds.cache
.get(req.params.guildId)
.members.fetch(req.session.user.id)
for (let PermissionRequired of req.requiredPermissions) {
let converted2 = PermissionRequired[0]
const DiscordJsVersion2 = Discord.version.split(".")[0]
if (DiscordJsVersion2 === "14")
converted2 = await convert14(PermissionRequired[0])
if (
!bot.guilds.cache
.get(req.params.guildId)
.members.cache.get(req.session.user.id)
.permissions.has(converted2)
)
return res.redirect("/manage?error=noPermsToManageGuild")
}
let cid = req.params.categoryId
let settings = config.settings
let category = settings.find((c) => c.categoryId == cid)
if (!category)
return res.send({
error: true,
message: "No category found",
})
let setNewRes
let errors = []
let successes = []
let catO = []
const userGuildMemberObject = bot.guilds.cache
.get(req.params.guildId)
.members.cache.get(req.session.user.id)
const guildObject = bot.guilds.cache.get(req.params.guildId)
for (let option of category.categoryOptionsList) {
let canUse = {}
if (option.allowedCheck) {
canUse = await option.allowedCheck({
guild: { id: req.params.guildId },
user: { id: req.session.user.id },
})
} else {
canUse = { allowed: true, errorMessage: null }
}
if (canUse.allowed == false) {
setNewRes = { error: canUse.errorMessage }
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else if (option.optionType != "spacer") {
if (config.useCategorySet) {
if (
option.optionType.type == "rolesMultiSelect" ||
option.optionType.type == "channelsMultiSelect" ||
option.optionType.type == "multiSelect"
) {
if (
!req.body[option.optionId] ||
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
)
catO.push({
optionId: option.optionId,
data: [],
})
else if (
typeof req.body[option.optionId] != "object"
)
catO.push({
optionId: option.optionId,
data: [req.body[option.optionId]],
})
else
catO.push({
optionId: option.optionId,
data: req.body[option.optionId],
})
} else if (option.optionType.type == "switch") {
if (
req.body[option.optionId] ||
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
) {
if (
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
)
catO.push({
optionId: option.optionId,
data: false,
})
else
catO.push({
optionId: option.optionId,
data: true,
})
}
} else if (option.optionType.type == "embedBuilder") {
if (
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
)
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
else {
try {
const parsedResponse = JSON.parse(
req.body[option.optionId]
)
catO.push({
optionId: option.optionId,
data: parsedResponse,
})
} catch (err) {
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
}
}
} else {
if (
req.body[option.optionId] == undefined ||
req.body[option.optionId] == null
)
catO.push({
optionId: option.optionId,
data: null,
})
else
catO.push({
optionId: option.optionId,
data: req.body[option.optionId],
})
}
} else {
if (
option.optionType.type == "rolesMultiSelect" ||
option.optionType.type == "channelsMultiSelect" ||
option.optionType.type == "multiSelect"
) {
if (
!req.body[option.optionId] ||
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: [],
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else if (
typeof req.body[option.optionId] != "object"
) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: [req.body[option.optionId]],
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: req.body[option.optionId],
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
} else if (option.optionType.type == "switch") {
if (
req.body[option.optionId] ||
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
) {
if (
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: false,
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: true,
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
}
} else if (option.optionType.type == "embedBuilder") {
if (
req.body[option.optionId] == null ||
req.body[option.optionId] == undefined
) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: option.optionType.data,
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
try {
const parsedResponse = JSON.parse(
req.body[option.optionId]
)
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: parsedResponse,
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} catch (err) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: option.optionType.data,
})) || {}
setNewRes = {
error: "JSON parse for embed builder went wrong, your settings have been reset.",
}
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
}
} else {
if (
req.body[option.optionId] == undefined ||
req.body[option.optionId] == null
) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: null,
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: req.body[option.optionId],
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
}
}
}
}
if (config.useCategorySet && catO.length) {
let sNR = await category.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
data: catO,
})
sNR ? null : (sNR = {})
if (sNR.error) {
errors.push(category.categoryId + "%is%" + sNR.error)
} else {
successes.push(category.categoryId)
}
}
let successesForDBDEvent = []
let errorsForDBDEvent = []
successes.forEach((item) => {
if (typeof item == "string") {
successesForDBDEvent.push(item.split("%is%"))
}
})
errors.forEach((item) => {
if (typeof item == "string") {
errorsForDBDEvent.push(item.split("%is%"))
}
})
req.DBDEvents.emit("guildSettingsUpdated", {
user: req.session.user,
changes: { successesForDBDEvent, errorsForDBDEvent },
guildId: req.params.guildId,
})
if (errors[0]) {
if (!successes) successes = []
req.session.success = successes.join("%and%")
req.session.errors = errors.join("%and%")
return res.redirect("/guild/" + req.params.guildId)
} else {
req.session.success = true
req.session.errors = false
return res.redirect("/guild/" + req.params.guildId)
}
}
)
return router
}
function convert14(perm) {
let final = "NULL"
switch (perm) {
case "CREATE_INSTANT_INVITE":
final = "CreateInstantInvite"
break
case "KICK_MEMBERS":
final = "KickMembers"
break
case "BAN_MEMBERS":
final = "BanMembers"
break
case "ADMINISTRATOR":
final = "Administrator"
break
case "MANAGE_CHANNELS":
final = "ManageChannels"
break
case "MANAGE_GUILD":
final = "ManageGuild"
break
case "ADD_REACTIONS":
final = "AddReactions"
break
case "VIEW_AUDIT_LOG":
final = "ViewAuditLog"
break
case "PRIORITY_SPEAKER":
final = "PrioritySpeaker"
break
case "STREAM":
final = "Stream"
break
case "VIEW_CHANNEL":
final = "ViewChannel"
break
case "SEND_MESSAGES":
final = "SendMessages"
break
case "SEND_TTS_MESSAGES":
final = "SendTTSMessages"
break
case "MANAGE_MESSAGES":
final = "ManageMessages"
break
case "EMBED_LINKS":
final = "ManageMessages"
break
case "ATTACH_FILES":
final = "AttachFiles"
break
case "READ_MESSAGE_HISTORY":
final = "ReadMessageHistory"
break
case "MENTION_EVERYONE":
final = "MentionEveryone"
break
case "USE_EXTERNAL_EMOJIS":
final = "UseExternalEmojis"
break
case "VIEW_GUILD_INSIGHTS":
final = "ViewGuildInsughts"
break
case "CONNECT":
final = "Connect"
break
case "SPEAK":
final = "Speak"
break
}
return final
}