This commit is contained in:
Jonny_Bro (Nikita) 2023-06-22 19:36:52 +05:00
parent f61dc139f6
commit 849a93887a
96 changed files with 10351 additions and 10825 deletions

7
.d.ts vendored
View file

@ -3,9 +3,6 @@ declare module "discord-dashboard" {
const formTypes: formTypes
const customPagesTypes: customPagesTypes
const DISCORD_FLAGS: {
Permissions: Permissions
}
const version: string
}
@ -18,7 +15,7 @@ interface RateLimitSettingsObject {
}
interface Dashboard {
new (config: {
new(config: {
port: number
client: {
id: string
@ -29,11 +26,9 @@ interface Dashboard {
bot: any
theme: any
settings: category[]
requiredPermissions?: object,
ownerIDs: array,
useTheme404: boolean,
useThemeMaintenance: boolean,
acceptPrivacyPolicy?: boolean
noCreateServer?: boolean
SSL?: {
enabled: boolean

35
.gitignore vendored
View file

@ -1,33 +1,2 @@
./node_modules/
node_modules/
test/
/test
./test/
./test/
./.idea
discord-dashboard-pp
./discord-dashboard-pp
.idea
.devChannel
./.devChannel
./ExternalStatistics/index_unobfuscated.js
ExternalStatistics/index_unobfuscated.js
./dev_project.json
dev_project.json
altometra-dashboard
./altometra-dashboard
index_unobf.js
./index_unobf.js
/altometra-dashoard
altometra-dashboard/
./altometra-dashboard/
/altometra-dashoard/
./licensedDashboardClass_unobfuscated.js
./npmPublish.js
licensedDashboardClass_unobfuscated.js
npmPublish.js
updateObfuscatedIndex.js
./updateObfuscatedIndex.js
.idea
.idea
yarn-error.log
node_modules
package-lock.json

View file

@ -28,5 +28,4 @@ module.exports = (websiteTitle) => `<!DOCTYPE html>
</body>
</html>
`
</html>`;

View file

@ -1,36 +1,26 @@
const prefix = "[DBD-Storage-Handler]"
const colors = require("colors")
const Keyv = require("keyv")
const { join } = require("path")
const err = (text) => {
return `🐧${text} Do you need help? Join our Discord server: ${"https://discord.gg/CzfMGtrdaA".blue
}`
}
const prefix = "[DBD-Storage-Handler]";
const Keyv = require("keyv");
const { join } = require("path");
class Handler {
constructor(keyvAdapter) {
this.db = new Keyv(
keyvAdapter || `sqlite://${join(__dirname, "/database.sqlite")}`
)
this.db = new Keyv(keyvAdapter || `sqlite://${join(__dirname, "/database.sqlite")}`);
this.db.on("error", (err) =>
console.error(`${prefix} ${`Keyv connection error: ${err}`.red}`)
)
this.db.on("error", (err) => console.error(`${prefix} ${`Keyv connection error: ${err}`.red}`));
this.Category = require(`${__dirname}/structures/Category`)(this.db)
this.Option = require(`${__dirname}/structures/Option`)(this.db)
this.Category = require(`${__dirname}/structures/Category`)(this.db);
this.Option = require(`${__dirname}/structures/Option`)(this.db);
console.log(`${prefix} Database successfully initialized!`)
console.log(`${prefix} Database successfully initialized!`);
}
async fetch(guildId, optionId) {
return await this.db.get(`${guildId}.options.${optionId}`)
return await this.db.get(`${guildId}.options.${optionId}`);
}
db() {
return this.db
return this.db;
}
}
module.exports = Handler
module.exports = Handler;

View file

@ -1,15 +1,19 @@
module.exports = (db) => {
module.exports = db => {
return class Category {
constructor(
options = { categoryId: "", categoryName: "", categoryDescription: "" }
options = {
categoryId: "",
categoryName: "",
categoryDescription: "",
},
) {
this.categoryId = options.categoryId
this.categoryName = options.categoryName
this.categoryDescription = options.categoryDescription
this.categoryOptionsList = []
this.categoryId = options.categoryId;
this.categoryName = options.categoryName;
this.categoryDescription = options.categoryDescription;
this.categoryOptionsList = [];
// const db = Handler.getDB()
this.db = db
this.db = db;
}
/**
@ -18,9 +22,9 @@ module.exports = (db) => {
* @returns
*/
setId(id) {
this.categoryId = id
this.categoryId = id;
return this
return this;
}
/**
@ -29,9 +33,9 @@ module.exports = (db) => {
* @returns
*/
setName(name) {
this.categoryName = name
this.categoryName = name;
return this
return this;
}
/**
@ -40,9 +44,9 @@ module.exports = (db) => {
* @returns
*/
setDescription(description) {
this.categoryDescription = description
this.categoryDescription = description;
return this
return this;
}
/**
@ -51,9 +55,9 @@ module.exports = (db) => {
* @returns
*/
setImage(image) {
this.categoryImageURL = image
this.categoryImageURL = image;
return this
return this;
}
/**
@ -62,22 +66,17 @@ module.exports = (db) => {
* @returns
*/
setToggleable(toggleable) {
this.toggleable = toggleable
this.toggleable = toggleable;
this.getActualSet = async ({ guild }) => {
return await this.db.get(
`${guild.id}.categories.${this.categoryId}.toggle`
)
}
return await this.db.get(`${guild.id}.categories.${this.categoryId}.toggle`);
};
this.setNew = async ({ guild, newData }) => {
await this.db.set(
`${guild.id}.categories.${this.categoryId}.toggle`,
newData
)
}
await this.db.set(`${guild.id}.categories.${this.categoryId}.toggle`, newData);
};
return this
return this;
}
/**
@ -96,9 +95,9 @@ module.exports = (db) => {
* )
*/
addOptions() {
this.categoryOptionsList.push(...arguments)
this.categoryOptionsList.push(...arguments);
return this
return this;
}
}
}
};
};

View file

@ -1,12 +1,6 @@
const { formTypes } = require("discord-dashboard")
const { formTypes } = require("../../ModuleExportsFunctions/formTypes");
const ids = []
const err = (text) => {
return `🐧${text} Do you need help? Join our Discord server: ${
"https://discord.gg/CzfMGtrdaA".blue
}`
}
const ids = [];
module.exports = (db) => {
return class Option {
@ -16,23 +10,23 @@ module.exports = (db) => {
optionName: "",
optionDescription: "",
optionType: formTypes,
}
},
) {
//
this.optionId = options.optionId
this.optionName = options.optionName
this.optionDescription = options.optionDescription
this.optionType = options.optionType
this.optionId = options.optionId;
this.optionName = options.optionName;
this.optionDescription = options.optionDescription;
this.optionType = options.optionType;
this.categoryId = "default"
this.categoryId = "default";
this.setNew = async ({ guild, newData }) => {
await db.set(`${guild.id}.options.${this.optionId}`, newData)
}
await db.set(`${guild.id}.options.${this.optionId}`, newData);
};
this.getActualSet = async ({ guild }) => {
return await db.get(`${guild.id}.options.${this.optionId}`)
}
return await db.get(`${guild.id}.options.${this.optionId}`);
};
}
/**
@ -41,13 +35,12 @@ module.exports = (db) => {
* @returns
*/
setId(id) {
this.optionId = id
this.optionId = id;
if (ids.includes(id))
throw new Error(err(`Option id ${id} already exists`))
else ids.push(this.optionId)
if (ids.includes(id)) throw new Error(`Option id ${id} already exists`);
else ids.push(this.optionId);
return this
return this;
}
/**
@ -56,9 +49,9 @@ module.exports = (db) => {
* @returns
*/
setName(name) {
this.optionName = name
this.optionName = name;
return this
return this;
}
/**
@ -67,9 +60,9 @@ module.exports = (db) => {
* @returns
*/
setDescription(description) {
this.optionDescription = description
this.optionDescription = description;
return this
return this;
}
/**
@ -78,7 +71,7 @@ module.exports = (db) => {
* @returns
*/
setOptions(options) {
this.themeOptions = options
this.themeOptions = options;
}
/**
@ -87,9 +80,9 @@ module.exports = (db) => {
* @returns
*/
setType(type) {
this.optionType = type
this.optionType = type;
return this
return this;
}
}
}
};
};

View file

@ -1,99 +1,40 @@
const https = require("https")
const http = require("http")
const { Server: SocketServer } = require("socket.io")
const err = (text) => {
return (
text +
` Do you need help? Join our Discord server: ${
"https://discord.gg/CzfMGtrdaA".blue
}`
)
}
const https = require("https");
const http = require("http");
const { Server: SocketServer } = require("socket.io");
module.exports = (app, config, themeConfig, modules) => {
if (config.noCreateServer) return { io: null, server: null }
let server
if (config.noCreateServer) return { io: null, server: null };
if (!config.SSL) config.SSL = {}
let server;
if (!config.SSL) config.SSL = {};
if (config.SSL.enabled) {
if (!config.SSL.key || !config.SSL.cert)
console.log(
err(
`${
"discord-dashboard issue:".red
} The SSL preference for Dashboard is selected (config.SSL.enabled), but config does not include key or cert (config.SSL.key, config.SSL.cert).`
)
)
let options = {
if (!config.SSL.key || !config.SSL.cert) console.log(`${"discord-dashboard issue:".red} The SSL preference for Dashboard is selected (config.SSL.enabled), but config does not include key or cert (config.SSL.key, config.SSL.cert).`);
const options = {
key: config.SSL.key || "",
cert: config.SSL.cert || "",
}
};
try {
const https = require("https")
server = https.createServer(options, app)
server = https.createServer(options, app);
} catch (e) {
console.log(
err(
`${
"discord-dashboard issue:".red
} There's a problem while creating server, check if the port specified is already on use.`
)
)
console.log(`${"discord-dashboard issue:".red} There's a problem while creating server, check if the port specified is already on use.`);
}
} else {
const http = require("http")
server = http.createServer(app)
server = http.createServer(app);
}
let pport = ""
if (config.port !== 80 && config.port !== 443) {
pport = `:${config.port}`
}
let pport = "";
if (config.port != 80 && config.port != 443) pport = `:${config.port}`;
if (!config.minimizedConsoleLogs) {
console.log(
`
Discord Bot Dashboard
`.rainbow +
`
Thanks for using ${
"discord-dashboard".rainbow
} module! The server is up and running, so head over to the ${
`${(config.domain || "domain.com") + pport}`.blue
} website and start your fun.
console.log(`DBD Dashboard running on ${`${(config.domain || "domain.com") + pport}`.blue} !`);
Remember that there are ${
"themes".rainbow
} available to make the Dashboard look better: ${
"https://dbd-docs.assistantscenter.com/#/?id=themes".blue
}
If you need help with something or you don't understand something, please visit our ${
"Discord Support Server".rainbow
}: ${"https://discord.gg/CzfMGtrdaA".blue}
`
)
} else {
console.log(
`DBD Dashboard running on ${
`${(config.domain || "domain.com") + pport}`.blue
} !`
)
}
const SocketServer = require("socket.io").Server
const io = new SocketServer(server, {
cors: {
origin: "*",
},
})
});
modules.forEach((module) => {
module.server({
@ -101,9 +42,10 @@ If you need help with something or you don't understand something, please visit
server: server,
config: config,
themeConfig: themeConfig,
})
})
});
});
server.listen(config.port)
return { server, io }
}
server.listen(config.port);
return { server, io };
};

View file

@ -4,20 +4,20 @@ module.exports = {
type: "redirect",
endpoint: endpoint,
getEndpoint: getDataFunction,
}
};
},
renderHtml: (endpoint, getDataFunction) => {
return {
type: "html",
endpoint: endpoint,
getHtml: getDataFunction,
}
};
},
sendJson: (endpoint, getDataFunction) => {
return {
type: "json",
endpoint: endpoint,
getJson: getDataFunction,
}
};
},
}
};

View file

@ -1,43 +0,0 @@
module.exports = {
CREATE_INSTANT_INVITE: ["CREATE_INSTANT_INVITE", 0x1],
KICK_MEMBERS: ["KICK_MEMBERS", 0x2],
BAN_MEMBERS: ["BAN_MEMBERS", 0x4],
ADMINISTRATOR: ["ADMINISTRATOR", 0x8],
MANAGE_CHANNELS: ["MANAGE_CHANNELS", 0x10],
MANAGE_GUILD: ["MANAGE_GUILD", 0x20],
ADD_REACTIONS: ["ADD_REACTIONS", 0x40],
VIEW_AUDIT_LOG: ["VIEW_AUDIT_LOG", 0x80],
PRIORITY_SPEAKER: ["PRIORITY_SPEAKER", 0x100],
STREAM: ["STREAM", 0x200],
VIEW_CHANNEL: ["VIEW_CHANNEL", 0x400],
SEND_MESSAGES: ["SEND_MESSAGES", 0x800],
SEND_TTS_MESSAGES: ["SEND_TTS_MESSAGES", 0x1000],
MANAGE_MESSAGES: ["MANAGE_MESSAGES", 0x2000],
EMBED_LINKS: ["EMBED_LINKS", 0x4000],
ATTACH_FILES: ["ATTACH_FILES", 0x8000],
READ_MESSAGE_HISTORY: ["READ_MESSAGE_HISTORY", 0x10000],
MENTION_EVERYONE: ["MENTION_EVERYONE", 0x20000],
USE_EXTERNAL_EMOJIS: ["USE_EXTERNAL_EMOJIS", 0x40000],
VIEW_GUILD_INSIGHTS: ["VIEW_GUILD_INSIGHTS", 0x80000],
CONNECT: ["CONNECT", 0x100000],
SPEAK: ["SPEAK", 0x200000],
MUTE_MEMBERS: ["MUTE_MEMBERS", 0x400000],
DEAFEN_MEMBERS: ["DEAFEN_MEMBERS", 0x800000],
MOVE_MEMBERS: ["MOVE_MEMBERS", 0x1000000],
USE_VAD: ["USE_VAD", 0x2000000],
CHANGE_NICKNAME: ["CHANGE_NICKNAME", 0x4000000],
MANAGE_NICKNAMES: ["MANAGE_NICKNAMES", 0x8000000],
MANAGE_ROLES: ["MANAGE_ROLES", 0x10000000],
MANAGE_WEBHOOKS: ["MANAGE_WEBHOOKS", 0x20000000],
MANAGE_EMOJIS_AND_STICKERS: ["MANAGE_EMOJIS_AND_STICKERS", 0x40000000],
USE_APPLICATION_COMMANDS: ["USE_APPLICATION_COMMANDS", 0x80000000],
REQUEST_TO_SPEAK: ["REQUEST_TO_SPEAK", 0x100000000],
MANAGE_EVENTS: ["MANAGE_EVENTS", 0x200000000],
MANAGE_THREADS: ["MANAGE_THREADS", 0x400000000],
CREATE_PUBLIC_THREADS: ["CREATE_PUBLIC_THREADS", 0x800000000],
CREATE_PRIVATE_THREADS: ["CREATE_PRIVATE_THREADS", 0x1000000000],
USE_EXTERNAL_STICKERS: ["USE_EXTERNAL_STICKERS", 0x2000000000],
SEND_MESSAGES_IN_THREADS: ["SEND_MESSAGES_IN_THREADS", 0x4000000000],
START_EMBEDDED_ACTIVITIES: ["START_EMBEDDED_ACTIVITIES", 0x8000000000],
MODERATE_MEMBERS: ["MODERATE_MEMBERS", 0x10000000000],
}

View file

