Skip to content
Merged

Dev #16

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,877 changes: 3,188 additions & 1,689 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,23 @@
"@sentry/node": "^8.28.0",
"@sentry/profiling-node": "^8.28.0",
"axios": "^1.6.7",
"cheerio": "^1.0.0-rc.12",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
"form-data": "^4.0.5",
"json-to-pretty-yaml": "^1.2.2",
"json-xml-parse": "^1.2.8",
"morgan": "^1.10.0",
"node": "^16.19.1",
"node-fetch": "^2.7.0",
"playwright": "^1.57.0",
"rate-limit-redis": "^3.0.1",
"redis": "^4.6.5",
"redis-json": "^6.0.3",
"rettiwt-api": "^3.1.1"
"rettiwt-api": "^6.0.8",
"undici": "^7.16.0"
},
"devDependencies": {
"dotenv": "^16.0.3",
"nodemon": "^3.1.0"
"nodemon": "^3.1.11"
}
}
30 changes: 23 additions & 7 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,38 @@ app.use((req, res, next) => {
next();
});

// Rutas deshabilitadas
const DISABLED_ROUTES = process.env.DISABLED_ROUTES
? process.env.DISABLED_ROUTES.split(',').map(r => r.trim())
: [];

//We have a folder called "routes", and inside that folder we have a folders called "v1", "v2", "v3" and more, inside those folders we have a folder called "users", "guilds" and more, inside those folders we have a file called "@me.js", "index.js" and more
//This is how we require all the files in the "routes" folder
//The route is the path to the file, and the file is the file that we require
function requireRoutes(path, fullpath = "") {
fs.readdirSync(join(__dirname, path)).forEach(file => {
if (file.endsWith(".js")) {
let routePath = "";
if (file === "index.js") {
app.use(`${fullpath.replace("~", ":")}`, require(join(__dirname, path, file)));
console.log(`Loaded route: ${fullpath.replace("~", ":")}`);
routePath = `${fullpath.replace("~", ":")}`;
} else {
routePath = `${fullpath.replace(".js", ).replace("~", ":")}/${file.replace(".js", "")}`;
}

// Verificar si la ruta está deshabilitada
const isDisabled = DISABLED_ROUTES.some(disabled => routePath.includes(disabled));

if (isDisabled) {
console.log(`⛔ Ruta deshabilitada (saltada): ${routePath}`);
} else {
app.use(`${fullpath.replace(".js", ).replace("~", ":")}/${file.replace(".js", "")}`, require(join(__dirname, path, file)));
console.log(`Loaded route: ${fullpath.replace(".js", ).replace("~", ":")}/${file.replace(".js", "")}`);
if (file === "index.js") {
app.use(`${fullpath.replace("~", ":")}`, require(join(__dirname, path, file)));
console.log(`✅ Ruta cargada: ${fullpath.replace("~", ":")}`);
} else {
app.use(`${fullpath.replace(".js", ).replace("~", ":")}/${file.replace(".js", "")}`, require(join(__dirname, path, file)));
console.log(`✅ Ruta cargada: ${fullpath.replace(".js", ).replace("~", ":")}/${file.replace(".js", "")}`);
}
}
// app.use(`${fullpath}/${file.replace(".js", "")}`, require(join(__dirname, path, file)));
// console.log(`Loaded route: ${fullpath}/${file.replace(".js", "")}`);
//If the file is called index.js, we don't want to add the file name to the route
} else {
requireRoutes(join(path, file), `${fullpath}/${file}`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/v1/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ router.get('/:id/banner', limit, async (req, res) => {
})
}

if(!data?.id) return;
if(!data?.id) return null;

let banner = data.banner ? new Image("UserBanner", data.id, data.banner) : null;

Expand Down
8 changes: 0 additions & 8 deletions src/routes/v2/discord/applications/@me.js

This file was deleted.

16 changes: 12 additions & 4 deletions src/routes/v2/discord/applications/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,25 @@ const limit = RateLimit(15, 25);

router.get('/:id', limit, async (req, res) => {
const { id } = req.params;
const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) await http.get('APPLICATION_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
if (response.status === 200) {
await cache.set(id, response.data);
if (!req.headers["discord-bot-token"]) await cache.set(id, response.data);
data = response.data;
} else {
return statusCodeHandler({ statusCode: response.status }, res);
}
}).catch(err => {
return statusCodeHandler({ statusCode: 14001 }, res);
});

if(res.headersSent) return null;

if (!data) return statusCodeHandler({ statusCode: 14001 }, res);

data.raw = JSON.parse(JSON.stringify(data));

//If the application has a cover image, add it to the object
if (data.cover_image) {
Expand All @@ -54,7 +58,11 @@ router.get('/:id', limit, async (req, res) => {
data.team.members.forEach(async member => {

//Get a axios get request to the user
let response = await axios.get(req.protocol + '://' + req.get('host') + `/v1/users/${member.user.id}`);
const response = await axios.get(`${req.protocol}://${req.get('host')}/v2/discord/users/${member.user.id}`, {
headers: {
"X-Api-Key": process.env.INTERNAL_API_KEY
}
});
//If the response is 200, replace the user object with the response data
if (response.status === 200) {
member.user = response.data;
Expand Down
4 changes: 3 additions & 1 deletion src/routes/v2/discord/experiments/guilds/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ router.get('/', limit, async (req, res) => {
return statusCodeHandler({ statusCode: response.status }, res);
}
}).catch(err => {
return;
if (err) {
console.log(err.stack);
}
}
);

Expand Down
6 changes: 5 additions & 1 deletion src/routes/v2/discord/experiments/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ router.get('/', limit, async (req, res) => {
return statusCodeHandler({ statusCode: response.status }, res);
}
}).catch(err => {
return;
if (err) {
console.log(err.stack);
return statusCodeHandler({ statusCode: 503 }, res);
}
return null;
}
);

Expand Down
7 changes: 6 additions & 1 deletion src/routes/v2/discord/experiments/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ router.get('/', limit, async (req, res) => {
return statusCodeHandler({ statusCode: response.status }, res);
}
}).catch(err => {
return;
if (err) {
console.log(err.stack);
return null;
}

return statusCodeHandler({ statusCode: 503 }, res);
}
);

Expand Down
68 changes: 34 additions & 34 deletions src/routes/v2/discord/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,72 +16,71 @@ const limit = RateLimit(15, 50);

router.get('/:id', limit, async (req, res) => {
const { id } = req.params;
const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) {
await http.get('USER_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
if (response.status === 200) {
await cache.set(id, response.data);
if(!req.headers["discord-bot-token"]) await cache.set(id, response.data);
data = response.data;
} else {
return statusCodeHandler({ statusCode: response.status }, res);
}

return null;
}).catch((e) => {
console.log(e)
return statusCodeHandler({ statusCode: 11001 }, res);
})
}

if(!data?.id) return;
if(!data?.id) return null;

data.raw = JSON.parse(JSON.stringify(data))

//If the user dont have a bot property, add it to the user object
if (!data.bot) data.bot = false;

//If the user has a username and discriminator, add it to the user object
data.tag = `${data.username}#${data.discriminator}`;

//Show the user's flags
let flags = new UserFlags(data.public_flags);

//If system is true, add "SYSTEM" to the flags
if (data.system) flags.addFlag("SYSTEM");
const conditions = {
dataSystem: data.system,
dataBannerOrAvatar: data.banner || data.avatar?.startsWith("a_"),
discordPartnerOrEmployee: (flags.hasFlag("DISCORD_PARTNER") || flags.hasFlag("DISCORD_EMPLOYEE")) && !flags.hasFlag("NITRO")
};

//If user has a banner, or a avatar with "a_" in front of it, add "NITRO" to the flags
if (data.banner || data.avatar?.startsWith("a_")) flags.addFlag("NITRO");
const mappedFlags = {
dataSystem: "SYSTEM",
dataBannerOrAvatar: "NITRO",
discordPartnerOrEmployee: "NITRO"
};

//If the user have DISCORD_PARTNER or DISCORD_EMPLOYEE, add "NITRO" to the flags
if ((flags.hasFlag("DISCORD_PARTNER") || flags.hasFlag("DISCORD_EMPLOYEE")) && !flags.hasFlag("NITRO")) flags.addFlag("NITRO");
Object.keys(conditions).forEach(key => {
if (conditions[key]) {
flags.addFlag(mappedFlags[key]);
}
});

//Add the flags to the user object
data.formedFlags = flags.getFlags();

//Convert hash of avatar and banner to a url
//If the banner or avatar starts with "a_", it's animated, so add ".gif" to the end of the url
let avatar = data.avatar ? new Image("UserAvatar", data.id, data.avatar) : new Image("DefaultUserAvatar", (data.discriminator === "0" || !data.discriminator) ? data.id : data.discriminator, { format: "png" });
let banner = data.banner ? new Image("UserBanner", data.id, data.banner) : null;

let avatarURL = avatar.url;
let bannerURL = banner ? banner.url : null;

//Add the avatar and banner url to the user object
data.avatarURL = avatarURL;
data.bannerURL = bannerURL;

//Now add a object called "avatarURLs" and bannerURLs to the user object, and add all the sizes of the avatar and banner
if (avatarURL) data.avatarURLs = avatar.sizes;
if (bannerURL) data.bannerURLs = banner.sizes;

//Get with the Discord Snowflake the date of when the user was created
let date = new Date(parseInt(data.id) / 4194304 + 1420070400000);

//Add the date to the user object
data.createdAt = date.toISOString();
data.createdAtTimestamp = date.getTime();

//Get all avatar decorations
if(data.avatar_decoration_data?.asset) data.avatarDecoration = data.avatar_decoration_data?.asset;

let avatarDecoration = data.avatar_decoration_data?.asset ? new Image("AvatarDecoration", data.avatar_decoration_data.asset, {format: "png"}) : null;
Expand All @@ -102,7 +101,6 @@ router.get('/:id', limit, async (req, res) => {

data.clanBadgeURLs = clanBadge ? clanBadge.sizes : null;

//Return the user object
return responseHandler(req.headers.accept, res, data, "user");

});
Expand All @@ -115,8 +113,8 @@ router.get(/\/(\d+)\/avatar(?:\.(\w+))?$/, limit, async (req, res) => {
// If is not gif, webp or png, set it to png, if it's not seted, not set nothing
if (ext && !["gif", "webp", "png"].includes(ext)) ext = "png";

const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) {
await http.get('USER_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
Expand Down Expand Up @@ -148,8 +146,8 @@ router.get(/\/(\d+)\/banner(?:\.(\w+))?$/, limit, async (req, res) => {
// If is not gif, webp or png, set it to png, if it's not seted, not set nothing
if (ext && !["gif", "webp", "png"].includes(ext)) ext = "png";

const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) {
await http.get('USER_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
Expand All @@ -164,7 +162,7 @@ router.get(/\/(\d+)\/banner(?:\.(\w+))?$/, limit, async (req, res) => {
})
}

if(!data?.id) return;
if(!data?.id) return null;

let banner = data.banner ? new Image("UserBanner", data.id, data.banner, { format: ext }) : null;
if(banner) return res.redirect(banner.url)
Expand All @@ -179,8 +177,8 @@ router.get(/\/(\d+)\/(?:avatar-decoration|avatardecoration|avatar-decorator|avat

if (!["webp", "png"].includes(ext)) ext = "png";

const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) {
await http.get('USER_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
Expand All @@ -190,13 +188,15 @@ router.get(/\/(\d+)\/(?:avatar-decoration|avatardecoration|avatar-decorator|avat
} else {
return statusCodeHandler({ statusCode: response.status }, res);
}

return null;
}).catch((e) => {
console.log(e)
return statusCodeHandler({ statusCode: 11001 }, res);
})
}

if(!data?.id) return;
if(!data?.id) return null;

let avatarDecoration = data.avatar_decoration_data?.asset ? new Image("AvatarDecoration", data.avatar_decoration_data.asset, {format: ext}) : null;

Expand All @@ -210,8 +210,8 @@ router.get(/\/(\d+)\/(?:clan-badge|clanbadge)(?:\.(\w+))?$/, limit, async (req,

if (!["webp", "png", "gif"].includes(ext)) ext = "png";

const http = new HTTP(process.env.DISCORD_BOT_TOKEN);
let data = await cache.get(id);
const http = new HTTP(req.headers["discord-bot-token"] || process.env.DISCORD_BOT_TOKEN);
let data = req.headers["discord-bot-token"] ? null : await cache.get(id);
if (!data) {
await http.get('USER_URL', "path", id).then(async response => {
//If the response is 200, add the user to the cache
Expand All @@ -227,7 +227,7 @@ router.get(/\/(\d+)\/(?:clan-badge|clanbadge)(?:\.(\w+))?$/, limit, async (req,
})
}

if(!data?.id) return;
if(!data?.id) return null;

let clanBadge = data.clan ? new Image("ClanBadge", data.clan.identity_guild_id, data.clan.badge, {format: ext}) : null;

Expand Down
Loading
Loading