dashboard-core/Routes/dashboard.js
2023-06-24 01:20:56 +05:00

555 lines
No EOL
18 KiB
JavaScript

const router = require("express").Router(),
RL = require("express-rate-limit");
module.exports = (app, config, themeConfig) => {
const RateLimits = config.rateLimits || {};
const 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,
});
}
const bot = config.bot;
if (!bot.guilds.cache.get(req.params.id)) {
try {
await bot.guilds.fetch(req.params.id);
} catch (e) { /* ... */ }
}
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 (e) { /* ... */ }
}
if (!bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id).permissions.has(config.requiredPermissions)) 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 (e) { /* ... */ }
}
if (bot.guilds.cache.get(req.params.id).roles.cache.size < 2) {
try {
await bot.guilds.cache.get(req.params.id).roles.fetch();
} catch (e) { /* ... */ }
}
const actual = {};
const 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.type == "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,
// });
// }
const bot = config.bot;
const member = bot.guilds.cache.get(req.params.guildId).members.cache.get(req.session.user.id);
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);
if (!member.permissions.has(config.requiredPermissions)) return res.redirect("/manage?error=noPermsToManageGuild");
const cid = req.params.categoryId;
const settings = config.settings;
const category = settings.find(c => c.categoryId == cid);
if (!category)
return res.send({
error: true,
message: "No category found",
});
let setNewRes;
const errors = [];
let successes = [];
const 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 (const 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);
}
const successesForDBDEvent = [];
const 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;
};