@ -1,17 +1,13 @@
const discordPermissions = require("./discordPermissions")
const { Permissions } = require("discord.js");
module.exports = {
select: (list, disabled, themeOptions = {}) => {
if (!list)
throw new Error(
err("List in the 'select' form type cannot be empty.")
)
if (typeof list != "object")
throw new Error(
err("List in the 'select' form type should be an JSON object.")
)
let keys = Object.keys(list)
let values = Object.values(list)
if (!list) throw new Error(console.log("List in the 'select' form type cannot be empty."));
if (typeof list != "object") throw new Error(console.log("List in the 'select' form type should be an JSON object."));
const keys = Object.keys(list);
const values = Object.values(list);
return {
type: "select",
data: {
@ -20,19 +16,15 @@ module.exports = {
},
disabled: disabled || false,
themeOptions,
}
};
},
multiSelect: (list, disabled, required, themeOptions = {}) => {
if (!list)
throw new Error(
err("List in the 'select' form type cannot be empty.")
)
if (typeof list != "object")
throw new Error(
err("List in the 'select' form type should be an JSON object.")
)
let keys = Object.keys(list)
let values = Object.values(list)
if (!list) throw new Error(console.log("List in the 'select' form type cannot be empty."));
if (typeof list != "object") throw new Error(console.log("List in the 'select' form type should be an JSON object."));
const keys = Object.keys(list);
const values = Object.values(list);
return {
type: "multiSelect",
data: {
@ -42,29 +34,13 @@ module.exports = {
disabled: disabled || false,
required: required || false,
themeOptions,
}
};
},
input: (placeholder, min, max, disabled, required, themeOptions = {}) => {
if (min) {
if (isNaN(min))
throw new Error(
err("'min' in the 'input' form type should be an number.")
)
}
if (max) {
if (isNaN(max))
throw new Error(
err("'max' in the 'input' form type should be an number.")
)
}
if (min && max) {
if (min > max)
throw new Error(
err(
"'min' in the 'input' form type cannot be higher than 'max'."
)
)
}
if (min && isNaN(min)) throw new Error(console.log("'min' in the 'input' form type should be an number."));
if (max && isNaN(max)) throw new Error(console.log("'max' in the 'input' form type should be an number."));
if ((min && max) && (min > max)) throw new Error(console.log("'min' in the 'input' form type cannot be higher than 'max'."));
return {
type: "input",
data: placeholder,
@ -73,36 +49,13 @@ module.exports = {
disabled: disabled || false,
required: required || false,
themeOptions,
}
};
},
textarea: (
placeholder,
min,
max,
disabled,
required,
themeOptions = {}
) => {
if (min) {
if (isNaN(min))
throw new Error(
err("'min' in the 'input' form type should be an number.")
)
}
if (max) {
if (isNaN(max))
throw new Error(
err("'max' in the 'input' form type should be an number.")
)
}
if (min && max) {
if (min > max)
throw new Error(
err(
"'min' in the 'input' form type cannot be higher than 'max'."
)
)
}
textarea: (placeholder, min, max, disabled, required, themeOptions = {}) => {
if (min && isNaN(min)) throw new Error(console.log("'min' in the 'input' form type should be an number."));
if (max && isNaN(max)) throw new Error(console.log("'max' in the 'input' form type should be an number."));
if ((min && max) && (min > max)) throw new Error(console.log("'min' in the 'input' form type cannot be higher than 'max'."));
return {
type: "textarea",
data: placeholder,
@ -111,221 +64,216 @@ module.exports = {
disabled: disabled || false,
required: required || false,
themeOptions,
}
};
},
switch: (disabled, themeOptions = {}) => {
return {
type: "switch",
disabled: disabled,
themeOptions,
}
};
},
checkbox: (disabled, themeOptions = {}) => {
return {
type: "checkbox",
disabled: disabled,
themeOptions,
}
};
},
channelsSelect: (
disabled,
channelTypes = ["GUILD_TEXT"],
hideNSFW,
onlyNSFW,
hideNoAccess,
themeOptions = {}
) => {
channelsSelect: (disabled, channelTypes = ["GUILD_TEXT"], hideNSFW, onlyNSFW, hideNoAccess, themeOptions = {}) => {
return {
type: "channelsSelect",
function: (client, guildid, userid) => {
let listCount = {}
const listCount = {};
let list = {
"-": "",
}
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache
.get(guildid)
.channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return
if (hideNSFW && channel.nsfw) return
if (onlyNSFW && !channel.nsfw) return
};
const guild = client.guilds.cache.get(guildid),
user = guild.members.cache.get(userid),
bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return;
if (hideNSFW && channel.nsfw) return;
if (onlyNSFW && !channel.nsfw) return;
if (hideNoAccess) {
if (!user.permissionsIn(channel).has('0x800') || !user.permissionsIn(channel).has('0x400')) return
if (!bot.permissionsIn(channel).has('0x800') || !bot.permissionsIn(channel).has('0x800')) return
if (!user.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !user.permissionsIn(channel).has(Permissions.FLAGS.VIEW_CHANNEL)) return;
if (!bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES)) return;
}
listCount[channel.name]
? (listCount[channel.name] =
listCount[channel.name] + 1)
: (listCount[channel.name] = 1)
if (list[channel.name])
list[
`${channel.name} (${listCount[channel.name]})`
] = channel.id
else list[channel.name] = channel.id
})
let myObj = list
let keys = Object.keys(myObj),
i = null,
len = keys.length
listCount[channel.name] ? (listCount[channel.name] = listCount[channel.name] + 1) : (listCount[channel.name] = 1);
keys.sort()
list = {}
if (list[channel.name]) list[`${channel.name} (${listCount[channel.name]})`] = channel.id;
else list[channel.name] = channel.id;
});
const myObj = list;
let i = null;
const keys = Object.keys(myObj),
len = keys.length;
keys.sort();
list = {};
for (i = 0; i < len; i++) {
k = keys[i]
list[k] = myObj[k]
const k = keys[i];
list[k] = myObj[k];
}
return {
values: Object.values(list),
keys: Object.keys(list),
}
};
},
disabled,
themeOptions,
}
};
},
channelsMultiSelect: (
disabled,
required,
channelTypes = ["GUILD_TEXT"],
hideNSFW,
onlyNSFW,
hideNoAccess,
themeOptions = {}
) => {
channelsMultiSelect: (disabled, required, channelTypes = ["GUILD_TEXT"], hideNSFW, onlyNSFW, hideNoAccess, themeOptions = {}) => {
return {
type: "channelsMultiSelect",
function: (client, guildid, userid) => {
let listCount = {}
let list = {}
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache
.get(guildid)
.channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return
if (hideNSFW && channel.nsfw) return
if (onlyNSFW && !channel.nsfw) return
const listCount = {};
let list = {};
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).channels.cache.forEach(channel => {
if (!channelTypes.includes(channel.type)) return;
if (hideNSFW && channel.nsfw) return;
if (onlyNSFW && !channel.nsfw) return;
if (hideNoAccess) {
if (!user.permissionsIn(channel).has('0x800') || !user.permissionsIn(channel).has('0x400')) return
if (!bot.permissionsIn(channel).has('0x800') || !bot.permissionsIn(channel).has('0x800')) return
if (!user.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !user.permissionsIn(channel).has(Permissions.FLAGS.VIEW_CHANNEL)) return;
if (!bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES)) return;
}
listCount[channel.name]
? (listCount[channel.name] =
listCount[channel.name] + 1)
: (listCount[channel.name] = 1)
if (list[channel.name])
list[
`${channel.name} (${listCount[channel.name]})`
] = channel.id
else list[channel.name] = channel.id
})
listCount[channel.name] ? (listCount[channel.name] = listCount[channel.name] + 1) : (listCount[channel.name] = 1);
let myObj = list
let keys = Object.keys(myObj),
i = null,
len = keys.length
if (list[channel.name]) list[`${channel.name} (${listCount[channel.name]})`] = channel.id;
else list[channel.name] = channel.id;
});
keys.sort()
list = {}
const myObj = list;
let i = null;
const keys = Object.keys(myObj),
len = keys.length;
keys.sort();
list = {};
for (i = 0; i < len; i++) {
k = keys[i]
list[k] = myObj[k]
const k = keys[i];
list[k] = myObj[k];
}
return {
values: Object.values(list),
keys: Object.keys(list),
}
};
},
disabled,
required,
themeOptions,
}
};
},
rolesMultiSelect: (disabled, required, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesMultiSelect",
function: (client, guildid, userid) => {
let listCount = {}
const list = []
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
const listCount = {};
const list = [];
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return
if (role.id === guildid) return // @everyone role
if (role.managed && !includeBots) return;
if (role.id === guildid) return; // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return
if (role.position >= bot.roles.highest.position) return
if (role.position >= user.roles.highest.position) return;
if (role.position >= bot.roles.highest.position) return;
}
listCount[role.name]
? (listCount[role.name] = listCount[role.name] + 1)
: (listCount[role.name] = 1)
listCount[role.name] ? (listCount[role.name] = listCount[role.name] + 1) : (listCount[role.name] = 1);
if (listCount[role.name] > 1)
list.push({ key: `${role.name} (${listCount[role.name]})`, value: role.id, position: role.position })
else list.push({ key: role.name, value: role.id, position: role.position })
})
list.push({
key: `${role.name} (${listCount[role.name]})`,
value: role.id,
position: role.position,
});
else list.push({
key: role.name,
value: role.id,
position: role.position,
});
});
list.sort((a, b) => b.position - a.position)
list.sort((a, b) => b.position - a.position);
const sortedList = {}
list.forEach(({ key, value }) => (sortedList[key] = value))
const sortedList = {};
list.forEach(({ key, value }) => (sortedList[key] = value));
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
}
};
},
disabled,
required,
themeOptions,
}
};
},
rolesSelect: (disabled, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesSelect",
function: (client, guildid, userid) => {
let listCount = {}
const list = [{ key: '-', value: '' }]
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
const listCount = {};
const list = [{
key: "-",
value: "",
}];
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return
if (role.id === guildid) return // @everyone role
if (role.managed && !includeBots) return;
if (role.id === guildid) return; // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return
if (role.position >= bot.roles.highest.position) return
if (role.position >= user.roles.highest.position) return;
if (role.position >= bot.roles.highest.position) return;
}
listCount[role.name]
? (listCount[role.name] = listCount[role.name] + 1)
: (listCount[role.name] = 1)
listCount[role.name] ? (listCount[role.name] = listCount[role.name] + 1) : (listCount[role.name] = 1);
if (listCount[role.name] > 1)
list.push({ key: `${role.name} (${listCount[role.name]})`, value: role.id, position: role.position })
else list.push({ key: role.name, value: role.id, position: role.position })
})
list.push({
key: `${role.name} (${listCount[role.name]})`,
value: role.id,
position: role.position,
});
else list.push({
key: role.name,
value: role.id,
position: role.position,
});
});
list.sort((a, b) => b.position - a.position)
list.sort((a, b) => b.position - a.position);
const sortedList = {}
list.forEach(({ key, value }) => (sortedList[key] = value))
const sortedList = {};
list.forEach(({ key, value }) => (sortedList[key] = value));
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
}
};
},
disabled,
themeOptions,
}
};
},
colorSelect: (defaultState, disabled, themeOptions = {}) => {
return {
@ -333,7 +281,7 @@ module.exports = {
data: defaultState,
disabled,
themeOptions,
}
};
},
embedBuilder: (defaultSettings, disabled, themeOptions = {}) => {
return {
@ -341,6 +289,6 @@ module.exports = {
data: defaultSettings,
disabled,
themeOptions,
}
};
},
}
};

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,18 @@
const router = require("express").Router()
const fetch = require("node-fetch")
const router = require("express").Router();
const RL = require("express-rate-limit");
const safeStorage = require("assistants-safe-storage");
const DiscordOauth2 = require("discord-oauth2")
const oauth = new DiscordOauth2()
const DiscordOauth2 = require("discord-oauth2");
const oauth = new DiscordOauth2();
module.exports = (app, config, themeConfig) => {
const scopes = config.guildAfterAuthorization?.use
? ["identify", "guilds", "guilds.join"]
: ["identify", "guilds"]
const RL = require("express-rate-limit")
const RateLimits = config.rateLimits || {}
let RateFunctions = {}
const storage = new safeStorage(config.bot.config.token);
const scopes = config.guildAfterAuthorization?.use ? ["identify", "guilds", "guilds.join"] : ["identify", "guilds"];
const NoRL = (req, res, next) => next()
const RateLimits = config.rateLimits || {};
const RateFunctions = {};
const NoRL = (req, res, next) => next();
if (RateLimits.discordOAuth2) {
RateFunctions.discordOAuth2 = RL.rateLimit({
@ -20,31 +20,28 @@ module.exports = (app, config, themeConfig) => {
max: RateLimits.discordOAuth2.max,
message: RateLimits.discordOAuth2.message,
store: RateLimits.discordOAuth2.store || new RL.MemoryStore(),
})
});
}
router.get("/", (req, res) => {
const clientId = req.client.id
const redirectUri = req.redirectUri
const clientId = req.client.id;
const redirectUri = req.redirectUri;
let newPage = "/"
if (themeConfig.landingPage?.enabled) newPage = "/dash"
req.session.r = req.query.r || newPage
let newPage = "/";
if (themeConfig.landingPage?.enabled) newPage = "/dash";
const authorizeUrl = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(
redirectUri
)}&response_type=code&scope=${scopes.join("%20")}`
res.redirect(authorizeUrl)
})
req.session.r = req.query.r || newPage;
const authorizeUrl = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${scopes.join("%20")}`;
res.redirect(authorizeUrl);
});
router.get("/status", async (req, res) => {
res.send(req.session?.discordAuthStatus)
})
res.send(req.session?.discordAuthStatus);
});
router.get(
"/callback",
RateFunctions.discordOAuth2 ? RateFunctions.discordOAuth2 : NoRL,
async (req, res) => {
router.get("/callback", RateFunctions.discordOAuth2 ? RateFunctions.discordOAuth2 : NoRL, async (req, res) => {
req.session.discordAuthStatus = {
loading: true,
success: null,
@ -52,24 +49,21 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: null,
},
}
const clientId = req.client.id
const clientSecret = req.client.secret
const redirectUri = req.redirectUri
};
const accessCode = req.query.code
if (!accessCode)
return res.redirect("/?error=NoAccessCodeReturnedFromDiscord")
const clientId = req.client.id;
const clientSecret = req.client.secret;
const redirectUri = req.redirectUri;
res.redirect("/loading")
const accessCode = req.query.code;
if (!accessCode) return res.redirect("/?error=NoAccessCodeReturnedFromDiscord");
let OAuth2Response
let OAuth2UserResponse
let OAuth2GuildsResponse
res.redirect("/loading");
let OAuth2Response;
let OAuth2UserResponse;
let OAuth2GuildsResponse;
/*
Get Discord OAuth2 API Response with Access Code gained
*/
try {
req.session.discordAuthStatus = {
loading: true,
@ -78,8 +72,10 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: "Requesting token...",
},
}
req.session.save(function (err) {})
};
req.session.save(function () {});
OAuth2Response = await oauth.tokenRequest({
clientId,
clientSecret,
@ -89,12 +85,10 @@ module.exports = (app, config, themeConfig) => {
grantType: "authorization_code",
redirectUri,
})
});
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2Response (line 86)",
err
)
console.log("Discord.js Route - OAuth2Response (line 88)\n" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -102,15 +96,16 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
};
req.session.save(function () {});
return;
}
/*
Get User from Discord OAuth2 API using gained access_token and update its values with tag and avatarURL
*/
try {
req.session.discordAuthStatus = {
loading: true,
@ -119,16 +114,14 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: "Getting User...",
},
}
req.session.save(function (err) {})
OAuth2UserResponse = await oauth.getUser(
OAuth2Response.access_token
)
};
req.session.save(function () {});
OAuth2UserResponse = await oauth.getUser(OAuth2Response.access_token);
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2UserResponse (line 118)",
err
)
console.log("Discord.js Route - OAuth2UserResponse (line 122)\n" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -136,29 +129,23 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
};
req.session.save(function () {});
return;
}
req.session.save(function (err) {})
return
}
OAuth2UserResponse.tag = `${OAuth2UserResponse.username}#${OAuth2UserResponse.discriminator}`
OAuth2UserResponse.avatarURL = OAuth2UserResponse.avatar
? `https://cdn.discordapp.com/avatars/${OAuth2UserResponse.id}/${OAuth2UserResponse.avatar}.png?size=1024`
: null
OAuth2UserResponse.tag = `${OAuth2UserResponse.username}#${OAuth2UserResponse.discriminator}`;
OAuth2UserResponse.avatarURL = OAuth2UserResponse.avatar ? `https://cdn.discordapp.com/avatars/${OAuth2UserResponse.id}/${OAuth2UserResponse.avatar}.png?size=1024` : null;
/*
Save user token in Assistants Secure Storage
*/
try {
req.AssistantsSecureStorage.SaveUser(
OAuth2UserResponse.id,
OAuth2Response.access_token
)
storage.SaveUser(OAuth2UserResponse.id, OAuth2Response.access_token);
} catch (err) {
req.config.reportError(
"Discord.js Route - Assistants Secure Storage (line 141)",
err
)
console.log("Discord.js Route - Assistants Secure Storage (line 147)\n" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -166,26 +153,27 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
};
req.session.save(function () {});
return;
}
/*
Save user in session
*/
req.session.user = OAuth2UserResponse
req.session.loggedInLastTime = true
req.session.user = OAuth2UserResponse;
req.session.loggedInLastTime = true;
/*
Register user to DBD Stats and emit userLoggedIn event
*/
try {
req.DBDEvents.emit("userLoggedIn", OAuth2UserResponse)
req.DBDEvents.emit("userLoggedIn", OAuth2UserResponse);
} catch (err) {
req.config.reportError("Discord.js Route - Register and DBDEvents emit userLoggedIn (line 170)", err)
console.log("Discord.js Route - DBDStats register and DBDEvent emit userLoggedIn (line 173)\n" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -193,15 +181,15 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
};
req.session.save(function () {});
return;
}
/*
Gain and update session with user guilds
*/
try {
req.session.discordAuthStatus = {
loading: true,
@ -210,16 +198,14 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: "Getting List of User Guilds...",
},
}
req.session.save(function (err) {})
OAuth2GuildsResponse = await oauth.getUserGuilds(
OAuth2Response.access_token
)
};
req.session.save(function () {});
OAuth2GuildsResponse = await oauth.getUserGuilds(OAuth2Response.access_token);
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse (line 201)",
err
)
req.config.reportError("Discord.js Route - OAuth2GuildsResponse (line 205)\n" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -227,16 +213,17 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
};
req.session.save(function () {});
return;
}
req.session.save(function (err) {})
return
}
req.session.guilds = OAuth2GuildsResponse || []
req.session.guilds = OAuth2GuildsResponse || [];
/*
Loop and fetch each guild into bots cache
*/
if (!req.config.disableResolvingGuildCache) {
try {
req.session.discordAuthStatus = {
@ -246,18 +233,18 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: "Resolving guilds cache...",
},
}
req.session.save(function (err) {})
for (let g of OAuth2GuildsResponse) {
};
req.session.save(function () {});
for (const g of OAuth2GuildsResponse) {
try {
await req.bot.guilds.fetch(g.id)
} catch (err) {}
await req.bot.guilds.fetch(g.id);
} catch (e) { /* ... */ }
}
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse Whole Loop (line 239)",
err
)
console.log("Discord.js Route - OAuth2GuildsResponse Whole Loop (line 244)" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
@ -265,9 +252,11 @@ module.exports = (app, config, themeConfig) => {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
};
req.session.save(function () {});
return;
}
}
@ -283,8 +272,10 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: "Authorizing user with guild...",
},
}
req.session.save(function (err) {})
};
req.session.save(function () {});
try {
await oauth.addMember({
accessToken: OAuth2Response.access_token,
@ -301,12 +292,9 @@ module.exports = (app, config, themeConfig) => {
deaf?: boolean,
}
*/
})
});
} catch (err) {
req.config.reportError(
"Discord.js Route - guildAfterAuthorization (line 287)",
err
)
req.config.reportError("Discord.js Route - guildAfterAuthorization (line 295)" + err);
}
}
@ -317,100 +305,93 @@ module.exports = (app, config, themeConfig) => {
error: null,
data: null,
},
}
req.session.save(function (err) {})
};
return
}
)
req.session.save(function () {});
return;
});
router.get("/logout", (req, res) => {
let r = req.query.r || "/"
req.session.destroy()
res.redirect(r)
})
const r = req.query.r || "/";
req.session.destroy();
res.redirect(r);
});
router.get("/guilds/reload", async (req, res) => {
if (!req.session.user) return res.redirect("/discord")
if (!req.session.user) return res.redirect("/discord");
/*
Fetch user token
*/
const access_token = storage.GetUser(req.session.user.id);
const access_token = req.AssistantsSecureStorage.GetUser(
req.session.user.id
)
if (!access_token)
return res.send({
error: true,
message: "You don't have any access_token saved.",
login_again_text: true,
})
});
/*
Gain and update session with user guilds
*/
let OAuth2GuildsResponse
let OAuth2GuildsResponse;
try {
OAuth2GuildsResponse = await oauth.getUserGuilds(access_token)
OAuth2GuildsResponse = await oauth.getUserGuilds(access_token);
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse for ReloadGuilds (line 335)",
err
)
req.config.reportError("Discord.js Route - OAuth2GuildsResponse for ReloadGuilds (line 342)" + err);
return res.send({
error: true,
message:
"An error occured. Access_token is wrong or you're being rate limited.",
message: "An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
})
});
}
req.session.guilds = OAuth2GuildsResponse || []
req.session.guilds = OAuth2GuildsResponse || [];
/*
Loop and fetch each guild into bots cache
*/
try {
const Promises = []
for (let g of OAuth2GuildsResponse) {
const Promises = [];
for (const g of OAuth2GuildsResponse) {
Promises.push(
// eslint-disable-next-line no-unused-vars, no-async-promise-executor
new Promise(async (resolve, reject) => {
try {
await req.bot.guilds.fetch(g.id)
} catch (err) {}
resolve(1)
})
)
await req.bot.guilds.fetch(g.id);
} catch (e) { /* ... */ }
resolve(1);
}),
);
try {
await Promises.all(Promises)
} catch (err) {}
await Promises.all(Promises);
} catch (e) { /* ... */ }
}
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse Whole Loop for ReloadGuilds (line 363)",
err
)
console.log("Discord.js Route - OAuth2GuildsResponse Whole Loop for ReloadGuilds (line 375)" + err);
return res.send({
error: true,
message:
"An error occured. Access_token is wrong or you're being rate limited.",
message: "An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
})
});
}
/*
Success
*/
return res.send({
error: false,
message: null,
login_again_text: false,
})
})
});
});
return router
}
return router;
};

