555 lines
No EOL
18 KiB
JavaScript
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" || c.optionType.type === "multiRow" || c.optionType.type === "embedBuilder") { /* ... */ } 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;
|
|
}; |