View file

@ -1,16 +1,18 @@
const Discord = require("discord.js")
const router = require("express").Router()
const router = require("express").Router();
// eslint-disable-next-line no-unused-vars
module.exports = (app, config, themeConfig, modules) => {
router.get(
themeConfig.landingPage?.enabled ? "/dash" : "/",
async (req, res) => {
let customThemeOptions
router.get(themeConfig.landingPage?.enabled ? "/dash" : "/", async (req, res) => {
let customThemeOptions;
if (themeConfig?.customThemeOptions?.index) {
customThemeOptions = await themeConfig.customThemeOptions.index(
{ req: req, res: res, config: config }
)
customThemeOptions = await themeConfig.customThemeOptions.index({
req: req,
res: res,
config: config,
});
}
res.render("index", {
req: req,
themeConfig: req.themeConfig,
@ -18,105 +20,72 @@ module.exports = (app, config, themeConfig, modules) => {
customThemeOptions: customThemeOptions || {},
config,
require,
})
}
)
});
});
if (themeConfig.landingPage?.enabled)
router.get("/", async (req, res) => {
res.setHeader("Content-Type", "text/html")
res.send(await themeConfig.landingPage.getLandingPage(req, res))
})
res.setHeader("Content-Type", "text/html");
res.send(await themeConfig.landingPage.getLandingPage(req, res));
});
router.get("/loading", async (req, res) => {
if (!req.session?.discordAuthStatus?.loading)
return res.redirect("/manage")
return res.redirect("/manage");
res.render("loading", { req, themeConfig, bot: config.bot })
})
res.render("loading", {
req,
themeConfig,
bot: config.bot,
});
});
router.get("/invite", (req, res) => {
let config = req.config
config.invite ? null : (config.invite = {})
const scopes = config.invite.scopes || ["bot"]
const config = req.config;
config.invite ? null : (config.invite = {});
const scopes = config.invite.scopes || ["bot"];
if (req.query.redirect && !req.query.g)
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}&response_type=code&redirect_uri=${req.query.redirect}${
config.invite.otherParams || ""
}`
)
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}&response_type=code&redirect_uri=${req.query.redirect}${config.invite.otherParams || ""}`);
if (req.query.redirect && req.query.g)
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}&response_type=code&redirect_uri=${
req.query.redirect
}&guild_id=${req.query.g}${config.invite.otherParams || ""}`
)
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}&response_type=code&redirect_uri=${req.query.redirect}&guild_id=${req.query.g}${config.invite.otherParams || ""}`);
if (req.query.g) {
let thingymabob = config.invite.redirectUri
? `&response_type=code&redirect_uri=${config.invite.redirectUri}`
: null;
if(!thingymabob) thingymabob = config.invite.specialredirectUri
? `&response_type=code&redirect_uri=${config.invite.specialRedirectUri.replace("{SERVER}", req.query.g)}`
: "";
let thingymabob = config.invite.redirectUri ? `&response_type=code&redirect_uri=${config.invite.redirectUri}` : null;
if (!thingymabob) thingymabob = config.invite.specialredirectUri ? `&response_type=code&redirect_uri=${config.invite.specialRedirectUri.replace("{SERVER}", req.query.g)}` : "";
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}${thingymabob}&guild_id=${req.query.g}${config.invite.otherParams || ""}`
)
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}${thingymabob}&guild_id=${req.query.g}${config.invite.otherParams || ""}`);
}
res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}${
config.invite.redirectUri
? `&response_type=code&redirect_uri=${config.invite.redirectUri}`
: ""
}${config.invite.otherParams || ""}`
)
})
res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}${config.invite.redirectUri ? `&response_type=code&redirect_uri=${config.invite.redirectUri}` : ""}${config.invite.otherParams || ""}`);
});
if (!config.supportServer) config.supportServer = {}
if (!config.supportServer) config.supportServer = {};
router.get(config.supportServer.slash || "/support-server", (req, res) => {
let config = req.config
config.supportServer ? null : (config.supportServer = {})
const config = req.config;
config.supportServer ? null : (config.supportServer = {});
if (!config.supportServer.inviteUrl)
return res.send({
error: true,
message:
"No inviteUrl defined (discord-dashboard config.supportServer).",
})
if (
!config.supportServer.inviteUrl
message: "No inviteUrl defined (discord-dashboard config.supportServer).",
});
if (!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.gg/") &&
!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.com/")
)
return res.send({
) return res.send({
error: true,
message:
"Invite url should start with 'https://discord.gg/' or 'https://discord.com/'.",
})
res.redirect(config.supportServer.inviteUrl)
})
message: "Invite url should start with 'https://discord.gg/' or 'https://discord.com/'.",
});
return router
}
res.redirect(config.supportServer.inviteUrl);
});
return router;
};

View file

@ -1,47 +1,52 @@
const EventEmitter = require('events');
const DBDEvents = new EventEmitter();
const version = require("./package.json").version;
const EventEmitter = require("events"),
express = require("express"),
app = express(),
session = require("express-session"),
bodyParser = require("body-parser"),
partials = require("express-partials"),
router = require("./router"),
initServer = require("./InitFunctions/initServer");
const err = (text) => {
return text + ` Do you need help? Join our Discord server: ${'https://discord.gg/CzfMGtrdaA'.blue}`;
}
const version = require("./package.json").version;
const DBDEvents = new EventEmitter();
class Dashboard {
constructor(config) {
let notSetYetAndRequired = [];
if (!config.port) notSetYetAndRequired.push('port');
if (!config.theme) notSetYetAndRequired.push('theme');
if (!config.client) notSetYetAndRequired.push('client');
if (!config.redirectUri) notSetYetAndRequired.push('redirectUri');
if (!config.bot) notSetYetAndRequired.push('bot');
if (!config.settings) notSetYetAndRequired.push('settings');
if (!config.domain) notSetYetAndRequired.push('domain');
if (notSetYetAndRequired[0]) throw new Error(err(`You need to define some more things: ${notSetYetAndRequired.join(', ')}.`));
const notSetYetAndRequired = [];
if (!config.port) notSetYetAndRequired.push("port");
if (!config.theme) notSetYetAndRequired.push("theme");
if (!config.client) notSetYetAndRequired.push("client");
if (!config.redirectUri) notSetYetAndRequired.push("redirectUri");
if (!config.bot) notSetYetAndRequired.push("bot");
if (!config.settings) notSetYetAndRequired.push("settings");
if (!config.domain) notSetYetAndRequired.push("domain");
if (notSetYetAndRequired[0]) throw new Error(`You need to define some more things: ${notSetYetAndRequired.join(", ")}.`);
this.config = config;
this.modules = [];
}
async init() {
const modules = this.modules;
const config = this.config;
const express = require('express');
const app = express();
const session = require('express-session');
const bodyParser = require('body-parser');
const partials = require('express-partials');
const v13support = require('discord.js').version.slice(0, 2) == "13";
const config = this.config,
modules = this.modules;
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(partials());
app.set('views', config.theme.viewsPath);
app.use(express.static(config.theme.staticPath));app.use('/', express.static(config.theme.staticPath));app.use('/:a/', express.static(config.theme.staticPath));app.use('/:a/:b/', express.static(config.theme.staticPath));app.use('/:a/:b/:c/', express.static(config.theme.staticPath));app.use('/:a/:b/:c/:d/', express.static(config.theme.staticPath));
app.set('view engine', 'ejs');
let sessionData = {
secret: config.cookiesSecret || 'total_secret_cookie_secret',
app.use(express.static(config.theme.staticPath));
app.use("/", express.static(config.theme.staticPath));
app.use("/:a/", express.static(config.theme.staticPath));
app.use("/:a/:b/", express.static(config.theme.staticPath));
app.use("/:a/:b/:c/", express.static(config.theme.staticPath));
app.use("/:a/:b/:c/:d/", express.static(config.theme.staticPath));
app.set("views", config.theme.viewsPath);
app.set("view engine", "ejs");
const sessionData = {
secret: config.cookiesSecret || "total_secret_cookie_secret",
resave: true,
saveUninitialized: true,
cookie: {
@ -49,13 +54,14 @@ class Dashboard {
maxAge: 253402300799999,
},
};
config.sessionSaveSession ? sessionData.store = config.sessionSaveSession : null;
app.use(session(sessionData));
let themeConfig = config.theme.themeConfig;
const themeConfig = config.theme.themeConfig;
app.get('*', (req,res,next) => {
DBDEvents.emit('websiteView', req.session.user ? req.session.user : {loggedIn: false});
app.get("*", (req, res, next) => {
DBDEvents.emit("websiteView", req.session.user ? req.session.user : { loggedIn: false });
next();
});
@ -63,7 +69,7 @@ class Dashboard {
app.use((req, res, next) => {
req.DBDEvents = DBDEvents;
if(req.session.loggedInLastTime == true){
if (req.session.loggedInLastTime == true) {
req.displayLoggedInInfo = true;
req.session.loggedInLastTime = false;
}
@ -77,18 +83,20 @@ class Dashboard {
req.botToken = config.bot.token;
req.guildAfterAuthorization = config.guildAfterAuthorization || {};
req.websiteTitle = config.websiteTitle || "Discord Web Dashboard";
req.iconUrl = config.iconUrl || 'https://www.nomadfoods.com/wp-content/uploads/2018/08/placeholder-1-e1533569576673.png';
req.websiteTitle = config.websiteTitle || "Discord Bot Dashboard";
req.iconUrl = config.iconUrl || "https://www.nomadfoods.com/wp-content/uploads/2018/08/placeholder-1-e1533569576673.png";
req.app = app;
req.config = config;
next();
});
require('./router')(app, config, themeConfig, modules);
router(app, config, themeConfig, modules);
this.app = app;
let sio = require('./InitFunctions/initServer')(app, config, themeConfig, modules);
const sio = initServer(app, config, themeConfig, modules);
this.server = sio.server;
this.io = sio.io;
}
@ -104,8 +112,8 @@ class Dashboard {
module.exports = {
Dashboard,
formTypes: require('./ModuleExportsFunctions/formTypes'),
customPagesTypes: require('./ModuleExportsFunctions/customPagesTypes'),
formTypes: require("./ModuleExportsFunctions/formTypes"),
customPagesTypes: require("./ModuleExportsFunctions/customPagesTypes"),
DBDEvents,
version
}
version,
};

View file

@ -1,19 +1,14 @@
{
"name": "discord-dashboard",
"version": "2.3.61",
"description": "Create an Dashboard for your bot in 10 minutes without APIs knowledge and slapping code from scratch!",
"version": "1.0",
"description": "dashboard",
"main": "index.js",
"directories": {
"test": "test"
},
"typings": ".d.ts",
"dependencies": {
"assistants-safe-storage": "^1.0.0",
"body-parser": "^1.20.0",
"colors": "^1.4.0",
"cookie-parser": "^1.4.6",
"discord-dashboard": "^2.3.39",
"discord-dashboard-pp-system": "^1.0.2",
"discord-oauth2": "^2.10.0",
"discord.js": "*",
"ejs": "^3.1.8",
@ -24,32 +19,103 @@
"https": "^1.0.0",
"keyv": "^4.5.2",
"node-fetch": "^2.6.7",
"readline-sync": "^1.4.10",
"socket.io": "^4.5.1",
"uuid": "^8.3.2"
"quick.db": "^7.1.3",
"socket.io": "^4.5.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "breftejk",
"license": "CC BY-NC-SA 4.0",
"homepage": "https://dbd-docs.assistantscenter.com/",
"keywords": [
"discord",
"discord.js",
"discordjs",
"discord dashboard",
"discord web dashboard",
"web dashboard",
"dashboard"
],
"repository": {
"type": "git",
"url": "https://github.com/Assistants-Center/Discord.js-Web-Dashboard.git"
},
"devDependencies": {
"dbd-dark-dashboard": "^1.6.58",
"eslint": "^8.23.0",
"javascript-obfuscator": "^4.0.0",
"prettier": "2.7.1"
},
"eslintConfig": {
"env": {
"commonjs": true,
"es6": true,
"es2020": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {
"arrow-spacing": [
"warn",
{
"before": true,
"after": true
}
],
"comma-dangle": [
"error",
"always-multiline"
],
"comma-spacing": "error",
"comma-style": "error",
"dot-location": [
"error",
"property"
],
"handle-callback-err": "off",
"indent": [
"error",
"tab",
{
"SwitchCase": 1
}
],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
{
"max": 4
}
],
"max-statements-per-line": [
"error",
{
"max": 2
}
],
"no-console": "off",
"no-multi-spaces": "error",
"no-multiple-empty-lines": [
"error",
{
"max": 2,
"maxEOF": 1,
"maxBOF": 0
}
],
"no-trailing-spaces": [
"error"
],
"no-var": "error",
"object-curly-spacing": [
"error",
"always"
],
"prefer-const": "error",
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"yoda": "error"
}
}
}

188
router.js
View file

@ -1,82 +1,63 @@
const cookieParser = require("cookie-parser"),
underMaintenancePageDefault = require("./underMaintenancePageDefault"),
error404pageDefault = require("./404pagedefault");
const mainRouter = require("./Routes/main"),
dashboardRouter = require("./Routes/dashboard"),
discordRouter = require("./Routes/discord");
module.exports = (app, config, themeConfig, modules) => {
app.use(require("cookie-parser")())
app.use(cookieParser());
app.use((req, res, next) => {
req.bot = config.bot
next()
})
req.bot = config.bot;
next();
});
if (themeConfig.defaultLocales) {
app.use((req, res, next) => {
if (req.cookies?.lang) req.lang = req.cookies.lang
else req.lang = req.acceptsLanguages()[0].replace("-", "")
if (req.cookies?.lang) req.lang = req.cookies.lang;
else req.lang = req.acceptsLanguages()[0].replace("-", "");
if (themeConfig.locales) {
if (Object.keys(themeConfig.locales).includes(req.lang)) {
req.locales = themeConfig.locales[req.lang]
} else {
req.locales =
themeConfig.locales[Object.keys(themeConfig.locales)[0]]
}
} else {
req.locales =
themeConfig.defaultLocales[
Object.keys(themeConfig.defaultLocales).includes(
req.lang
)
? req.lang
: "enUS"
]
if (Object.keys(themeConfig.locales).includes(req.lang)) req.locales = themeConfig.locales[req.lang];
else req.locales = themeConfig.locales[Object.keys(themeConfig.locales)[0]];
} else
req.locales = themeConfig.defaultLocales[Object.keys(themeConfig.defaultLocales).includes(req.lang) ? req.lang : "enUS"];
next();
});
}
next()
})
}
app.use(
"/discord",
require("./Routes/discord")(app, config, themeConfig, modules)
)
app.use("/discord", discordRouter(app, config, themeConfig, modules));
if (config.useUnderMaintenance) {
app.get(
config.underMaintenanceAccessPage || "/total-secret-get-access",
(req, res) => {
app.get(config.underMaintenanceAccessPage || "/total-secret-get-access", (req, res) => {
res.send(`
<form action="${config.domain}${
config.underMaintenanceAccessPage ||
"/total-secret-get-access"
}" method="POST" >
<form action="${config.domain}${config.underMaintenanceAccessPage || "/total-secret-get-access"}" method="POST" >
<input id="accessKey" name="accessKey"/>
<button role="submit">Submit</button>
</form>
`)
}
)
`);
});
app.post(
config.underMaintenanceAccessPage || "/total-secret-get-access",
(req, res) => {
if (!req.body) req.body = {}
const accessKey = req.body.accessKey
if (accessKey != config.underMaintenanceAccessKey)
return res.send("Wrong key.")
req.session.umaccess = true
res.redirect("/")
}
)
app.post(config.underMaintenanceAccessPage || "/total-secret-get-access", (req, res) => {
if (!req.body) req.body = {};
const accessKey = req.body.accessKey;
if (accessKey != config.underMaintenanceAccessKey) return res.send("Wrong key.");
req.session.umaccess = true;
res.redirect("/");
});
app.use((req, res, next) => {
if (req.originalUrl.startsWith("/loading")) return next()
if (req.originalUrl.startsWith("/loading")) return next();
if (!req.session.umaccess && !req.session.user) {
if (!config.useThemeMaintenance)
return res.send(
config.underMaintenanceCustomHtml ||
require("./underMaintenancePageDefault")(
config.underMaintenance,
false
)
)
return res.send(config.underMaintenanceCustomHtml || underMaintenancePageDefault(config.underMaintenance, false));
else
res.render("maintenance", {
req: req,
@ -84,20 +65,10 @@ module.exports = (app, config, themeConfig, modules) => {
themeConfig: req.themeConfig,
loggedIn: false,
defaultMaintenanceConfig: config.underMaintenance || {},
})
} else if (
!req.session.umaccess &&
config.ownerIDs &&
!config.ownerIDs.includes(req.session.user.id)
) {
});
} else if (!req.session.umaccess && config.ownerIDs && !config.ownerIDs.includes(req.session.user.id)) {
if (!config.useThemeMaintenance)
return res.send(
config.underMaintenanceCustomHtml ||
require("./underMaintenancePageDefault")(
config.underMaintenance,
true
)
)
return res.send(config.underMaintenanceCustomHtml || underMaintenancePageDefault(config.underMaintenance, true));
else
res.render("maintenance", {
req: req,
@ -105,69 +76,62 @@ module.exports = (app, config, themeConfig, modules) => {
themeConfig: req.themeConfig,
loggedIn: true,
defaultMaintenanceConfig: config.underMaintenance || {},
})
} else next()
})
});
} else next();
});
}
app.use("/", require("./Routes/main")(app, config, themeConfig, modules))
app.use(
"/",
require("./Routes/dashboard")(app, config, themeConfig, modules)
)
app.use("/", mainRouter(app, config, themeConfig, modules));
app.use("/", dashboardRouter(app, config, themeConfig, modules));
config.theme.init(app, config)
config.theme.init(app, config);
let customPages = config.customPages || []
customPages.forEach((p) => {
const customPages = config.customPages || [];
customPages.forEach(p => {
if (p.type == "redirect") {
app.get(p.endpoint, async (req, res) => {
let endpoint = await p.getEndpoint({
const endpoint = await p.getEndpoint({
user: req.session.user || {},
req,
})
res.redirect(endpoint)
})
});
res.redirect(endpoint);
});
} else if (p.type == "html") {
app.get(p.endpoint, async (req, res) => {
let html = await p.getHtml({
const html = await p.getHtml({
user: req.session.user || {},
req,
})
res.send(html)
})
});
res.send(html);
});
} else if (p.type == "json") {
app.get(p.endpoint, async (req, res) => {
let json = await p.getJson({
const json = await p.getJson({
user: req.session.user || {},
req,
})
res.send(json)
})
}
})
});
modules.forEach((module) => {
res.send(json);
});
}
});
modules.forEach(module => {
module.app({
app: app,
config: this.config,
themeConfig: themeConfig,
})
})
});
});
if (!config.useTheme404) {
app.get("*", (req, res) => {
let text =
config.html404 ||
require("./404pagedefault")(
config.websiteTitle || themeConfig.websiteName
)
res.send(
text.replace(
"{{websiteTitle}}",
config.websiteTitle || themeConfig.websiteName
)
)
})
const text = config.html404 || error404pageDefault(config.websiteTitle || themeConfig.websiteName);
res.send(text.replace("{{websiteTitle}}", config.websiteTitle || themeConfig.websiteName));
});
}
}
};

View file

@ -1,288 +1,289 @@
const icons = [
'address-book',
'address-card',
'adjust',
'air-freshener',
'align-center',
'align-left',
'align-right',
'ambulance',
'angle-double-down',
'angle-double-left',
'angle-double-right',
'angle-double-up',
'angle-down',
'angle-left',
'angle-right',
'angle-up',
'archive',
'arrow-alt-circle-down',
'arrow-alt-circle-left',
'arrow-alt-circle-right',
'arrow-alt-circle-up',
'arrow-down',
'arrow-left',
'arrow-right',
'arrow-up',
'arrows-alt',
'arrows-alt-h',
'arrows-alt-v',
'assistive-listening-systems',
'asterisk',
'at',
'atlas',
'award',
'backspace',
'backward',
'bahai',
'ban',
'band-aid',
'bars',
'battery-empty',
'battery-full',
'battery-half',
'battery-quarter',
'battery-three-quarters',
'bed',
'beer',
'bell',
'bell-slash',
'birthday-cake',
'bolt',
'bomb',
'bone',
'book',
'book-dead',
'book-medical',
'book-open',
'bookmark',
'border-all',
'border-none',
'border-style',
'bowling-ball',
'box',
'box-open',
'briefcase',
'broadcast-tower',
'bug',
'building',
'bullhorn',
'calculator',
'calendar',
'calendar-alt',
'calendar-check',
'calendar-day',
'calendar-minus',
'calendar-plus',
'calendar-times',
'calendar-week',
'camera',
'caret-down',
'caret-left',
'caret-right',
'caret-up',
'certificate',
'chair',
'chalkboard',
'charging-station',
'chart-bar',
'chart-line',
'chart-pie',
'check',
'check-circle',
'check-square',
'circle',
'circle-notch',
'clipboard',
'clock',
'clone',
'cloud',
'cloud-download-alt',
'cloud-meatball',
'cloud-moon',
'cloud-moon-rain',
'cloud-rain',
'cloud-showers-heavy',
'cloud-sun',
'cloud-sun-rain',
'cloud-upload-alt',
'code',
'code-branch',
'cog',
'cogs',
'columns',
'comment',
'comment-alt',
'comment-dollar',
'comment-dots',
'comment-medical',
'comment-slash',
'comments',
'comments-dollar',
'compact-disc',
'compass',
'compress-alt',
'cookie',
'cookie-bite',
'copy',
'credit-card',
'crop',
'crop-alt',
'cut',
'database',
'desktop',
'edit',
'envelope',
'envelope-open',
'eraser',
'ethernet',
'exchange-alt',
'exclamation',
'exclamation-circle',
'exclamation-triangle',
'expand',
'expand-alt',
'external-link-alt',
'eye',
'eye-dropper',
'eye-slash',
'fan',
'file',
'file-alt',
'file-archive',
'file-audio',
'file-code',
'file-download',
'fill',
'fill-drip',
'filter',
'fingerprint',
'fire',
'fire-alt',
'folder',
'folder-open',
'forward',
'gamepad',
'ghost',
'gift',
'gifts',
'globe',
'globe-africa',
'globe-asia',
'globe-europe',
'headphones',
'headphones-alt',
'headset',
'heart',
'heart-broken',
'heartbeat',
'history',
'home',
'info',
'keyboard',
'layer-group',
'list',
'lock',
'lock-open',
'map-marker',
'map-marker-alt',
'microphone',
'microphone-alt',
'microphone-alt-slash',
'minus',
'mobile',
'mobile-alt',
'moon',
'mouse',
'mouse-pointer',
'music',
'network-wired',
'neuter',
'paperclip',
'paste',
'pause',
'paw',
'pen',
'pencil-alt',
'percent',
'percentage',
'phone',
'phone-alt',
'phone-slash',
'phone-volume',
'photo-video',
'power-off',
'question',
'question-circle',
'redo',
'redo-alt',
'reply',
'robot',
'rocket',
'rss',
'satellite-dish',
'save',
'search',
'server',
'shapes',
'share',
'share-alt',
'shield-alt',
'signal',
'skull',
'skull-crossbones',
'sliders-h',
'sort',
'spinner',
'times',
'times-circle',
'toggle-off',
'toggle-on',
'toolbox',
'tools',
'trash',
'trash-alt',
'tv',
'undo',
'undo-alt',
'unlink',
'unlock',
'unlock-alt',
'upload',
'user',
'user-alt',
'volume-down',
'volume-mute',
'volume-off',
'volume-up',
'wifi',
'wrench'
]
"address-book",
"address-card",
"adjust",
"air-freshener",
"align-center",
"align-left",
"align-right",
"ambulance",
"angle-double-down",
"angle-double-left",
"angle-double-right",
"angle-double-up",
"angle-down",
"angle-left",
"angle-right",
"angle-up",
"archive",
"arrow-alt-circle-down",
"arrow-alt-circle-left",
"arrow-alt-circle-right",
"arrow-alt-circle-up",
"arrow-down",
"arrow-left",
"arrow-right",
"arrow-up",
"arrows-alt",
"arrows-alt-h",
"arrows-alt-v",
"assistive-listening-systems",
"asterisk",
"at",
"atlas",
"award",
"backspace",
"backward",
"bahai",
"ban",
"band-aid",
"bars",
"battery-empty",
"battery-full",
"battery-half",
"battery-quarter",
"battery-three-quarters",
"bed",
"beer",
"bell",
"bell-slash",
"birthday-cake",
"bolt",
"bomb",
"bone",
"book",
"book-dead",
"book-medical",
"book-open",
"bookmark",
"border-all",
"border-none",
"border-style",
"bowling-ball",
"box",
"box-open",
"briefcase",
"broadcast-tower",
"bug",
"building",
"bullhorn",
"calculator",
"calendar",
"calendar-alt",
"calendar-check",
"calendar-day",
"calendar-minus",
"calendar-plus",
"calendar-times",
"calendar-week",
"camera",
"caret-down",
"caret-left",
"caret-right",
"caret-up",
"certificate",
"chair",
"chalkboard",
"charging-station",
"chart-bar",
"chart-line",
"chart-pie",
"check",
"check-circle",
"check-square",
"circle",
"circle-notch",
"clipboard",
"clock",
"clone",
"cloud",
"cloud-download-alt",
"cloud-meatball",
"cloud-moon",
"cloud-moon-rain",
"cloud-rain",
"cloud-showers-heavy",
"cloud-sun",
"cloud-sun-rain",
"cloud-upload-alt",
"code",
"code-branch",
"cog",
"cogs",
"columns",
"comment",
"comment-alt",
"comment-dollar",
"comment-dots",
"comment-medical",
"comment-slash",
"comments",
"comments-dollar",
"compact-disc",
"compass",
"compress-alt",
"cookie",
"cookie-bite",
"copy",
"credit-card",
"crop",
"crop-alt",
"cut",
"database",
"desktop",
"edit",
"envelope",
"envelope-open",
"eraser",
"ethernet",
"exchange-alt",
"exclamation",
"exclamation-circle",
"exclamation-triangle",
"expand",
"expand-alt",
"external-link-alt",
"eye",
"eye-dropper",
"eye-slash",
"fan",
"file",
"file-alt",
"file-archive",
"file-audio",
"file-code",
"file-download",
"fill",
"fill-drip",
"filter",
"fingerprint",
"fire",
"fire-alt",
"folder",
"folder-open",
"forward",
"gamepad",
"ghost",
"gift",
"gifts",
"globe",
"globe-africa",
"globe-asia",
"globe-europe",
"headphones",
"headphones-alt",
"headset",
"heart",
"heart-broken",
"heartbeat",
"history",
"home",
"info",
"keyboard",
"layer-group",
"list",
"lock",
"lock-open",
"map-marker",
"map-marker-alt",
"microphone",
"microphone-alt",
"microphone-alt-slash",
"minus",
"mobile",
"mobile-alt",
"moon",
"mouse",
"mouse-pointer",
"music",
"network-wired",
"neuter",
"paperclip",
"paste",
"pause",
"paw",
"pen",
"pencil-alt",
"percent",
"percentage",
"phone",
"phone-alt",
"phone-slash",
"phone-volume",
"photo-video",
"power-off",
"question",
"question-circle",
"redo",
"redo-alt",
"reply",
"robot",
"rocket",
"rss",
"satellite-dish",
"save",
"search",
"server",
"shapes",
"share",
"share-alt",
"shield-alt",
"signal",
"skull",
"skull-crossbones",
"sliders-h",
"sort",
"spinner",
"times",
"times-circle",
"toggle-off",
"toggle-on",
"toolbox",
"tools",
"trash",
"trash-alt",
"tv",
"undo",
"undo-alt",
"unlink",
"unlock",
"unlock-alt",
"upload",
"user",
"user-alt",
"volume-down",
"volume-mute",
"volume-off",
"volume-up",
"wifi",
"wrench",
];
const otherIcons = [
'youtube',
'discord',
'node',
'apple',
'sellsy',
'app-store',
'cloudflare',
'dev',
'github-alt',
'gitlab',
'google',
'itunes-note',
'node-js',
'npm',
'spotify',
'usb',
'windows'
]
"youtube",
"discord",
"node",
"apple",
"sellsy",
"app-store",
"cloudflare",
"dev",
"github-alt",
"gitlab",
"google",
"itunes-note",
"node-js",
"npm",
"spotify",
"usb",
"windows",
];
function run() {
return {
icons,
otherIcons
}
otherIcons,
};
}
module.exports = run()
module.exports = run();

View file

@ -1,69 +1,48 @@
const colors = require('colors')
const npmUpdater = require('./utils/updater/npm')
const fileUpdater = require('./utils/updater/files')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const Keyv = require('keyv')
const path = require('path')
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const Keyv = require("keyv");
const path = require("path");
const { readFileSync } = require("fs");
module.exports = (themeConfig = {}) => {
return {
themeCodename: 'softui',
viewsPath: path.join(__dirname, '/views'),
staticPath: path.join(__dirname, '/views/src'),
themeCodename: "softui",
viewsPath: path.join(__dirname, "/views"),
staticPath: path.join(__dirname, "/views/src"),
themeConfig: {
...themeConfig,
defaultLocales: require('./locales.js')
defaultLocales: require("./locales.js"),
},
messages: {
error: {
addonLicense: `${consolePrefix}${'Failed to initialise {{ADDON}}.\nThe license this addon was installed with does not match your current discord-dashboard license.'
.cyan
}`
addonLicense: `${consolePrefix}${"Failed to initialise {{ADDON}}.\nThe license this addon was installed with does not match your current discord-dashboard license.".cyan}`,
},
success: {
addonLoaded: `${consolePrefix}${'Successfully loaded {{ADDON}}.'.cyan
}`
}
addonLoaded: `${consolePrefix}${"Successfully loaded {{ADDON}}.".cyan}`,
},
embedBuilderComponent: require('fs').readFileSync(
path.join(__dirname, '/embedBuilderComponent.txt'),
'utf8'
),
},
embedBuilderComponent: readFileSync(path.join(__dirname, "/embedBuilderComponent.txt"), "utf8"),
init: async (app, config) => {
if(!config?.useTheme404) return console.log(`${consolePrefix}${'You need to set useTheme404 to true in your DBD config otherwise Soft-UI will not work correctly!\n\nDashboard has not fully initialised due to this. Pages will 404!'.red}`);
if (!config?.useTheme404) return console.log(`${consolePrefix}${"You need to set useTheme404 to true in your DBD config otherwise Soft-UI will not work correctly!\n\nDashboard has not fully initialised due to this. Pages will 404!".red}`);
let outdated = false
; (async () => {
let check = await npmUpdater.update()
await fileUpdater.update()
if (!check) outdated = true
})()
const db = new Keyv(themeConfig.dbdriver || "sqlite://" + path.join(__dirname, "/database.sqlite"));
const db = new Keyv(
themeConfig.dbdriver ||
'sqlite://' + path.join(__dirname, '/database.sqlite')
)
db.on("error", (err) => {
console.log("Connection Error", err);
process.exit();
});
db.on('error', (err) => {
console.log('Connection Error', err)
process.exit()
})
themeConfig = { ...themeConfig, defaultLocales: require("./locales.js") };
themeConfig = {
...themeConfig,
defaultLocales: require('./locales.js')
}
require('./utils/functions/errorHandler')(config, themeConfig, db)
require('./utils/functions/settingsPage')(config, themeConfig, db)
require("./utils/functions/errorHandler")(config, themeConfig, db);
require("./utils/functions/settingsPage")(config, themeConfig, db);
// await require('./utils/addonManager').execute(themeConfig, config, app, module.exports.messages);
require('./utils/initPages').init(config, themeConfig, app, db)
}
}
}
require("./utils/initPages").init(config, themeConfig, app, db);
},
};
};
module.exports.partials = __dirname + '/views/partials'
module.exports.formTypes = require('./utils/formtypes')
module.exports.Feed = require('./utils/feedHandler')
module.exports.cmdHandler = require('./utils/cmdHandler')
module.exports.version = require('./package.json').version
module.exports.partials = __dirname + "/views/partials";
module.exports.formTypes = require("./utils/formtypes");
module.exports.Feed = require("./utils/feedHandler");
module.exports.cmdHandler = require("./utils/cmdHandler");
module.exports.version = require("./package.json").version;

View file

@ -1,95 +1,94 @@
module.exports = {
enUS: {
name: 'English',
name: "English",
index: {
feeds: ['Current Users', 'CPU', 'System Platform', 'Server Count'],
feeds: ["Current Users", "CPU", "System Platform", "Server Count"],
card: {
category: 'Soft UI',
title: 'Assistants - The center of everything',
description:
"Assistants Discord Bot management panel. Assistants Bot was created to give others the ability to do what they want. Just.<br>That's an example text.<br><br><b><i>Feel free to use HTML</i></b>",
footer: 'Learn More',
image: '/img/soft-ui.webp',
linkText: 'Learn more'
category: "Soft UI",
title: "Assistants - The center of everything",
description: "Assistants Discord Bot management panel. Assistants Bot was created to give others the ability to do what they want. Just.<br>That's an example text.<br><br><b><i>Feel free to use HTML</i></b>",
footer: "Learn More",
image: "/img/soft-ui.webp",
linkText: "Learn more",
},
feedsTitle: 'Feeds',
graphTitle: 'Graphs'
feedsTitle: "Feeds",
graphTitle: "Graphs",
},
manage: {
settings: {
memberCount: 'Members',
memberCount: "Members",
info: {
info: 'Info',
server: 'Server Information'
}
}
info: "Info",
server: "Server Information",
},
},
},
privacyPolicy: {
title: 'Privacy Policy',
description: 'Privacy Policy and Terms of Service'
title: "Privacy Policy",
description: "Privacy Policy and Terms of Service",
},
partials: {
sidebar: {
dash: 'Dashboard',
manage: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin',
account: 'Account Pages',
login: 'Sign In',
logout: 'Sign Out'
dash: "Dashboard",
manage: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin",
account: "Account Pages",
login: "Sign In",
logout: "Sign Out",
},
navbar: {
home: 'Home',
home: "Home",
pages: {
manage: 'Manage Guilds',
settings: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin Panel',
error: 'Error',
credits: 'Credits',
debug: 'Debug',
leaderboard: 'Leaderboard',
profile: 'Profile',
maintenance: 'Under Maintenance'
}
manage: "Manage Guilds",
settings: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin Panel",
error: "Error",
credits: "Credits",
debug: "Debug",
leaderboard: "Leaderboard",
profile: "Profile",
maintenance: "Under Maintenance",
},
},
title: {
pages: {
manage: 'Manage Guilds',
settings: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin Panel',
error: 'Error',
credits: 'Credits',
debug: 'Debug',
leaderboard: 'Leaderboard',
profile: 'Profile',
maintenance: 'Under Maintenance'
}
manage: "Manage Guilds",
settings: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin Panel",
error: "Error",
credits: "Credits",
debug: "Debug",
leaderboard: "Leaderboard",
profile: "Profile",
maintenance: "Under Maintenance",
},
},
preloader: {
text: 'Page is loading...'
text: "Page is loading...",
},
premium: {
title: 'Want more from Assistants?',
description: 'Check out premium features below!',
buttonText: 'Become Premium'
title: "Want more from Assistants?",
description: "Check out premium features below!",
buttonText: "Become Premium",
},
settings: {
title: 'Site Configuration',
description: 'Configurable Viewing Options',
title: "Site Configuration",
description: "Configurable Viewing Options",
theme: {
title: 'Site Theme',
description: 'Make the site more appealing for your eyes!'
title: "Site Theme",
description: "Make the site more appealing for your eyes!",
},
language: {
title: 'Site Language',
description: 'Select your preferred language!'
}
}
}
}
}
title: "Site Language",
description: "Select your preferred language!",
},
},
},
},
};

View file

@ -1,18 +1,8 @@
{
"name": "dbd-soft-ui",
"version": "1.6.48-beta.1",
"description": "dashboard theme",
"version": "1.0",
"typings": "dbd-soft-ui.d.ts",
"author": {
"name": "iMidnight"
},
"contributors": [
"PlainDevelopment",
"Breftejk"
],
"bugs": {
"url": "https://github.com/Assistants-Center/dbd-soft-ui/issues"
},
"bundleDependencies": [],
"dependencies": {
"@keyv/sqlite": "^3.6.1",
"colors": "1.4.0",
@ -21,29 +11,100 @@
"nodeactyl": "^3.2.2",
"quick.db": "^7.1.3"
},
"deprecated": false,
"description": "Soft UI DBD Theme: An awesome - feature packed theme to use with discord-dashboard!",
"homepage": "https://softui.assistantscenter.com/",
"keywords": [
"discord",
"discord.js",
"discordjs",
"discord dashboard",
"discord web dashboard",
"web dashboard",
"dashboard"
],
"license": "MIT",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/Assistants-Center/DBD-Soft-UI.git"
},
"scripts": {
"test": "echo \"Error: no test specified\""
},
"devDependencies": {
"express": "^4.18.2",
"eslint": "^8.23.0",
"prettier": "2.7.1"
},
"eslintConfig": {
"env": {
"commonjs": true,
"es6": true,
"es2020": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {
"arrow-spacing": [
"warn",
{
"before": true,
"after": true
}
],
"comma-dangle": [
"error",
"always-multiline"
],
"comma-spacing": "error",
"comma-style": "error",
"dot-location": [
"error",
"property"
],
"handle-callback-err": "off",
"indent": [
"error",
"tab",
{
"SwitchCase": 1
}
],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
{
"max": 4
}
],
"max-statements-per-line": [
"error",
{
"max": 2
}
],
"no-console": "off",
"no-multi-spaces": "error",
"no-multiple-empty-lines": [
"error",
{
"max": 2,
"maxEOF": 1,
"maxBOF": 0
}
],
"no-trailing-spaces": [
"error"
],
"no-var": "error",
"object-curly-spacing": [
"error",
"always"
],
"prefer-const": "error",
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"yoda": "error"
}
}
}

View file

@ -1,27 +1,24 @@
const npmUpdater = require('../../utils/updater/npm')
const fileUpdater = require('../../utils/updater/files')
module.exports = {
page: '/control',
page: "/control",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const { uuid, action } = req.query;
const { uuid, action } = req.query
if (!uuid && action && req.query.type) {
if (req.query.type === 'npm') await npmUpdater.update()
if (req.query.type === 'live') await fileUpdater.update()
return res.redirect('/admin?result=true')
return res.redirect("/admin?result=true");
}
if (!uuid || !action) return res.sendStatus(412)
if (!uuid || !action) return res.sendStatus(412);
try {
if (action === 'start') await themeConfig.nodeactyl.startServer(uuid)
if (action === 'restart') await themeConfig.nodeactyl.restartServer(uuid)
if (action === 'stop') await themeConfig.nodeactyl.stopServer(uuid)
if (action === 'kill') await themeConfig.nodeactyl.killServer(uuid)
if (action === "start") await themeConfig.nodeactyl.startServer(uuid);
if (action === "restart") await themeConfig.nodeactyl.restartServer(uuid);
if (action === "stop") await themeConfig.nodeactyl.stopServer(uuid);
if (action === "kill") await themeConfig.nodeactyl.killServer(uuid);
} catch (error) {
console.error(error)
return res.redirect('/admin?result=false')
console.error(error);
return res.redirect("/admin?result=false");
}
return res.redirect('/admin?result=true')
return res.redirect("/admin?result=true");
}
}
};

View file

@ -1,193 +1,197 @@
const db = require('quick.db')
const { icons, otherIcons } = require('../../icons')
const db = require("quick.db");
const { icons, otherIcons } = require("../../icons");
module.exports = {
page: '/feed',
page: "/feed",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
if (req.query.action === 'delete') {
const deleteFeed = req.query.feed
if (!deleteFeed) return res.redirect('/admin?error=invalidFeed')
if (!/^\d+$/.test(deleteFeed))
return res.redirect('/admin?error=invalidFeed')
if (deleteFeed !== '1' && deleteFeed !== '2' && deleteFeed !== '3')
return res.redirect('/admin?error=invalidFeed')
if (deleteFeed === '1') {
if (!db.get('feeds.one'))
return res.redirect('/admin?error=invalidFeed')
if (db.get('feeds.two')) {
const f = await db.get('feeds.two')
await db.set('feeds.one', {
if (req.query.action === "delete") {
const deleteFeed = req.query.feed;
if (!deleteFeed) return res.redirect("/admin?error=invalidFeed");
if (!/^\d+$/.test(deleteFeed)) return res.redirect("/admin?error=invalidFeed");
if (deleteFeed !== "1" && deleteFeed !== "2" && deleteFeed !== "3") return res.redirect("/admin?error=invalidFeed");
if (deleteFeed === "1") {
if (!db.get("feeds.one")) return res.redirect("/admin?error=invalidFeed");
if (db.get("feeds.two")) {
const f = await db.get("feeds.two");
await db.set("feeds.one", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
diff: f.diff,
});
} else await db.delete("feeds.one");
if (db.get("feeds.three")) {
const f = await db.get("feeds.three");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
await db.delete("feeds.three");
}
} else if (deleteFeed === "2") {
if (!db.get("feeds.two")) return res.redirect("/admin?error=invalidFeed");
if (db.get("feeds.one")) {
const f = await db.get("feeds.one");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
await db.delete("feeds.one");
} else {
await db.delete('feeds.one')
await db.delete("feeds.two");
}
if (db.get('feeds.three')) {
const f = await db.get('feeds.three')
await db.set('feeds.two', {
} else if (deleteFeed === "3") {
if (!db.get("feeds.three")) return res.redirect("/admin?error=invalidFeed");
await db.delete("feeds.three");
if (db.get("feeds.two")) {
const f = await db.get("feeds.two");
await db.set("feeds.three", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
await db.delete('feeds.three')
diff: f.diff,
});
}
} else if (deleteFeed === '2') {
if (!db.get('feeds.two'))
return res.redirect('/admin?error=invalidFeed')
if (db.get('feeds.one')) {
const f = await db.get('feeds.one')
await db.set('feeds.two', {
if (db.get("feeds.one")) {
const f = await db.get("feeds.one");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
await db.delete('feeds.one')
} else {
await db.delete('feeds.two')
}
} else if (deleteFeed === '3') {
if (!db.get('feeds.three'))
return res.redirect('/admin?error=invalidFeed')
await db.delete('feeds.three')
if (db.get('feeds.two')) {
const f = await db.get('feeds.two')
await db.set('feeds.three', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
}
if (db.get('feeds.one')) {
const f = await db.get('feeds.one')
await db.set('feeds.two', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
diff: f.diff,
});
}
}
return res.redirect('/admin')
} else if (req.query.action === 'create') {
const { color, description, icon } = req.query
if (!color || !description || !icon)
return res.redirect('/admin?error=missingData')
if (
color !== 'red' &&
color !== 'orange' &&
color !== 'pink' &&
color !== 'gray' &&
color !== 'green' &&
color !== 'blue' &&
color !== 'dark'
)
return res.redirect('/admin?error=invalidData')
if (description.length < 3 || description.length > 128)
return res.redirect('/admin?error=invalidData')
if (!icons.includes(icon) && !otherIcons.includes(icon))
return res.redirect('/admin?error=invalidData')
let diff
let col
if (otherIcons.includes(icon)) diff = true
if (color === 'red') col = 'danger'
if (color === 'orange') col = 'warning'
if (color === 'pink') col = 'primary'
if (color === 'gray') col = 'secondary'
if (color === 'green') col = 'success'
if (color === 'blue') col = 'info'
if (color === 'dark') col = 'dark'
if (
db.get('feeds.three') &&
db.get('feeds.two') &&
db.get('feeds.one')
) {
await db.delete('feeds.one')
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.two', {
return res.redirect("/admin");
} else if (req.query.action === "create") {
const { color, description, icon } = req.query;
if (!color || !description || !icon) return res.redirect("/admin?error=missingData");
if (color !== "red" && color !== "orange" && color !== "pink" && color !== "gray" && color !== "green" && color !== "blue" && color !== "dark") return res.redirect("/admin?error=invalidData");
if (description.length < 3 || description.length > 128) return res.redirect("/admin?error=invalidData");
if (!icons.includes(icon) && !otherIcons.includes(icon)) return res.redirect("/admin?error=invalidData");
let diff;
let col;
if (otherIcons.includes(icon)) diff = true;
if (color === "red") col = "danger";
if (color === "orange") col = "warning";
if (color === "pink") col = "primary";
if (color === "gray") col = "secondary";
if (color === "green") col = "success";
if (color === "blue") col = "info";
if (color === "dark") col = "dark";
if (db.get("feeds.three") && db.get("feeds.two") && db.get("feeds.one")) {
await db.delete("feeds.one");
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.one', {
diff: f3.diff,
});
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.three', {
diff: f2.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
} else {
if (!db.get('feeds.three'))
await db.set('feeds.three', {
if (!db.get("feeds.three")) {
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
else if (!db.get('feeds.two')) {
const f3 = db.get('feeds.three')
await db.set('feeds.two', {
diff: diff,
});
} else if (!db.get("feeds.two")) {
const f3 = db.get("feeds.three");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
} else {
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.one', {
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.two', {
diff: f2.diff,
});
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
}
}
return res.redirect('/admin')
return res.redirect("/admin");
}
}
}
},
};

View file

@ -1,48 +1,45 @@
const db = require('quick.db')
const db = require("quick.db");
module.exports = {
page: '/admin',
page: "/admin",
execute: async (req, res, app, config, themeConfig, info, database) => {
if (!req.session.user) return res.redirect('/discord?r=/admin/')
if (!config.ownerIDs?.includes(req.session.user.id))
return res.redirect('/')
if (!themeConfig.nodeactyl && themeConfig.admin?.pterodactyl?.enabled)
return res.send(
'Unable to contact Pterodactyl, are your details correct?'
)
if (!req.session.user) return res.redirect("/discord?r=/admin/");
if (!config.ownerIDs?.includes(req.session.user.id)) return res.redirect("/");
if (!themeConfig.nodeactyl && themeConfig.admin?.pterodactyl?.enabled) return res.send("Unable to contact Pterodactyl, are your details correct?");
async function getServers() {
if (!themeConfig?.admin?.pterodactyl?.enabled) return []
const serverData = []
for (const uuid of themeConfig?.admin?.pterodactyl?.serverUUIDs) {
let dataStatus = await themeConfig?.nodeactyl?.getServerStatus(uuid)
let data = await themeConfig?.nodeactyl?.getServerDetails(uuid)
if (!themeConfig?.admin?.pterodactyl?.enabled) return [];
const serverData = [];
const serverUUIDS = themeConfig?.admin?.pterodactyl?.serverUUIDs;
for (const uuid of serverUUIDS) {
const dataStatus = await themeConfig?.nodeactyl?.getServerStatus(uuid);
const data = await themeConfig?.nodeactyl?.getServerDetails(uuid);
serverData.push({
name: data.name.toString(),
uuid: data.uuid.toString(),
desc: data.description.toString(),
node: data.node.toString(),
status: dataStatus.toString()
})
}
return serverData
status: dataStatus.toString(),
});
}
let allFeedsUsed = false
if (db.get('feeds.one') && db.get('feeds.two') && db.get('feeds.three'))
allFeedsUsed = true
const d = await getServers()
res.render('admin', {
return serverData;
}
const d = await getServers();
res.render("admin", {
req,
sData: d,
ldata: await database.get('logs'),
ldata: await database.get("logs"),
themeConfig: req.themeConfig,
node: themeConfig.nodeactyl,
bot: config.bot,
allFeedsUsed,
allFeedsUsed: (db.get("feeds.one") && db.get("feeds.two") && db.get("feeds.three")) ? true : false,
config,
require
})
}
}
require,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/blacklisted',
page: "/blacklisted",
execute: async (req, res, app, config, themeConfig, info) => {
res.render('blacklisted', {
res.render("blacklisted", {
req,
config,
themeConfig,
info
})
}
}
info,
});
},
};

View file

@ -1,12 +1,12 @@
module.exports = {
page: '/commands',
page: "/commands",
execute: async (req, res, app, config, themeConfig, info) => {
if (themeConfig.commands)
res.render('commands.ejs', {
res.render("commands", {
req,
config,
themeConfig,
info
})
}
}
info,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/credits',
page: "/credits",
execute: async (req, res, app, config, themeConfig, info) => {
res.render('credits', {
res.render("credits", {
req: req,
config,
themeConfig,
info
})
}
}
info,
});
},
};

View file

@ -1,70 +1,45 @@
const fetch = require('node-fetch')
const fs = require('fs')
let DBD = require('discord-dashboard')
const fetch = require("node-fetch");
const fs = require("fs");
const DBD = require("../../../../index");
module.exports = {
page: '/debug',
page: "/debug",
execute: async (req, res, app, config, themeConfig, info) => {
/*
Do not remove this page.
It will be used with support in the discord server.
*/
if (!req.session.user) return res.redirect('/discord?r=/debug/')
if (!config.ownerIDs?.includes(req.session.user.id))
return res.redirect('/')
if (!req.session.user) return res.redirect("/discord?r=/debug/");
if (!config.ownerIDs?.includes(req.session.user.id)) return res.redirect("/");
let onlineFiles = {
index: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/index.ejs`
),
guild: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guild.ejs`
),
guilds: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guilds.ejs`
)
}
const onlineFiles = {
index: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/index.ejs"),
guild: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guild.ejs"),
guilds: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guilds.ejs"),
};
onlineFiles.index = await onlineFiles.index.text()
onlineFiles.guild = await onlineFiles.guild.text()
onlineFiles.guilds = await onlineFiles.guilds.text()
let localFiles = {
index: await fs.readFileSync(
`${__dirname}/../..//views/index.ejs`,
'utf-8'
),
guild: await fs.readFileSync(
`${__dirname}/../../views/settings.ejs`,
'utf-8'
),
guilds: await fs.readFileSync(
`${__dirname}/../../views/guilds.ejs`,
'utf-8'
)
}
onlineFiles.index = await onlineFiles.index.text();
onlineFiles.guild = await onlineFiles.guild.text();
onlineFiles.guilds = await onlineFiles.guilds.text();
let onlineV = await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`
)
const localV = require(`${__dirname}/../../utils/updater/versions.json`)
onlineV = await onlineV.json()
const localFiles = {
index: await fs.readFileSync(`${__dirname}/../../views/index.ejs`, "utf-8"),
guild: await fs.readFileSync(`${__dirname}/../../views/settings.ejs`, "utf-8"),
guilds: await fs.readFileSync(`${__dirname}/../../views/guilds.ejs`, "utf-8"),
};
res.render('debug', {
license: require(`discord-dashboard`).licenseInfo().type, // replace with discord-dashboard
onlineV,
localV,
res.render("debug", {
onlineFiles,
localFiles,
rawUptime: process.uptime(),
nodeVersion: process.version,
themeConfig,
discordVersion: require('discord.js').version,
discordVersion: require("discord.js").version,
dbdVersion: DBD.version,
themeVersion: require(`dbd-soft-ui`).version,
themePartials: require(`${__dirname}/../../utils/updater/versions.json`),
themeVersion: require("dbd-soft-ui").version,
req,
config,
info
})
}
}
info,
});
},
};

View file

@ -1,8 +1,8 @@
module.exports = {
page: '/shards/get',
page: "/shards/get",
execute: async (req, res, app, config, themeConfig, info, db) => {
let returned = await db.get('stats')
const returned = await db.get("stats");
res.json(returned)
}
}
res.json(returned);
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/privacy-policy',
page: "/privacy-policy",
execute: async (req, res, app, config, themeConfig, info) => {
res.render('pp', {
res.render("pp", {
req,
config,
themeConfig,
info
})
}
}
info,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/settings/:id/:category',
page: "/settings/:id/:category",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const categoryExists = config.settings?.find(
(s) => s.categoryId === req.params.category
)
if (!categoryExists) return config.errorPage(req, res, null, 404)
const categoryExists = config.settings?.find(s => s.categoryId === req.params.category);
await config.guildSettings(req, res, false, req.params.category)
}
}
if (!categoryExists) return config.errorPage(req, res, null, 404);
await config.guildSettings(req, res, false, req.params.category);
},
};

View file

@ -1,6 +1,7 @@
module.exports = {
page: '/settings/:id/',
page: "/settings/:id/",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
await config.guildSettings(req, res, true)
}
}
await config.guildSettings(req, res, true);
},
};

View file

@ -1,11 +1,12 @@
module.exports = {
page: '/shards',
page: "/shards",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info, db) => {
res.render('shards', {
res.render("shards", {
req: req,
config,
themeConfig,
info
})
}
}
info,
});
},
};

View file

@ -1,49 +1,45 @@
module.exports = {
page: '/guild/update/:guildId/',
page: "/guild/update/:guildId/",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const data = req.body
const data = req.body;
let setNewRes
let errors = []
let successes = []
let setNewRes;
const errors = [];
const successes = [];
if (!req.session?.user)
return res.send({
if (!req.session?.user) return res.send({
success: false,
message: 'User is not logged in'
})
message: "User is not logged in",
});
const userGuildMemberObject = config.bot.guilds.cache
.get(req.params.guildId)
.members.cache.get(req.session.user.id)
const guildObject = config.bot.guilds.cache.get(req.params.guildId)
const userGuildMemberObject = config.bot.guilds.cache.get(req.params.guildId).members.cache.get(req.session.user.id);
const guildObject = config.bot.guilds.cache.get(req.params.guildId);
let category = config.settings?.find((c) => c.categoryId == req.query.categoryId)
let catO = [];
let catToggle = [];
const category = config.settings?.find(c => c.categoryId == req.query.categoryId);
const catO = [];
const catToggle = [];
if (data.categoryToggle) {
for (const s of data.categoryToggle) {
if (!config.useCategorySet) try {
let category = config.settings?.find(
(c) => c?.categoryId == s.id
)
const category = config.settings?.find(c => c?.categoryId == s.id);
await category.setNew({
guild: { id: req.params.guildId },
newData: s.value
})
newData: s.value,
});
} catch (err) {
errors.push(`Category ${s.id} %is%Failed to save%is%categoryToggle`);
}
else {
if (category?.categoryId == s.id) catO.push({
optionId: category.categoryId == s.id ? "categoryToggle" : s.id,
data: s.value
data: s.value,
});
else catToggle.push({
optionId: s.id,
data: s.value
data: s.value,
});
}
}
@ -53,360 +49,275 @@ module.exports = {
message: "Saved toggle",
errors: [],
successes: [],
})
});
}
}
if (!category)
return res.send({
if (!category) return res.send({
error: true,
message: "No category found",
})
});
const subOptions = category.categoryOptionsList.filter((o) => o.optionType.type == "multiRow")
.map((o) => o.optionType.options)
.flat()
const subOptions = category.categoryOptionsList.filter(o => o.optionType.type == "multiRow").map(o => o.optionType.options).flat();
const newOptionsList = [
...category.categoryOptionsList.filter((o) => o.optionType.type != "multiRow"),
...subOptions
]
...subOptions,
];
if (data.options) for (let option of newOptionsList) {
let d = data.options.find((o) => o.id === option.optionId);
let canUse = {}
if (data.options)
for (const option of newOptionsList) {
const d = data.options.find(o => o.id === option.optionId);
let canUse = {};
if (!d && !d?.id) continue;
if (option.allowedCheck) canUse = await option.allowedCheck({
guild: { id: req.params.guildId },
user: { id: req.session.user.id },
})
else canUse = { allowed: true, errorMessage: null }
});
else canUse = {
allowed: true,
errorMessage: null,
};
if (canUse.allowed == false) {
setNewRes = { error: canUse.errorMessage }
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
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" || option.optionType.type == 'tagInput') {
if (option.optionType.type == "rolesMultiSelect" || option.optionType.type == "channelsMultiSelect" || option.optionType.type == "multiSelect" || option.optionType.type == "tagInput") {
if (!d.value || d.value == null || d.value == undefined) catO.push({
optionId: option.optionId,
data: [],
})
});
else if (typeof d.value != "object") catO.push({
optionId: option.optionId,
data: [d.value],
})
});
else catO.push({
optionId: option.optionId,
data: d.value,
})
});
} else if (option.optionType.type == "switch") {
if (
d.value ||
d.value == null ||
d.value == undefined ||
d.value == false
) {
if (d.value || d.value == null || d.value == undefined || d.value == false) {
if (d.value || d.value == null || d.value == undefined || d.value == false) {
if (d.value == null || d.value == undefined || d.value == false)
catO.push({
optionId: option.optionId,
data: false
data: false,
});
else
catO.push({
optionId: option.optionId,
data: true
data: true,
});
}
}
} else if (option.optionType.type == "embedBuilder") {
if (
d.value == null ||
d.value == undefined
)
if (d.value == null || d.value == undefined)
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
});
else {
try {
const parsedResponse = JSON.parse(
d.value
)
const parsedResponse = JSON.parse(d.value);
catO.push({
optionId: option.optionId,
data: parsedResponse,
})
});
} catch (err) {
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
});
}
}
} else {
if (
d.value == undefined ||
d.value == null
)
if (d.value == undefined || d.value == null)
catO.push({
optionId: option.optionId,
data: null,
})
});
else
catO.push({
optionId: option.optionId,
data: d.value,
})
});
}
} else {
if (
option.optionType.type ==
'rolesMultiSelect' ||
option.optionType.type ==
'channelsMultiSelect' ||
option.optionType.type == 'multiSelect' ||
option.optionType.type == 'tagInput'
) {
if (
!d.value ||
d.value == null ||
d.value == undefined
) {
if (option.optionType.type == "rolesMultiSelect" || option.optionType.type == "channelsMultiSelect" || option.optionType.type == "multiSelect" || option.optionType.type == "tagInput") {
if (!d.value || d.value == null || d.value == undefined) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
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 d.value != 'object'
) {
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 d.value != "object") {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData: [d.value]
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
newData: [d.value],
});
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
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData: d.value
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
newData: d.value,
});
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 (
d.value !== null ||
d.value !== undefined
) {
setNewRes =
(await option.setNew({
} else if (option.optionType.type == "embedBuilder") {
if (d.value !== null || d.value !== undefined) {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData: JSON.parse(
d.value
)
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
d.value,
),
})) || {};
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(
d.value
)
setNewRes =
(await option.setNew({
const parsedResponse = JSON.parse(d.value);
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
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
)
}
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({
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData:
option.optionType.data
})) || {}
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
)
}
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 (
d.value == undefined ||
d.value == null
) {
setNewRes =
(await option.setNew({
if (d.value == undefined || d.value == null) {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData: null
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
newData: null,
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} else {
successes.push(option.optionName)
}
} else {
setNewRes =
(await option.setNew({
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
object: userGuildMemberObject,
},
newData: d.value
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
newData: d.value,
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
}
}
}
@ -424,17 +335,19 @@ module.exports = {
object: userGuildMemberObject,
},
data: catO,
})
sNR ? null : (sNR = {})
if (sNR.error) {
errors.push(category.categoryId + "%is%" + sNR.error)
} else {
successes.push(category.categoryId)
}
});
sNR ? null : (sNR = {});
if (sNR.error)
errors.push(category.categoryId + "%is%" + sNR.error);
else
successes.push(category.categoryId);
}
if (config.useCategorySet && catToggle.length) for (const opt of catToggle) {
let cat = config.settings?.find((c) => c.categoryId == opt.optionId);
if (config.useCategorySet && catToggle.length)
for (const opt of catToggle) {
const cat = config.settings?.find(c => c.categoryId == opt.optionId);
if (!cat) {
errors.push(`Category ${opt.optionId} %is%Doesn't exist%is%categoryToggle`);
@ -453,7 +366,7 @@ module.exports = {
},
data: [{
optionId: "categoryToggle",
data: opt.data
data: opt.data,
}],
});
} catch (err) {
@ -461,16 +374,19 @@ module.exports = {
}
}
req.DBDEvents.emit('guildSettingsUpdated', {
req.DBDEvents.emit("guildSettingsUpdated", {
user: req.session.user,
changes: { successes, errors }
})
changes: {
successes,
errors,
},
});
res.send({
success: true,
message: 'saved changed',
message: "saved changed",
errors,
successes
})
}
}
successes,
});
},
};

View file

@ -1,23 +1,21 @@
module.exports = {
page: '/stats/logs/update',
page: "/stats/logs/update",
execute: async (req, res, app, config, themeConfig, info, db) => {
if (
'Bearer ' + themeConfig.admin?.logs?.key !==
req.headers.authorization
)
return res.json({ status: 'Invalid sharding key' })
if ("Bearer " + themeConfig.admin?.logs?.key !== req.headers.authorization) return res.json({ status: "Invalid sharding key" });
const logs = await db.get('logs')
const logs = await db.get("logs");
let newLogs = []
let newLogs = [];
if (!logs || !logs.length || !logs[0])
newLogs = [req.body]
newLogs = [req.body];
else
newLogs = [req.body, ...logs]
newLogs = [req.body, ...logs];
await db.set('logs', newLogs)
await db.set("logs", newLogs);
res.json({ status: 'Completed' })
}
}
res.json({
status: "Completed",
});
},
};

View file

@ -1,36 +1,34 @@
module.exports = {
page: '/stats/shards/update',
page: "/stats/shards/update",
execute: async (req, res, app, config, themeConfig, info, db) => {
if (
'Bearer ' + themeConfig.shardspage?.key !==
req.headers.authorization
)
return res.json({ status: 'Invalid sharding key' })
if ("Bearer " + themeConfig.shardspage?.key !== req.headers.authorization) return res.json({ status: "Invalid sharding key" });
const stats = await db.get('stats')
const stats = await db.get("stats");
const clean = req.body.map((s) => {
if (!stats) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping]
}
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
};
const currentSaved = stats?.find((x) => x.id === s.id)
const currentSaved = stats?.find((x) => x.id === s.id);
if (!currentSaved) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping]
}
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
};
const nextPing = currentSaved?.ping?.slice(1, 10)
const nextPing = currentSaved?.ping?.slice(1, 10);
return {
...s,
ping: nextPing ? [...nextPing, s.ping] : [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
}
})
};
});
await db.set('stats', clean)
await db.set("stats", clean);
res.json({ status: 'Completed' })
}
}
res.json({
status: "Completed",
});
},
};

View file

@ -1,52 +1,42 @@
module.exports = (commands, prefix) => {
if (!commands)
throw new Error('No commands were provided to the Soft UI cmdHandler.')
if (!prefix) prefix = '!'
if (!commands) throw new Error("No commands were provided to the Soft UI cmdHandler.");
if (!prefix) prefix = "/";
let finalCategories = []
let categories = []
const finalCategories = [];
const categories = [];
commands.map((cmd) => {
if (!categories.includes(cmd.category)) {
categories.push(cmd.category)
}
})
commands.map(cmd => {
if (!categories.includes(cmd.category)) categories.push(cmd.category);
});
for (const category of categories) {
if (
category.toLowerCase().includes('admin') ||
category.toLowerCase().includes('owner') ||
category.toLowerCase().includes('development')
)
continue
let commandsArr = []
if (category.toLowerCase().includes("admin") || category.toLowerCase().includes("owner") || category.toLowerCase().includes("development") || category.toLowerCase().includes("suncountry") || category.toLowerCase().includes("iat")) continue;
const commandsArr = [];
commands
.filter((cmd) => cmd.category === category)
.map((cmd) => {
let obj = {
commands.filter(cmd => cmd.category === category).map(cmd => {
const obj = {
commandName: cmd.name,
commandUsage: `${cmd.usage ? cmd.usage : `${prefix}${cmd.name}`}`,
commandDescription: cmd.description,
commandAlias: cmd.aliases?.join(', ') || 'None'
}
commandsArr.push(obj)
})
commandAlias: cmd.aliases?.join(", ") || "None",
};
commandsArr.push(obj);
});
const categoryObj = {
categoryId: category,
category: `${capitalizeFirstLetter(category)}`,
subTitle: `${capitalizeFirstLetter(category)} commands`,
list: commandsArr
}
list: commandsArr,
};
finalCategories.push(categoryObj)
finalCategories.push(categoryObj);
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
return string.charAt(0).toUpperCase() + string.slice(1);
}
return finalCategories
}
return finalCategories;
};

View file

@ -1,73 +1,70 @@
const db = require('quick.db')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const colors = require('colors')
const { icons, otherIcons } = require('../icons')
const db = require("quick.db");
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const colors = require("colors");
const { icons, otherIcons } = require("../icons");
module.exports = class Feed {
constructor() {
this.setColor = function (color) {
if (!color) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid color.')}`.cyan}`);
if (
color !== 'red' &&
color !== 'orange' &&
color !== 'pink' &&
color !== 'gray' &&
color !== 'green' &&
color !== 'blue' &&
color !== 'dark'
) {
throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid color.')}`.cyan}`);
}
if (!color) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid color.")}`.cyan}`);
if (color !== "red" && color !== "orange" && color !== "pink" && color !== "gray" && color !== "green" && color !== "blue" && color !== "dark") throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid color.")}`.cyan}`);
this.color = color;
return this;
}
};
this.setDescription = function (description) {
if (!description) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid description.')}`.cyan}`);
if (description.length < 3 || description.length > 128) console.log(`${consolePrefix}${'Invalid description'.cyan}`);
if (!description) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid description.")}`.cyan}`);
if (description.length < 3 || description.length > 128) console.log(`${consolePrefix}${"Invalid description".cyan}`);
this.description = description;
return this;
}
};
this.setIcon = function (icon) {
if (!icon) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid icon.')}`.cyan}`);
if (!icons.includes(icon) && !otherIcons.includes(icon)) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid icon.')}`.cyan}`);
if (!icon) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid icon.")}`.cyan}`);
if (!icons.includes(icon) && !otherIcons.includes(icon)) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid icon.")}`.cyan}`);
this.icon = icon;
return this;
}
};
this.getFeed = function (id) {
if (!id) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Invalid id.')}`.cyan}`);
let feedName = '';
if (!id) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Invalid id.")}`.cyan}`);
let feedName = "";
switch (id) {
case 1:
feedName = 'one';
feedName = "one";
break;
case 2:
feedName = 'two';
feedName = "two";
break;
case 3:
feedName = 'three';
feedName = "three";
break;
case "all":
feedName = 'all';
feedName = "all";
break;
default:
throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Invalid id.')}`.cyan}`);
throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Invalid id.")}`.cyan}`);
}
let feed = db.get(`feeds${feedName === "all" ? "" : `.${feedName}`}`)
if (!feed) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Feed not found.')}`.cyan}`);
const feed = db.get(`feeds${feedName === "all" ? "" : `.${feedName}`}`);
if (!feed) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Feed not found.")}`.cyan}`);
this.feed = feed;
return this;
}
};
this.delete = function () {
if (!this.feed)throw new Error(`${consolePrefix}${`Failed to delete feed. ${colors.red('Feed not selected')}`.cyan}`);
if (!this.feed) throw new Error(`${consolePrefix}${`Failed to delete feed. ${colors.red("Feed not selected")}`.cyan}`);
db.delete(`feeds.${this.feed.id}`);
return this;
}
};
this.send = async function () {
const { color, description, icon } = this;
@ -76,90 +73,99 @@ module.exports = class Feed {
let col;
if (otherIcons.includes(icon)) diff = true;
if (color === 'red') col = 'danger';
if (color === 'orange') col = 'warning';
if (color === 'pink') col = 'primary';
if (color === 'gray') col = 'secondary';
if (color === 'green') col = 'success';
if (color === 'blue') col = 'info';
if (color === 'dark') col = 'dark';
if (color === "red") col = "danger";
if (color === "orange") col = "warning";
if (color === "pink") col = "primary";
if (color === "gray") col = "secondary";
if (color === "green") col = "success";
if (color === "blue") col = "info";
if (color === "dark") col = "dark";
if (db.get('feeds.three') && db.get('feeds.two') && db.get('feeds.one')) {
await db.delete('feeds.one')
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.two', {
if (db.get("feeds.three") && db.get("feeds.two") && db.get("feeds.one")) {
await db.delete("feeds.one");
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.one', {
diff: f3.diff,
});
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.three', {
diff: f2.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
} else {
if (!db.get('feeds.three')) {
await db.set('feeds.three', {
if (!db.get("feeds.three")) {
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else if (!db.get('feeds.two')) {
const f3 = db.get('feeds.three')
await db.set('feeds.two', {
diff: diff,
});
} else if (!db.get("feeds.two")) {
const f3 = db.get("feeds.three");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
} else {
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.one', {
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.two', {
diff: f2.diff,
});
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
diff: diff,
});
}
}
};
}
}
}
};

View file

@ -3,7 +3,7 @@ module.exports = {
// Validate Data
if (options && (!options.length || !options[0])) throw new Error("Options in the 'collapsable' form type should be an array.");
const hasType = (object) => object.hasOwnProperty('optionType') && object.optionType?.hasOwnProperty('type');
const hasType = object => Object.prototype.hasOwnProperty.call(object, "optionType") && Object.prototype.hasOwnProperty.call(object.optionType, "type");
if (options && !options.every(hasType)) throw new Error("Invalid form type provided in the 'multiRow' form type.");
@ -11,53 +11,53 @@ module.exports = {
return {
type: "multiRow",
options
}
options,
};
},
spacer: (themeOptions = {}) => {
return {
type: 'spacer',
themeOptions
}
type: "spacer",
themeOptions,
};
},
emojiPicker: (disabled, themeOptions = {}) => {
return {
type: 'emojiPicker',
type: "emojiPicker",
disabled,
themeOptions
}
themeOptions,
};
},
slider: (min, max, step, disabled, themeOptions = {}) => {
return {
type: 'slider',
type: "slider",
min,
max,
step,
disabled,
themeOptions
}
themeOptions,
};
},
date: (disabled, themeOptions = {}) => {
return {
type: 'date',
type: "date",
disabled,
themeOptions
}
themeOptions,
};
},
numberPicker: (min, max, disabled, themeOptions = {}) => {
return {
type: 'numberPicker',
type: "numberPicker",
min,
max,
disabled,
themeOptions
}
themeOptions,
};
},
tagInput: (disabled, themeOptions = {}) => {
return {
type: 'tagInput',
type: "tagInput",
disabled,
themeOptions
}
}
}
themeOptions,
};
},
};

View file

@ -1,23 +1,20 @@
module.exports = function (config, themeConfig) {
config.errorPage = function (req, res, error, type) {
let title, subtitle, description = null;
if (type == 404) {
title = themeConfig?.error?.error404?.title || '404'
subtitle =
themeConfig?.error?.error404?.subtitle || 'Page not found'
description =
themeConfig?.error?.error404?.description ||
'The page you are looking for does not exist.'
title = themeConfig?.error?.error404?.title || "404";
subtitle = themeConfig?.error?.error404?.subtitle || "Page not found";
description = themeConfig?.error?.error404?.description || "The page you are looking for does not exist.";
}
title = themeConfig?.error?.dbdError?.title || type.toString()
subtitle = themeConfig?.error?.dbdError?.subtitle || 'An error occurred'
title = themeConfig?.error?.dbdError?.title || type.toString();
subtitle = themeConfig?.error?.dbdError?.subtitle || "An error occurred";
description =
themeConfig?.error?.dbdError?.description ||
'Please contact us if the issue persists or try again later.'
"Please contact us if the issue persists or try again later.";
if (error) {
console.error(error)
}
if (error) console.error(error);
if (themeConfig?.error?.errorHandler)
themeConfig.error.errorHandler({
@ -26,13 +23,13 @@ module.exports = function (config, themeConfig) {
error: {
type,
path: error?.path || null,
error: error?.stack || `Page ${req.originalUrl} not found!`
error: error?.stack || `Page ${req.originalUrl} not found!`,
},
user: req?.session?.user || null
})
user: req?.session?.user || null,
});
return res.render('error', {
strError: error?.stack?.split('\n'),
return res.render("error", {
strError: error?.stack?.split("\n"),
req,
bot: config.bot,
config,
@ -41,7 +38,7 @@ module.exports = function (config, themeConfig) {
title,
subtitle,
description,
error: error || undefined
})
}
}
error: error || undefined,
});
};
};

View file

@ -1,63 +1,53 @@
const Discord = require('discord.js')
module.exports = function (config, themeConfig) {
config.guildSettings = async function (req, res, home, category) {
if (!req.session.user) return res.redirect('/discord?r=/guild/' + req.params.id)
const { Permissions } = require("discord.js");
let bot = config.bot
module.exports = function (config, themeConfig) {
// eslint-disable-next-line no-unused-vars
config.guildSettings = async function (req, res, home, category) {
if (!req.session.user) return res.redirect("/discord?r=/guild/" + req.params.id);
const bot = config.bot;
if (!bot.guilds.cache.get(req.params.id)) {
try {
await bot.guilds.fetch(req.params.id)
} catch (err) { }
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)
) {
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) { }
await bot.guilds.cache.get(req.params.id).members.fetch(req.session.user.id);
} catch (e) { /* ... */ }
}
for (let PermissionRequired of req.requiredPermissions) {
let converted = PermissionRequired[0]
const DiscordJsVersion = Discord.version.split('.')[0]
if (DiscordJsVersion === '14') converted = await 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')
}
}
// for (const PermissionRequired of req.requiredPermissions) {
// const permissionsReq = Permissions.FLAGS[PermissionRequired[0]];
// if (!bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id).permissions.has(permissionsReq))
// 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) { }
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 (err) { }
await bot.guilds.cache.get(req.params.id).roles.fetch();
} catch (e) { /* ... */ }
}
let actual = {}
let toggle = {}
let premium = {}
const actual = {};
const toggle = {};
const premium = {};
let canUseList = {}
const canUseList = {};
if (config.settings?.length) for (const category of config.settings) {
if (config.settings?.length)
for (const category of config.settings) {
if (!canUseList[category.categoryId]) canUseList[category.categoryId] = {};
if (!actual[category.categoryId]) actual[category.categoryId] = {}
if (!actual[category.categoryId]) actual[category.categoryId] = {};
if (config.useCategorySet) {
let catGAS = await category.getActualSet({
@ -67,243 +57,195 @@ module.exports = function (config, themeConfig) {
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id),
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
if (category.toggleable) {
if (!toggle[category.categoryId]) {
toggle[category.categoryId] = {}
toggle[category.categoryId] = {};
}
toggle[category.categoryId] = catGAS.find(o => o.optionId === "categoryToggle") || null;
catGAS = catGAS.filter((c) => c.optionId !== 'categoryToggle')
catGAS = catGAS.filter(c => c.optionId !== "categoryToggle");
}
if (category.premium) {
if (!premium[category.categoryId]) {
premium[category.categoryId] = {}
}
premium[category.categoryId] = await s.premiumUser({
guild: {
id: req.params.id
},
user: {
id: req.session.user.id,
tag: req.session.user.tag
}
})
}
if (!premium[category.categoryId]) premium[category.categoryId] = {};
if (category.premium && premium[category.categoryId] == false) return res.redirect(
`/settings/${req.params.id}?error=premiumRequired`
)
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."
)
continue;
}
const option = category.categoryOptionsList.find(
(c) => c.optionId == o.optionId
)
if (option) {
if (option.allowedCheck) {
const canUse = await option.allowedCheck({
premium[category.categoryId] = await category.premiumUser({
guild: {
id: req.params.id,
},
user: {
id: req.session.user.id,
tag: req.session.user.tag,
},
})
});
}
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
if (category.premium && premium[category.categoryId] == false)
return res.redirect(`/settings/${req.params.id}?error=premiumRequired`);
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.");
continue;
}
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
] = {
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 actual[category.categoryId][option.optionId] = {
type: 'spacer',
themeOptions: option.themeOptions
}
} else console.log(`WARNING: Option ${o.optionId} in category ${category.categoryId} doesn't exist in your config.`)
if (!actual[category.categoryId]) actual[category.categoryId] = {};
if (!actual[category.categoryId][option.optionId])
actual[category.categoryId][option.optionId] = o.data;
} else actual[category.categoryId][option.optionId] = {
type: "spacer",
themeOptions: option.themeOptions,
};
} else console.log(`WARNING: Option ${o.optionId} in category ${category.categoryId} doesn't exist in your config.`);
}
} else for (const s of config.settings) {
if (!canUseList[s.categoryId]) canUseList[s.categoryId] = {}
} else
for (const s of config.settings) {
if (!canUseList[s.categoryId]) canUseList[s.categoryId] = {};
if (s.toggleable) {
if (!toggle[s.categoryId]) {
toggle[s.categoryId] = {}
}
if (!toggle[s.categoryId]) toggle[s.categoryId] = {};
toggle[s.categoryId] = await s.getActualSet({
guild: {
id: req.params.id
}
})
id: req.params.id,
},
});
}
if (s.premium) {
if (!premium[s.categoryId]) {
premium[s.categoryId] = {}
}
if (!premium[s.categoryId]) premium[s.categoryId] = {};
premium[s.categoryId] = await s.premiumUser({
guild: {
id: req.params.id
id: req.params.id,
},
user: {
id: req.session.user.id,
tag: req.session.user.tag
}
})
tag: req.session.user.tag,
},
});
}
if (category) {
if (s.premium && premium[category] == false) {
return res.redirect(
`/settings/${req.params.id}?error=premiumRequired`
)
}
}
if (category)
if (s.premium && premium[category] == false)
return res.redirect(`/settings/${req.params.id}?error=premiumRequired`);
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
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
}
errorMessage: null,
};
}
if (!actual[s.categoryId]) actual[s.categoryId] = {}
if (!actual[s.categoryId]) actual[s.categoryId] = {};
if (c.optionType.type == 'spacer') {
if (c.optionType.type == "spacer") {
actual[s.categoryId][c.optionId] = {
type: 'spacer',
themeOptions: c.themeOptions
}
} else if (
c.optionType.type == 'collapsable' ||
c.optionType.type == 'modal'
) {
type: "spacer",
themeOptions: c.themeOptions,
};
} else if (c.optionType.type == "collapsable" || c.optionType.type == "modal") {
for (const item of c.optionType.options) {
if (
item.optionType.type == 'channelsMultiSelect' ||
item.optionType.type == 'roleMultiSelect' ||
item.optionType.type == 'tagInput'
) {
actual[s.categoryId][item.optionId] = []
}
if (item.optionType.type == "channelsMultiSelect" || item.optionType.type == "roleMultiSelect" || item.optionType.type == "tagInput")
actual[s.categoryId][item.optionId] = [];
}
} else {
if (!actual[s.categoryId]) {
actual[s.categoryId] = {}
}
if (!actual[s.categoryId]) actual[s.categoryId] = {};
if (!actual[s.categoryId][c.optionId]) {
if (c.optionType.type === "multiRow") {
for (const item of c.optionType.options) {
actual[s.categoryId][item.optionId] = await item.getActualSet(
{
actual[s.categoryId][item.optionId] = await item.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(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)
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
}
continue;
}
)
}
continue
}
actual[s.categoryId][c.optionId] = await c.getActualSet(
{
actual[s.categoryId][c.optionId] = await c.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(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)
}
}
)
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
}
}
}
}
}
let errors
let success
// boo
let errors;
let success;
if (req.session.errors) {
if (String(req.session.errors).includes('%is%')) {
errors = req.session.errors.split('%and%')
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%')
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
req.session.errors = null;
req.session.success = null;
const guild = bot.guilds.cache.get(req.params.id)
let gIcon
const guild = bot.guilds.cache.get(req.params.id);
let gIcon;
if (!guild.iconURL()) gIcon = themeConfig?.icons?.noGuildIcon
else gIcon = guild.iconURL()
if (!guild.iconURL()) gIcon = themeConfig?.icons?.noGuildIcon;
else gIcon = guild.iconURL();
res.render('settings', {
res.render("settings", {
successes: success,
errors: errors,
settings: config.settings,
@ -318,82 +260,7 @@ module.exports = function (config, themeConfig) {
req: req,
guildid: req.params.id,
themeConfig: req.themeConfig,
config
})
}
}
async function convert14(perm) {
var 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
}
config,
});
};
};

View file

@ -1,89 +1,66 @@
const fs = require('fs')
const colors = require('colors')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const Nodeactyl = require('nodeactyl')
const fs = require("fs");
const colors = require("colors");
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const Nodeactyl = require("nodeactyl");
module.exports = {
init: async function (config, themeConfig, app, db) {
let info;
if (themeConfig?.customThemeOptions?.info) info = await themeConfig.customThemeOptions.info({ config: config });
if(themeConfig?.admin?.pterodactyl?.enabled) {
themeConfig.nodeactyl = new Nodeactyl.NodeactylClient(
themeConfig.admin?.pterodactyl?.panelLink,
themeConfig.admin?.pterodactyl?.apiKey
)
if (themeConfig?.admin?.pterodactyl?.enabled) {
themeConfig.nodeactyl = new Nodeactyl.NodeactylClient(themeConfig.admin?.pterodactyl?.panelLink, themeConfig.admin?.pterodactyl?.apiKey);
try {
await themeConfig.nodeactyl.getAccountDetails();
} catch (error) {
console.log(`${consolePrefix}${('Failed to connect to Pterodactyl panel!\nEnsure you\'ve used a CLIENT api key, (found at ' + themeConfig.admin.pterodactyl.panelLink + '/account/api)').red}`);
console.log(`${consolePrefix}${("Failed to connect to Pterodactyl panel!\nEnsure you've used a CLIENT api key, (found at " + themeConfig.admin.pterodactyl.panelLink + "/account/api)").red}`);
}
}
const eventFolders = fs.readdirSync(`${__dirname}/../pages`)
const eventFolders = fs.readdirSync(`${__dirname}/../pages`);
for (const folder of eventFolders) {
const eventFiles = fs
.readdirSync(`${__dirname}/../pages/${folder}`)
.filter((file) => file.endsWith('.js'));
const eventFiles = fs.readdirSync(`${__dirname}/../pages/${folder}`).filter((file) => file.endsWith(".js"));
for (const file of eventFiles) {
const e = require(`${__dirname}/../pages/${folder}/${file}`);
try {
if (folder === 'admin') {
if (folder === "admin") {
await app.get(e.page, async function (req, res) {
if (!req.session.user) return res.sendStatus(401)
if (!req.session.user) return res.sendStatus(401);
if (!config.ownerIDs?.includes(req.session.user.id)) return res.sendStatus(403);
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
} else if (folder === 'post') {
e.execute(req, res, app, config, themeConfig, info, db);
});
} else if (folder === "post") {
await app.post(e.page, function (req, res) {
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
} else if (folder === 'get') {
e.execute(req, res, app, config, themeConfig, info, db);
});
} else if (folder === "get") {
await app.use(e.page, async function (req, res) {
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
e.execute(req, res, app, config, themeConfig, info, db);
});
}
} catch (error) {
console.log(`${consolePrefix}${'Failed to load:'.cyan} ${colors.red(e.page)}`);
console.log(`${consolePrefix}${"Failed to load:".cyan} ${colors.red(e.page)}`);
console.log(`Page handler ${file}: ${error}`);
}
}
}
app.use('*', async function (req, res) {
res.status(404)
config.errorPage(req, res, undefined, 404)
})
app.use("*", async function (req, res) {
res.status(404);
config.errorPage(req, res, undefined, 404);
});
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
res.status(500)
config.errorPage(req, res, err, 500)
})
res.status(500);
config.errorPage(req, res, err, 500);
});
console.log(`${consolePrefix}${'Initialised all pages!'.cyan}`);
}
}
console.log(`${consolePrefix}${"Initialised all pages!".cyan}`);
},
};

View file

@ -1,80 +0,0 @@
const fetch = require('node-fetch')
const fs = require('fs')
const consolePrefix = `\x1b[34m[\x1b[33mdbd-soft-ui\x1b[34m]\x1b[36m `
const colors = require('colors')
async function update() {
let failed3 = 0
let failed4 = 0
try {
await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`);
} catch (error) {
failed3++
console.log(`${consolePrefix}Failed to check live for updates.`)
}
if (failed3 === 0) {
let checkArray = await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`);
try {
checkArray = await checkArray.json()
} catch (error) {
failed4++
console.log(`${consolePrefix}Failed to check live for updates.`)
}
if (failed4 === 0) {
let latestVersions = [];
let currentVersions = fs.readFileSync(__dirname + '/versions.json');
currentVersions = JSON.parse(currentVersions);
let needsUpdating = [];
for (const latestFile of checkArray) {
if (latestFile.version > currentVersions[latestFile.name]) {
needsUpdating.push({
name: latestFile.name,
type: latestFile.type
})
const { name, type } = latestFile
if (type === 'partial') {
let failedFile = 0
let fileRaw = await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/partials/${name}.ejs`);
try {
fileRaw = await fileRaw.text()
} catch (error) {
failedFile++
console.log(
`${consolePrefix}Failed to update ${colors.red(
name
)}.`
)
}
if (failedFile === 0) {
await fs.writeFileSync(
`${__dirname}/../../views/partials/${name}.ejs`,
fileRaw
)
currentVersions[name] = latestFile.version
await fs.writeFileSync(
`${__dirname}/versions.json`,
JSON.stringify(currentVersions)
)
console.log(
`${consolePrefix}Successfully updated ${colors.green(
name
)}`
)
}
}
}
}
}
}
}
exports.update = async () => {
await update()
}

View file

@ -1,3 +0,0 @@
exports.update = () => {
return;
}

View file

@ -1,17 +0,0 @@
{
"colorscheme": "1.0.64",
"feeds": "1.0.62",
"footer": "1.0.1",
"graph": "1.0.2",
"iconsList": "1.0.0",
"meta": "0.0.0",
"navbar": "1.0.11",
"popup": "1.1.5",
"preload": "0.0.0",
"preloader": "1.1.14",
"premium": "1.0.0",
"scripts": "0.0.0",
"secret": "1.0.0",
"sidebar": "0.0.0",
"theme": "1.1.0"
}

View file

@ -1,57 +0,0 @@
[
{
"name": "colorscheme",
"version": "1.0.64",
"type": "partial"
},
{
"name": "footer",
"version": "1.0.1",
"type": "partial"
},
{
"name": "graph",
"version": "1.0.2",
"type": "partial"
},
{
"name": "iconsList",
"version": "1.0.0",
"type": "partial"
},
{
"name": "navbar",
"version": "1.0.11",
"type": "partial"
},
{
"name": "popup",
"version": "1.1.5",
"type": "partial"
},
{
"name": "preloader",
"version": "1.1.14",
"type": "partial"
},
{
"name": "premium",
"version": "1.0.0",
"type": "partial"
},
{
"name": "secret",
"version": "1.0.0",
"type": "partial"
},
{
"name": "theme",
"version": "1.1.0",
"type": "partial"
},
{
"name": "preload",
"version": "0.0.0",
"type": "partial"
}
]

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">

View file

@ -1,42 +1,28 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now: 'commands'}) %>
<%- include("partials/preloader.ejs", {now: "commands"}) %>
<script>
// docuemnt on read
document.addEventListener('DOMContentLoaded', function() {
$('.glow').removeClass('active');
$('.active_all').addClass('active');
// document on read
document.addEventListener("DOMContentLoaded", function() {
$(".glow").removeClass("active");
$(".active_all").addClass("active");
});
$(function () {
$('#all').click(function () {
$('.item').slideDown("slow");
$('.glow').removeClass('active');
$('.active_all').addClass('active');
$("#all").click(function () {
$(".item").slideDown("slow");
$(".glow").removeClass("active");
$(".active_all").addClass("active");
return false;
});
<% themeConfig.commands?.forEach(category => { %>
$('#<%= category.categoryId %>').click(function () {
$('.item').not('.<%= category.categoryId %>').slideUp(300);
$('.<%= category.categoryId %>').slideDown("slow");
$('.glow').removeClass('active');
$('.active_<%= category.categoryId %>').addClass('active');
$("#<%= category.categoryId %>").click(function () {
$(".item").not(".<%= category.categoryId %>").slideUp(300);
$(".<%= category.categoryId %>").slideDown("slow");
$(".glow").removeClass("active");
$(".active_<%= category.categoryId %>").addClass("active");
return false;
});
<% }) %>
@ -46,16 +32,17 @@
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'commands'}) %>
<%- include("partials/preload.ejs") %>
<%- include("partials/sidebar.ejs", {config: config, now:"commands"}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'commands'}) %>
<%- include("partials/navbar.ejs", {now:"commands"}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="row">
<div class="container-fluid">
<% themeConfig.commands?.forEach(category => { %>
<% if (!category.hideSidebarItem) { %>
<section id="<%= category.categoryId %>">
<div class="col-12 item <%= category.categoryId %>" id="divtable">
<div class="card mb-4 command-card">
@ -131,29 +118,30 @@
</div>
</div>
</section>
<% } %>
<% }) %>
</div>
</div>
</main>
<%- include('partials/footer.ejs') %>
<%- include("partials/footer.ejs") %>
<script>
$('#searchBar').on('change keyup paste enter', function () {
var input = $(this).val().toLowerCase();
$("#searchBar").on("change keyup paste enter", function () {
const input = $(this).val().toLowerCase();
const divs = $(".command-card").toArray()
if (!input || input.length <= 0) {
$('.item').show();
$(".item").show();
$(divs).show();
}
$('tr').show()
$('tr:not(:contains(' + input + '))').hide()
$("tr").show()
$("tr:not(:contains(" + input + "))").hide()
for (const item of divs) {
try {
const tbody = item.firstChild.nextElementSibling.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.nextElementSibling
if ($(tbody).children(':visible').length == 0) $(item).hide()
if ($(tbody).children(":visible").length == 0) $(item).hide()
} catch (error) {
console.log(error)
@ -161,7 +149,7 @@
}
});
</script>
<%- include('partials/scripts.ejs', {now: "commands"}) %>
<%- include("partials/scripts.ejs", {now: "commands"}) %>
</body>
</html>

View file

@ -1,4 +1,3 @@
<div class="formTypes">
<% option.optionType.options.forEach(opt => { %>
<div class="formtype-item mt-3">

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">

View file

@ -1,24 +1,9 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../testcdn/a05ee437b7ade39c78f8.css" data-n-p="">
<%- include('partials/preloader.ejs', {now: 'debug'}) %>
<%- include("partials/preloader.ejs", {now: "debug"}) %>
<%
let seconds = Math.round(rawUptime % 60);
@ -39,10 +24,6 @@
let modified = 0;
if (onlineFiles.index.replace(/\s+/g, '') !== localFiles.index.replace(/\s+/g, '')) modified++;
if (onlineFiles.guild.replace(/\s+/g, '') !== localFiles.guild.replace(/\s+/g, '')) modified++;
if (onlineFiles.guilds.replace(/\s+/g, '') !== localFiles.guilds.replace(/\s+/g, '')) modified++;
const info = []
const versions = []
if (modified !== 0) modded = "true"
@ -51,9 +32,8 @@
let information = [
{name: "Theme", value: "Soft UI Theme"},
{name: "Modified", value: `${modded}`},
{name: "License Type", value: `${license}`},
{name: "Uptime", value: `${filterUptime}`},
{name: "Permissions", value: req.requiredPermissions},
// {name: "Permissions", value: req.requiredPermissions},
{name: "Redirect URI", value: `${config.redirectUri?.includes("/discord/callback")}`}
]
@ -64,14 +44,6 @@
{name: "Theme", version: `${themeVersion}`, npm: "soft-ui"},
]
onlineV.forEach(online => {
const current = localV[online.name];
const latest = online.version;
const name = online.name;
versions.push({name: name, current: current, latest: latest})
});
const settings = config.settings
let debug = {information, modules, versions, settings, themeConfig}
@ -81,11 +53,11 @@
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'debug'}) %>
<%- include("partials/preload.ejs") %>
<%- include("partials/sidebar.ejs", {config: config, now:"debug"}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'debug'}) %>
<%- include("partials/navbar.ejs", {now:"debug"}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="modal fade" id="exampleModalSignUp" tabindex="-1" role="dialog"
@ -97,7 +69,7 @@
<div class="card-header pb-0 text-left">
<h4 class="font-weight-bolder text-primary text-gradient">Download Log file.</h4>
<p class="mb-0"
style="text-align: center;">This log contains the dashboard's Theme Config and all options with any personal information redacted.</p>
style="text-align: center;">This log contains the dashboard"s Theme Config and all options with any personal information redacted.</p>
</div>
<div class="card-body pb-3" id="form1">
<form role="form text-left">
@ -114,7 +86,7 @@
//get time
const timeFinal = dateSplit[4];
//split by space and join by -
const timeFinal2 = timeFinal.replace(/[&\/\\#, +()$~%.'":*?<>{}]/g, '-');
const timeFinal2 = timeFinal.replace(/[&\/\\#, +()$~%."":*?<>{}]/g, "-");
%>
<a href="data:<%- data %>"
download="Log_SoftUI_<%- timeFinal2 %>_<%- dateFinal %>.json"
@ -279,30 +251,9 @@
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<% if (license == "opensource") { %>
<div class="alert alert-primary text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
<div class="alert alert-warning text-white font-weight-bold" role="alert">
License type: <span style="text-transform: capitalize;">No License</span>
</div>
<% } else if (license == "personal") { %>
<div class="alert alert-success text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
</div>
<% } else if (license == "production") { %>
<div class="alert alert-info text-white font-weight-bold" role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
</div>
<% } else { %>
<div class="alert alert-warning text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;">Unknown</span>
</div>
<% } %>
</div>
</div>
</div>
@ -317,58 +268,6 @@
<h6 class="mb-2">Partial Information</h6>
</div>
</div>
<div class="table-responsive">
<table class="table align-items-center ">
<tbody>
<% onlineV.forEach(online => { %>
<%
const latest = onlineV[online.version];
const current = localV[online.name];
const newest = online.version;
%>
<tr>
<td class="w-30">
<div class="d-flex px-2 py-1 align-items-center">
<div class="ms-2">
<p class="text-xs font-weight-bold mb-0">Name:</p>
<h6 class="text-sm mb-0"
style="text-transform: capitalize;"><%- online.name %></h6>
</div>
</div>
</td>
<td>
<div class="text-center">
<p class="text-xs font-weight-bold mb-0">Version:</p>
<h6 class="text-sm mb-0"><%- current %></h6>
</div>
</td>
<td>
<div class="text-center">
<p class="text-xs font-weight-bold mb-0">Type:</p>
<h6 class="text-sm mb-0"
style="text-transform: capitalize;"><%- online.type %></h6>
</div>
</td>
<td class="align-middle text-sm">
<div class="col text-center">
<p class="text-xs font-weight-bold mb-0">Latest:</p>
<%
let update = true;
if (newest > current) update = true;
if (newest == current) update = false;
%>
<% if (update) { %>
<span class="badge bg-gradient-danger"><%- online.version %></span>
<% } else { %>
<span class="badge bg-gradient-success"><%- online.version %></span>
<% } %>
</div>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</div>
</div>
</div>
@ -376,11 +275,11 @@
</div>
<div class="row">
</div>
<%- include('partials/footer.ejs') %>
<%- include("partials/footer.ejs") %>
</div>
</main>
</div>
<%- include('partials/scripts.ejs', {now: "debug"}) %>
<%- include("partials/scripts.ejs", {now: "debug"}) %>
</body>
</html>

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">

View file

@ -1,22 +1,6 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.onload = function () {

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<%- include('partials/preloader.ejs', {now:'index', req: req}) %>

View file

@ -1,16 +1,3 @@
<!--
=========================================================
* Soft UI Design System - v1.0.5
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-design-system
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -->
<%
let logged = `<a id="login" onclick="auth()" class="btn btn-sm bg-gradient-primary btn-round mb-0 me-1 mt-2 mt-md-0">Login</a>`;
if (loggedIn) logged = '<a href="/discord/logout" class="btn btn-sm bg-gradient-primary btn-round mb-0 me-1 mt-2 mt-md-0">Logout</a>';

View file

@ -49,12 +49,12 @@ if (currentScheme == "custom") {
<meta name="theme-color" content="<%- colone %>">
<style>
:root {
--gradient: <%= currentCode%> !important;
--colone: <%= colone%> !important;
--coltwo: <%= coltwo%> !important;
--gradient: <%=currentCode%> !important;
--colone: <%=colone%> !important;
--coltwo: <%=coltwo%> !important;
}
input:checked + .tslider {
input:checked+.tslider {
background: linear-gradient(var(--gradient)) !important;
}
@ -71,7 +71,8 @@ if (currentScheme == "custom") {
color: var(--colone) !important;
}
.card.card-background.card-background-mask-primary::after, .swal2-popup.swal2-toast {
.card.card-background.card-background-mask-primary::after,
.swal2-popup.swal2-toast {
background-image: linear-gradient(var(--gradient)) !important;
}
@ -85,7 +86,9 @@ if (currentScheme == "custom") {
-webkit-font-smoothing: antialiased;
}
.swal2-success-fix, .swal2-success-circular-line-left, .swal2-success-circular-line-right {
.swal2-success-fix,
.swal2-success-circular-line-left,
.swal2-success-circular-line-right {
background: none !important;
}
@ -94,12 +97,16 @@ if (currentScheme == "custom") {
border: rgba(0, 0, 0, 0) !important;
}
.swal2-icon.swal2-error, .swal2-icon.swal2-success {
.swal2-icon.swal2-error,
.swal2-icon.swal2-success {
border-color: #f9f9f9 !important;
color: #f9f9f9 !important;
}
.swal2-x-mark-line-right, .swal2-x-mark-line-left, .swal2-success-line-long, .swal2-success-line-tip {
.swal2-x-mark-line-right,
.swal2-x-mark-line-left,
.swal2-success-line-long,
.swal2-success-line-tip {
background-color: #f9f9f9 !important;
}
@ -125,7 +132,7 @@ if (currentScheme == "custom") {
opacity: .85;
}
.navbar-vertical .navbar-nav > .nav-item .nav-link.active .icon {
.navbar-vertical .navbar-nav>.nav-item .nav-link.active .icon {
background-image: linear-gradient(var(--gradient)) !important;
}
@ -149,14 +156,14 @@ if (currentScheme == "custom") {
border-bottom: 0px solid;
}
.pagination.pagination-primary .page-item.active > .page-link,
.pagination.pagination-primary .page-item.active > .page-link:focus,
.pagination.pagination-primary .page-item.active > .page-link:hover {
.pagination.pagination-primary .page-item.active>.page-link,
.pagination.pagination-primary .page-item.active>.page-link:focus,
.pagination.pagination-primary .page-item.active>.page-link:hover {
background-image: linear-gradient(var(--gradient));
border: none;
}
.sidenav[data-color="primary"] .navbar-nav > .nav-item > .nav-link.active .icon {
.sidenav[data-color="primary"] .navbar-nav>.nav-item>.nav-link.active .icon {
background-image: linear-gradient(var(--gradient));
}

View file

@ -5,9 +5,13 @@
<div class="copyright text-center text-sm text-muted text-lg-start">
© <%= new Date().getFullYear() %>
<% if(themeConfig?.footer?.replaceDefault === true) { %>
<a href="/credits" class="font-weight-bold" target="_blank">Assistants</a><% if(themeConfig?.footer?.text?.length) { %> | <%= themeConfig?.footer?.text %> <% } %>
<a href="/credits" class="font-weight-bold"
target="_blank">Assistants</a><% if(themeConfig?.footer?.text?.length) { %> |
<%= themeConfig?.footer?.text %> <% } %>
<% } else { %>
Made with <i class="fa fa-heart"></i> by <a href="/credits" class="font-weight-bold" target="_blank">PlainDevelopment</a> and <a href="/credits" class="font-weight-bold" target="_blank">iMidnight</a>
Made with <i class="fa fa-heart"></i> by <a href="/credits" class="font-weight-bold"
target="_blank">PlainDevelopment</a> and <a href="/credits" class="font-weight-bold"
target="_blank">Jonny_Bro</a>
<% } %>
</div>
</div>

View file

@ -1,25 +1,45 @@
<meta charset="utf-8"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Meta Information -->
<% if(themeConfig?.meta?.author){ %><meta name="author" content="<%- themeConfig.meta.author %>"><% } %>
<% if(themeConfig?.meta?.owner){ %><meta name="owner" content="<%- themeConfig.meta.owner %>"><% } %>
<% if(themeConfig?.meta?.ogLocale){ %><meta property="og:locale" content="<%- themeConfig.meta.ogLocale %>"><% } %>
<% if(themeConfig?.meta?.ogTitle){ %><meta property="og:title" content="<%- themeConfig.meta.ogTitle %>"><% } %>
<% if(themeConfig?.meta?.twitterTitle){ %><meta property="twitter:title" content="<%- themeConfig.meta.twitterTitle %>"><% } %>
<% if(themeConfig?.meta?.description){ %><meta name="description" content="<%- themeConfig.meta.description %>"><% } %>
<% if(themeConfig?.meta?.ogDescription){ %><meta property="og:description" content="<%- themeConfig.meta.ogDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDescription){ %><meta property="twitter:description" content="<%- themeConfig.meta.twitterDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDomain){ %><meta property="twitter:domain" content="<%- themeConfig.meta.twitterDomain %>"><% } %>
<% if(themeConfig?.meta?.twitterUrl){ %><meta property="twitter:url" content="<%- themeConfig.meta.twitterUrl %>"><% } %>
<% if(themeConfig?.meta?.twitterCard){ %><meta property="twitter:card" content="<%- themeConfig.meta.twitterCard %>"><% } %>
<% if(themeConfig?.meta?.twitterSite){ %><meta property="twitter:site" content="<%- themeConfig.meta.twitterSite %>"><% } %>
<% if(themeConfig?.meta?.twitterSiteId){ %><meta property="twitter:site:id" content="<%- themeConfig.meta.twitterSiteId %>"><% } %>
<% if(themeConfig?.meta?.twitterCreator){ %><meta property="twitter:creator" content="<%- themeConfig.meta.twitterCreator %>"><% } %>
<% if(themeConfig?.meta?.twitterCreatorId){ %><meta property="twitter:creator:id" content="<%- themeConfig.meta.twitterCreatorId %>"><% } %>
<% if(themeConfig?.meta?.twitterImage){ %><meta property="twitter:image" content="<%- themeConfig.meta.twitterImage %>"><% } %>
<% if(themeConfig?.meta?.ogImage){ %><meta property="og:image" itemprop="image" content="<%- themeConfig.meta.ogImage %>"><% } %>
<% if(themeConfig?.meta?.ogType){ %><meta property="og:type" content="<%- themeConfig.meta.ogType %>"><% } %>
<% if(themeConfig?.meta?.ogUrl){ %><meta property="og:url" content="<%- themeConfig.meta.ogUrl %>"><% } %>
<% if(themeConfig?.meta?.ogSiteName){ %><meta property="og:site_name" content="<%- themeConfig.meta.ogSiteName %>"><% } %>
<% if(themeConfig?.meta?.author){ %>
<meta name="author" content="<%- themeConfig.meta.author %>"><% } %>
<% if(themeConfig?.meta?.owner){ %>
<meta name="owner" content="<%- themeConfig.meta.owner %>"><% } %>
<% if(themeConfig?.meta?.ogLocale){ %>
<meta property="og:locale" content="<%- themeConfig.meta.ogLocale %>"><% } %>
<% if(themeConfig?.meta?.ogTitle){ %>
<meta property="og:title" content="<%- themeConfig.meta.ogTitle %>"><% } %>
<% if(themeConfig?.meta?.twitterTitle){ %>
<meta property="twitter:title" content="<%- themeConfig.meta.twitterTitle %>"><% } %>
<% if(themeConfig?.meta?.description){ %>
<meta name="description" content="<%- themeConfig.meta.description %>"><% } %>
<% if(themeConfig?.meta?.ogDescription){ %>
<meta property="og:description" content="<%- themeConfig.meta.ogDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDescription){ %>
<meta property="twitter:description" content="<%- themeConfig.meta.twitterDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDomain){ %>
<meta property="twitter:domain" content="<%- themeConfig.meta.twitterDomain %>"><% } %>
<% if(themeConfig?.meta?.twitterUrl){ %>
<meta property="twitter:url" content="<%- themeConfig.meta.twitterUrl %>"><% } %>
<% if(themeConfig?.meta?.twitterCard){ %>
<meta property="twitter:card" content="<%- themeConfig.meta.twitterCard %>"><% } %>
<% if(themeConfig?.meta?.twitterSite){ %>
<meta property="twitter:site" content="<%- themeConfig.meta.twitterSite %>"><% } %>
<% if(themeConfig?.meta?.twitterSiteId){ %>
<meta property="twitter:site:id" content="<%- themeConfig.meta.twitterSiteId %>"><% } %>
<% if(themeConfig?.meta?.twitterCreator){ %>
<meta property="twitter:creator" content="<%- themeConfig.meta.twitterCreator %>"><% } %>
<% if(themeConfig?.meta?.twitterCreatorId){ %>
<meta property="twitter:creator:id" content="<%- themeConfig.meta.twitterCreatorId %>"><% } %>
<% if(themeConfig?.meta?.twitterImage){ %>
<meta property="twitter:image" content="<%- themeConfig.meta.twitterImage %>"><% } %>
<% if(themeConfig?.meta?.ogImage){ %>
<meta property="og:image" itemprop="image" content="<%- themeConfig.meta.ogImage %>"><% } %>
<% if(themeConfig?.meta?.ogType){ %>
<meta property="og:type" content="<%- themeConfig.meta.ogType %>"><% } %>
<% if(themeConfig?.meta?.ogUrl){ %>
<meta property="og:url" content="<%- themeConfig.meta.ogUrl %>"><% } %>
<% if(themeConfig?.meta?.ogSiteName){ %>
<meta property="og:site_name" content="<%- themeConfig.meta.ogSiteName %>"><% } %>
<!-- End of Meta Information -->

File diff suppressed because one or more lines are too long

View file

@ -1,19 +1,3 @@
<!--
=========================================================
* Now UI Dashboard - v1.5.0
=========================================================
* Product Page: https://www.creative-tim.com/product/now-ui-dashboard
* Copyright 2019 Creative Tim (http://www.creative-tim.com)
* Designed by www.invisionapp.com Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">

View file

@ -1,29 +1,14 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now:'settings'}) %>
<link href='/css/dashboard/settings.css' rel='stylesheet'>
<%- include("partials/preloader.ejs", {now:"settings"}) %>
<link href="/css/dashboard/settings.css" rel="stylesheet">
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100">
<%- include('partials/preload.ejs') %>
<%- include("partials/preload.ejs") %>
<aside
class="sidenav navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-3 ps"
style="float:left;" id="sidenav-main">
@ -141,7 +126,7 @@
</div>
<% if(themeConfig?.premium && req.session.user) { %>
<div class="sidenav-footer mx-3 pb-4" style="position: absolute;bottom: 0;">
<%- include('partials/premium.ejs') %>
<%- include("partials/premium.ejs") %>
</div>
<% } %>
@ -209,7 +194,7 @@
images.length)]; %>
<div class="container-fluid">
<div class="page-header min-height-300 border-radius-xl mt-4"
style="background-image: url('/img/curved-images/<%- image %>.webp'); background-position-y: 50%;">
style="background-image: url("/img/curved-images/<%- image %>.webp"); background-position-y: 50%;">
<span class="mask bg-gradient-primary opacity-6"></span>
</div>
<div class="card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
@ -454,24 +439,24 @@
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/bootstrap.tagsinput/0.4.2/bootstrap-tagsinput.min.js"></script>
<script>
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var win = navigator.platform.indexOf("Win") > -1;
if (win && document.querySelector("#sidenav-scrollbar")) {
var options = {
damping: '0.5'
damping: "0.5"
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
Scrollbar.init(document.querySelector("#sidenav-scrollbar"), options);
}
</script>
<script>
$(document).ready(function () {
<% if ( req.query.error === "premiumRequired" ) { %>
sweetalert("error", "<%= themeConfig?.sweetalert?.error?.requirePremium || 'Premium is required for this category' %>", 2000);
window.history.replaceState({}, title, window.location.href.split('?')[0]);
sweetalert("error", "<%= themeConfig?.sweetalert?.error?.requirePremium || "Premium is required for this category" %>", 2000);
window.history.replaceState({}, title, window.location.href.split("?")[0]);
<% } %>
$('.multiSelect').select2({ closeOnSelect: true });
$(".multiSelect").select2({ closeOnSelect: true });
$(".tags").select2({ theme: "classic", tags: true })
$(".select2-selection").addClass("form-control")
$(".select2-search__field").attr('formType', 'tagInput');
$(".select2-search__field").attr("formType", "tagInput");
});
function updateSlider(slideAmount, id) {
@ -482,7 +467,7 @@
<!-- Github buttons -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<!-- Control Center for Soft Dashboard: parallax effects, scripts for the example pages etc -->
<%- include('partials/scripts.ejs', {now: "settings" }) %>
<%- include("partials/scripts.ejs", {now: "settings" }) %>
</body>
</html>

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<%- include('partials/preloader.ejs', {now:'index', req: req}) %>

View file

@ -14741,23 +14741,8 @@ fieldset:disabled .btn {
.d-print-none {
display: none !important;
}
} /*!
}
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (site.license)
* Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
.alert-primary {
background-image: linear-gradient(310deg, #7928ca 0, #d6006c 100%);
}

827
yarn.lock

File diff suppressed because it is too large Load diff