mirror of
https://github.com/ApfelTeeSaft/Reload-Backend.git
synced 2026-08-27 03:43:27 +00:00
Fixed bugs, added a lot of stuff including the SAC
This commit is contained in:
@@ -11,7 +11,7 @@ bUseBorderlessWindow=True
|
||||
[/Script/FortniteGame.FortGlobals]
|
||||
bAllowLogout=false
|
||||
|
||||
### Turbo build
|
||||
# Turbo build
|
||||
;[/Script/FortniteGame.FortPlayerController]
|
||||
;TurboBuildInterval=0.015f
|
||||
;TurboBuildFirstInterval=0.015f
|
||||
|
||||
+4
-1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"moderators": ["discordId"],
|
||||
"moderators": ["discordId", "discordId2"],
|
||||
"discord": {
|
||||
"bUseDiscordBot": true,
|
||||
"bot_token": ""
|
||||
},
|
||||
"mongodb": {
|
||||
@@ -11,6 +12,8 @@
|
||||
"EnableGlobalChat": false
|
||||
},
|
||||
|
||||
"bEnableDebugLogs": false,
|
||||
|
||||
"//": "If you want to use the backend on reboot, leave 3551 as the port",
|
||||
"port": 3551,
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ module.exports = {
|
||||
execute: async (interaction) => {
|
||||
|
||||
if (!config.moderators.includes(interaction.user.id)) {
|
||||
console.log("User does not have moderator permissions.");
|
||||
return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ module.exports = {
|
||||
execute: async (interaction) => {
|
||||
|
||||
if (!config.moderators.includes(interaction.user.id)) {
|
||||
console.log("User does not have moderator permissions.");
|
||||
return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,5 @@ module.exports = {
|
||||
if (accessToken != -1 || refreshToken != -1) functions.UpdateTokens();
|
||||
|
||||
interaction.editReply({ content: `Successfully banned ${targetUser.username}`, ephemeral: true });
|
||||
|
||||
const logChannel = interaction.client.channels.cache.get(config.logChannelBanId);
|
||||
if (logChannel) {
|
||||
logChannel.send(`<@${interaction.user.id}> / ${interaction.user.tag} has banned **${targetUser.username}**`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
const functions = require("../../../structs/functions.js");
|
||||
const config = require("../../../Config/config.json");
|
||||
|
||||
module.exports = {
|
||||
commandInfo: {
|
||||
name: "createsac",
|
||||
description: "Creates a Support A Creator Code.",
|
||||
options: [
|
||||
{
|
||||
name: "code",
|
||||
description: "The SUpport A Creator Code.",
|
||||
required: true,
|
||||
type: 3
|
||||
},
|
||||
{
|
||||
name: "ingame-username",
|
||||
description: "In-Game Name of the codes owner.",
|
||||
required: true,
|
||||
type: 3
|
||||
},
|
||||
],
|
||||
},
|
||||
execute: async (interaction) => {
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
if (!config.moderators.includes(interaction.user.id)) {
|
||||
return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
|
||||
}
|
||||
|
||||
const { options } = interaction;
|
||||
|
||||
const code = options.get("code").value;
|
||||
const username = options.get("ingame-username").value;
|
||||
const creator = interaction.user.id;
|
||||
await functions.createSAC(code, username, creator).then(resp => {
|
||||
|
||||
if (resp.message == undefined) return interaction.editReply({ content: "There was an unknown error!", ephemeral: true})
|
||||
|
||||
if (resp.status >= 400) return interaction.editReply({ content: resp.message, ephemeral: true });
|
||||
|
||||
interaction.editReply({ content: resp.message, ephemeral: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ module.exports = {
|
||||
execute: async (interaction) => {
|
||||
|
||||
if (!config.moderators.includes(interaction.user.id)) {
|
||||
console.log("User does not have moderator permissions.");
|
||||
return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
|
||||
}
|
||||
|
||||
@@ -46,5 +45,5 @@ module.exports = {
|
||||
.setTimestamp();
|
||||
await interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
await interaction.options.getUser('username').send({ content: `Your account has been deleted by <@${interaction.user.id}>` });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,11 +44,6 @@ module.exports = {
|
||||
|
||||
if (accessToken != -1 || refreshToken != -1) {
|
||||
functions.UpdateTokens();
|
||||
|
||||
const logChannel = interaction.client.channels.cache.get(config.logChannelKickId);
|
||||
if (logChannel) {
|
||||
logChannel.send(`<@${interaction.user.id}> / ${interaction.user.tag} has kicked **${targetUser.username}**`);
|
||||
}
|
||||
|
||||
return interaction.editReply({ content: `Successfully kicked ${targetUser.username}`, ephemeral: true });
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ module.exports = {
|
||||
execute: async (interaction) => {
|
||||
|
||||
if (!config.moderators.includes(interaction.user.id)) {
|
||||
console.log("User does not have moderator permissions.");
|
||||
return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,5 @@ module.exports = {
|
||||
await targetUser.updateOne({ $set: { banned: false } });
|
||||
|
||||
interaction.editReply({ content: `Successfully unbanned ${targetUser.username}`, ephemeral: true });
|
||||
|
||||
const logChannel = interaction.client.channels.cache.get(config.logChannelUnbanId);
|
||||
if (logChannel) {
|
||||
logChannel.send(`<@${interaction.user.id}> / ${interaction.user.tag} has unbanned **${targetUser.username}**`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,6 @@ module.exports = {
|
||||
|
||||
let plainPassword = options.get("password").value;
|
||||
|
||||
if (plainPassword.length >= 128) return interaction.editReply({ content: "Your password must be less than 128 characters long.", ephemeral: true });
|
||||
if (plainPassword.length < 8) return interaction.editReply({ content: "Your password must be atleast 8 characters long.", ephemeral: true });
|
||||
|
||||
let hashedPassword = await bcrypt.hash(plainPassword, 10);
|
||||
|
||||
await user.updateOne({ $set: { password: hashedPassword } });
|
||||
|
||||
@@ -24,21 +24,12 @@ module.exports = {
|
||||
if (!user)
|
||||
return interaction.editReply({ content: "You are not registered!", ephemeral: true });
|
||||
|
||||
const validUsernameRegex = /^[a-zA-Z0-9]+$/;
|
||||
const username = interaction.options.getString('username');
|
||||
if (!validUsernameRegex.test(username) || badwords.isProfane(username)) {
|
||||
return interaction.editReply({ content: "Invalid username. Username must contain only letters and numbers, and no spaces or special characters. Additionally, it should not contain inappropriate language." });
|
||||
if (!badwords.isProfane(username)) {
|
||||
return interaction.editReply({ content: "Invalid username. Username must not contain inappropriate language." });
|
||||
}
|
||||
|
||||
const plainUsername = interaction.options.getString('username');
|
||||
|
||||
if (plainUsername.length < 3) {
|
||||
return interaction.editReply({ content: "Invalid username. Username must have at least 3 characters." });
|
||||
}
|
||||
|
||||
if (plainUsername.length > 20) {
|
||||
return interaction.editReply({ content: "Invalid username. Username must be 20 characters or less" });
|
||||
}
|
||||
|
||||
const existingUser = await User.findOne({ username: plainUsername });
|
||||
if (existingUser) {
|
||||
|
||||
@@ -12,17 +12,15 @@ module.exports = {
|
||||
const user = await User.findOne({ discordId: interaction.user.id }).lean();
|
||||
if (!user) return interaction.editReply({ content: "You do not have a registered account!", ephemeral: true });
|
||||
|
||||
//let onlineStatus = global.Clients.some(i => i.accountId == user.accountId);
|
||||
let onlineStatus = global.Clients.some(i => i.accountId == user.accountId);
|
||||
|
||||
let embed = new MessageEmbed()
|
||||
.setColor("GREEN")
|
||||
.setDescription("These are your account details")
|
||||
//.setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() })
|
||||
.setFields(
|
||||
//{ name: "Created", value: `${new Date(user.created)}`.substring(0, 15) },
|
||||
{ name: 'Username', value: user.username },
|
||||
{ name: 'Email', value: `${user.email}` },
|
||||
//{ name: "Online", value: `${onlineStatus ? "Yes" : "No"}` },
|
||||
{ name: "Online", value: `${onlineStatus ? "Yes" : "No"}` },
|
||||
{ name: "Banned", value: `${user.banned ? "Yes" : "No"}` },
|
||||
{ name: "Account ID", value: user.accountId })
|
||||
.setTimestamp()
|
||||
|
||||
@@ -46,4 +46,21 @@ client.on("interactionCreate", async interaction => {
|
||||
executeCommand(path.join(__dirname, "commands"), interaction.commandName);
|
||||
});
|
||||
|
||||
//AntiCrash Sysyem
|
||||
client.on("error", (err) => {
|
||||
console.log("Discord API Error:", err);
|
||||
});
|
||||
|
||||
process.on("unhandledRejection", (reason, p) => {
|
||||
console.log("Unhandled promise rejection:", reason, p);
|
||||
});
|
||||
|
||||
process.on("uncaughtException", (err, origin) => {
|
||||
console.log("Uncaught Exception:", err, origin);
|
||||
});
|
||||
|
||||
process.on("uncaughtExceptionMonitor", (err, origin) => {
|
||||
console.log("Uncaught Exception Monitor:", err, origin);
|
||||
});
|
||||
|
||||
client.login(config.discord.bot_token);
|
||||
@@ -4,6 +4,85 @@
|
||||
|
||||
Reload Backend is a universal Fortnite private server backend written in JavaScript
|
||||
|
||||
Created by Burlone, This is a modded backend, all main backend credits to lawin
|
||||
Created by Burlone, This is a modded backend, all main backend credits to [Lawin](https://github.com/Lawin0129)
|
||||
|
||||
(Missions only work on s8, daily missions working on all versions)
|
||||
## Features
|
||||
- Locker:
|
||||
[x] Changing items.
|
||||
[x] Changing banner icon and banner color.
|
||||
[x] Changing item edit styles.
|
||||
[x] Favoriting items.
|
||||
[x] Marking items as seen.
|
||||
- Friends:
|
||||
[x] Adding friends.
|
||||
[x] Accepting friend requests.
|
||||
[x] Removing friends.
|
||||
[x] Blocking friends.
|
||||
[x] Setting nicknames.
|
||||
[x] Removing nicknames.
|
||||
- Item Shop:
|
||||
[x] Customizable Item Shop.
|
||||
[x] Purchasing items from the Item Shop.
|
||||
[x] Gifting items to your friends.
|
||||
- BattlePass (s2-s10):
|
||||
[x] Possibility to buy the battle pass
|
||||
[x] Possibility to purchase pass levels
|
||||
- Challenges:
|
||||
[x] Daily missions worked (Backend Part)
|
||||
[x] Working weekly missions (Backend Part)
|
||||
- SAC (Support A Creator):
|
||||
[x] It supports a supported creator, you can set it using the "/createsac" command on discord
|
||||
- Matchmaker:
|
||||
[x] An improved matchmaker
|
||||
### XMPP Features
|
||||
- Parties (builds 3.5 to 14.50).
|
||||
- Chat (whispering, global chat, party chat).
|
||||
- Friends.
|
||||
|
||||
## TO-DO
|
||||
- [] Create an automatic shop
|
||||
- [] Create a support with save the world
|
||||
|
||||
## Discord Bot Commands
|
||||
### User Commands:
|
||||
- `/create {email} {username} {password}` - Creates an account on the backend (You can only create 1 account).
|
||||
- `/details` - Retrieves your account info.
|
||||
- `/lookup {username}` - Retrieves someones account info.
|
||||
- `/exchange-code` - Generates an exchange code for login. (One time use for each code and if not used it expires after 5 mins).
|
||||
- `/change-username {newUsername}` - You can change your username using this command.
|
||||
- `/change-email {newEmail}` - You can change your email using this command.
|
||||
- `/change-password {newPassword}` - You can change your password using this command.
|
||||
- `/sign-out-of-all-sessions` - Signs you out if you have an active session.
|
||||
- `/vbucksamount` - Shows how many vbucks to the user
|
||||
### Admin Commands:
|
||||
- You can only use the admin commands if you are a moderator.
|
||||
- `/addall {user}` - Allows you to give a user all cosmetics. Note: This will reset all your lockers to default
|
||||
- `/addvbucks {user} {vbucks}` - Lets you change a users amount of vbucks
|
||||
- `/ban {targetUsername}` - Ban a user from the backend by their username.
|
||||
- `/createsac {code} {ingame-username}` - Creates a Support A Creator Code.
|
||||
- `/delete {username}` - Deletes a users account
|
||||
- `/kick {targetUsername}` - Kick someone out of their current session by their username.
|
||||
- `/removevbucks {user} {vbucks}` - Lets you change a users amount of vbucks
|
||||
- `/unban {targetUsername}` - Unban a user from the backend by their username.
|
||||
### How to set up moderators?
|
||||
1) Go to Config/config.json in the directory you extracted Reboot Backend into.
|
||||
2) Open it, you should see a "moderators" section in the file.
|
||||
3) You have to get your discord id and replace discordId with it.
|
||||
4) You can set multiple moderators like this `["discordId","discordId2"]`.
|
||||
|
||||
## How to start Reboot Backend
|
||||
1) Install [NodeJS](https://nodejs.org/en/) and [MongoDB](https://www.mongodb.com/try/download/community).
|
||||
2) Download and Extract Reboot Backend to a safe location.
|
||||
3) Run "install_packages.bat" to install all the required modules.
|
||||
4) Go to Config/config.json in the directory you extracted Reboot Backend into.
|
||||
5) Open it, set your discord bot token (DO NOT SHARE THIS TOKEN) and save it. The discord bot will be used for creating accounts and managing your account (You can disable the discord bot by entering "bUseDiscordBot" to false in "Config/config.json").
|
||||
6) Run "start.bat", if there is no errors, it should work.
|
||||
7) Use something to redirect the Fortnite servers to localhost:8080 (Which could be fiddler, ssl bypass that redirects servers, etc...)
|
||||
8) When Fortnite launches and is connected to the backend, enter your email and password (or launch with an exchange code) then press login. It should let you in and everything should be working fine.
|
||||
|
||||
## Credits
|
||||
### Credits to:
|
||||
[Lawin](https://github.com/Lawin0129) - For the backend base (LawinServerV2)
|
||||
[Burlone](https://github.com/burlone0) - For having modded most things, let's say he modded everything
|
||||
[NotTacos](https://github.com/PhysicalDrive) - For adding the working challenges (Backend Part)
|
||||
[zvivsp](https://github.com/zvivsp) - For creating the graphics
|
||||
@@ -15,7 +15,7 @@ if (!fs.existsSync("./ClientSettings")) fs.mkdirSync("./ClientSettings");
|
||||
global.JWT_SECRET = functions.MakeID();
|
||||
const PORT = config.port;
|
||||
|
||||
console.log('Welcome to Reload Backend\n')
|
||||
console.log('Welcome to Reload Backend\n');
|
||||
|
||||
const tokens = JSON.parse(fs.readFileSync("./tokenManager/tokens.json").toString());
|
||||
|
||||
@@ -54,22 +54,37 @@ fs.readdirSync("./routes").forEach(fileName => {
|
||||
app.use(require(`./routes/${fileName}`));
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
app.get("/unknown", (req, res) => {
|
||||
log.debug('GET /unknown endpoint called');
|
||||
res.json({ msg: "Reboot Backend - Made by Burlone" });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
log.backend(`App started listening on port ${PORT}`);
|
||||
|
||||
require("./xmpp/xmpp.js");
|
||||
require("./DiscordBot");
|
||||
if(config.discord.bUseDiscordBot === true) {
|
||||
require("./DiscordBot");
|
||||
}
|
||||
}).on("error", async (err) => {
|
||||
if (err.code == "EADDRINUSE") {
|
||||
log.error(`Port ${PORT} is already in use!\nClosing in 3 seconds...`);
|
||||
await functions.sleep(3000)
|
||||
await functions.sleep(3000);
|
||||
process.exit(0);
|
||||
} else throw err;
|
||||
});
|
||||
|
||||
// if endpoint not found, return this error
|
||||
const loggedUrls = new Set();
|
||||
app.use((req, res, next) => {
|
||||
const url = req.originalUrl;
|
||||
if (loggedUrls.has(url)) {
|
||||
return next();
|
||||
}
|
||||
log.debug(`Missing endpoint: ${req.method} ${url} request port ${req.socket.localPort}`);
|
||||
if (req.url.includes("..")) {
|
||||
res.redirect("https://youtu.be/dQw4w9WgXcQ");
|
||||
return;
|
||||
}
|
||||
error.createError(
|
||||
"errors.com.epicgames.common.not_found",
|
||||
"Sorry the resource you were trying to find could not be found",
|
||||
@@ -83,3 +98,5 @@ function DateAddHours(pdate, number) {
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
module.exports = app;
|
||||
@@ -0,0 +1,19 @@
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const SACCodesSchema = new mongoose.Schema(
|
||||
{
|
||||
created: { type: Date, required: true },
|
||||
createdby: { type: String, required: true },
|
||||
owneraccountId: { type: String, required: true },
|
||||
code: { type: String, required: true },
|
||||
code_lower: { type: String, required: true },
|
||||
code_higher: { type: String, required: true },
|
||||
},
|
||||
{
|
||||
collection: "SACcodes"
|
||||
}
|
||||
);
|
||||
|
||||
const model = mongoose.model('SACCodeSchema', SACCodesSchema);
|
||||
|
||||
module.exports = model;
|
||||
+3
-1
@@ -9,7 +9,9 @@ const UserSchema = new mongoose.Schema(
|
||||
username: { type: String, required: true, unique: true },
|
||||
username_lower: { type: String, required: true, unique: true },
|
||||
email: { type: String, required: true, unique: true },
|
||||
password: { type: String, required: true }
|
||||
password: { type: String, required: true },
|
||||
matchmakingId: { type: String, required: true, unique: true},
|
||||
isServer: { type: Boolean, default: false}
|
||||
},
|
||||
{
|
||||
collection: "users"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,106 @@
|
||||
const express = require("express");
|
||||
const app = express.Router();
|
||||
|
||||
const codes = require("./../model/saccodes.js");
|
||||
const Profile = require("../model/profiles.js");
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
app.get("/affiliate/api/public/affiliates/slug/:slug", async (req, res) => {
|
||||
var slug = req.params.slug;
|
||||
var lccode = slug.toLowerCase();
|
||||
|
||||
log.debug(`GET /affiliate/api/public/affiliates/slug/${slug} called`);
|
||||
|
||||
const code = await codes.findOne({ code_lower: lccode });
|
||||
|
||||
var ValidCode = null;
|
||||
|
||||
if (code === null) { ValidCode = false } else { ValidCode = true }
|
||||
|
||||
if (ValidCode === true) {
|
||||
log.debug(`Code found: ${code.code}`);
|
||||
return res.json({
|
||||
"id": code.code,
|
||||
"slug": code.code,
|
||||
"displayName": code.code,
|
||||
"code_higher": code.code_higher,
|
||||
"status": "ACTIVE",
|
||||
"verified": false
|
||||
});
|
||||
}
|
||||
|
||||
if (ValidCode === false) {
|
||||
log.debug(`Code not found: ${slug}`);
|
||||
res.status(404);
|
||||
res.json({});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/game/v2/profile/*/client/SetAffiliateName", verifyToken, async (req, res) => {
|
||||
const profiles = await Profile.findOne({ accountId: req.params[0] });
|
||||
let profile = profiles.profiles[req.query.profileId];
|
||||
|
||||
var ApplyProfileChanges = [];
|
||||
var BaseRevision = profile.rvn || 0;
|
||||
var QueryRevision = req.query.rvn || -1;
|
||||
var StatChanged = false;
|
||||
|
||||
var slug = req.body.affiliateName;
|
||||
var lccode = slug.toLowerCase();
|
||||
|
||||
log.debug(`POST /fortnite/api/game/v2/profile/*/client/SetAffiliateName called with slug: ${slug}`);
|
||||
|
||||
const code = await codes.findOne({ code_lower: lccode });
|
||||
|
||||
if (code == null) {
|
||||
log.debug(`Affiliate name not found: ${slug}`);
|
||||
res.status(404);
|
||||
res.json({});
|
||||
}
|
||||
|
||||
profile.stats.attributes.mtx_affiliate_set_time = new Date().toISOString();
|
||||
profile.stats.attributes.mtx_affiliate = code.code;
|
||||
|
||||
StatChanged = true;
|
||||
|
||||
if (StatChanged === true) {
|
||||
profile.rvn += 1;
|
||||
profile.commandRevision += 1;
|
||||
|
||||
ApplyProfileChanges.push({
|
||||
"changeType": "statModified",
|
||||
"name": "mtx_affiliate_set_time",
|
||||
"value": profile.stats.attributes.mtx_affiliate_set_time
|
||||
});
|
||||
|
||||
ApplyProfileChanges.push({
|
||||
"changeType": "statModified",
|
||||
"name": "mtx_affiliate",
|
||||
"value": profile.stats.attributes.mtx_affiliate
|
||||
});
|
||||
}
|
||||
|
||||
if (QueryRevision != BaseRevision) {
|
||||
ApplyProfileChanges = [{
|
||||
"changeType": "fullProfileUpdate",
|
||||
"profile": profile
|
||||
}];
|
||||
}
|
||||
|
||||
await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } });
|
||||
|
||||
res.json({
|
||||
"profileRevision": profile.rvn || 0,
|
||||
"profileId": req.query.profileId || "common_core",
|
||||
"profileChangesBaseRevision": BaseRevision,
|
||||
"profileChanges": ApplyProfileChanges,
|
||||
"profileCommandRevision": profile.commandRevision || 0,
|
||||
"serverTime": new Date().toISOString(),
|
||||
"responseVersion": 1
|
||||
});
|
||||
res.end();
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
+61
-29
@@ -5,6 +5,7 @@ const bcrypt = require("bcrypt");
|
||||
|
||||
const error = require("../structs/error.js");
|
||||
const functions = require("../structs/functions.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const tokenCreation = require("../tokenManager/tokenCreation.js");
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
@@ -20,6 +21,7 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
|
||||
clientId = clientId[0];
|
||||
} catch {
|
||||
log.debug("Invalid client ID in authorization header");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_client",
|
||||
"It appears that your Authorization header may be invalid or not present, please verify that you are sending the correct headers.",
|
||||
@@ -27,6 +29,8 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
);
|
||||
}
|
||||
|
||||
log.debug(`POST /account/api/oauth/token called with grant_type: ${req.body.grant_type}`);
|
||||
|
||||
switch (req.body.grant_type) {
|
||||
case "client_credentials":
|
||||
let ip = req.ip;
|
||||
@@ -52,11 +56,14 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
return;
|
||||
|
||||
case "password":
|
||||
if (!req.body.username || !req.body.password) return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Username/password is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
if (!req.body.username || !req.body.password) {
|
||||
log.debug("Missing username or password in request");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Username/password is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
}
|
||||
const { username: email, password: password } = req.body;
|
||||
|
||||
req.user = await User.findOne({ email: email.toLowerCase() }).lean();
|
||||
@@ -67,18 +74,26 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
[], 18031, "invalid_grant", 400, res
|
||||
);
|
||||
|
||||
if (!req.user) return err();
|
||||
else {
|
||||
if (!await bcrypt.compare(password, req.user.password)) return err();
|
||||
if (!req.user) {
|
||||
log.debug("Invalid username or password");
|
||||
return err();
|
||||
} else {
|
||||
if (!await bcrypt.compare(password, req.user.password)) {
|
||||
log.debug("Invalid password");
|
||||
return err();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "refresh_token":
|
||||
if (!req.body.refresh_token) return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Refresh token is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
if (!req.body.refresh_token) {
|
||||
log.debug("Missing refresh token in request");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Refresh token is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
}
|
||||
|
||||
const refresh_token = req.body.refresh_token;
|
||||
|
||||
@@ -99,6 +114,7 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
functions.UpdateTokens();
|
||||
}
|
||||
|
||||
log.debug("Invalid or expired refresh token");
|
||||
error.createError(
|
||||
"errors.com.epicgames.account.auth_token.invalid_refresh_token",
|
||||
`Sorry the refresh token '${refresh_token}' is invalid`,
|
||||
@@ -112,22 +128,28 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
break;
|
||||
|
||||
case "exchange_code":
|
||||
if (!req.body.exchange_code) return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Exchange code is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
if (!req.body.exchange_code) {
|
||||
log.debug("Missing exchange code in request");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.common.oauth.invalid_request",
|
||||
"Exchange code is required.",
|
||||
[], 1013, "invalid_request", 400, res
|
||||
);
|
||||
}
|
||||
|
||||
const { exchange_code } = req.body;
|
||||
|
||||
let index = global.exchangeCodes.findIndex(i => i.exchange_code == exchange_code);
|
||||
let exchange = global.exchangeCodes[index];
|
||||
|
||||
if (index == -1) return error.createError(
|
||||
"errors.com.epicgames.account.oauth.exchange_code_not_found",
|
||||
"Sorry the exchange code you supplied was not found. It is possible that it was no longer valid",
|
||||
[], 18057, "invalid_grant", 400, res
|
||||
);
|
||||
if (index == -1) {
|
||||
log.debug("Exchange code not found or invalid");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.account.oauth.exchange_code_not_found",
|
||||
"Sorry the exchange code you supplied was not found. It is possible that it was no longer valid",
|
||||
[], 18057, "invalid_grant", 400, res
|
||||
);
|
||||
}
|
||||
|
||||
global.exchangeCodes.splice(index, 1);
|
||||
|
||||
@@ -135,6 +157,7 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug(`Unsupported grant type: ${req.body.grant_type}`);
|
||||
error.createError(
|
||||
"errors.com.epicgames.common.oauth.unsupported_grant_type",
|
||||
`Unsupported grant type: ${req.body.grant_type}`,
|
||||
@@ -143,11 +166,14 @@ app.post("/account/api/oauth/token", async (req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.user.banned) return error.createError(
|
||||
"errors.com.epicgames.account.account_not_active",
|
||||
"You have been permanently banned from Fortnite.",
|
||||
[], -1, undefined, 400, res
|
||||
);
|
||||
if (req.user.banned) {
|
||||
log.debug("User account is banned");
|
||||
return error.createError(
|
||||
"errors.com.epicgames.account.account_not_active",
|
||||
"You have been permanently banned from Fortnite.",
|
||||
[], -1, undefined, 400, res
|
||||
);
|
||||
}
|
||||
|
||||
let refreshIndex = global.refreshTokens.findIndex(i => i.accountId == req.user.accountId);
|
||||
if (refreshIndex != -1) global.refreshTokens.splice(refreshIndex, 1);
|
||||
@@ -192,6 +218,8 @@ app.get("/account/api/oauth/verify", verifyToken, (req, res) => {
|
||||
let token = req.headers["authorization"].replace("bearer ", "");
|
||||
const decodedToken = jwt.decode(token.replace("eg1~", ""));
|
||||
|
||||
log.debug(`GET /account/api/oauth/verify called for account: ${req.user.accountId}`);
|
||||
|
||||
res.json({
|
||||
token: token,
|
||||
session_id: decodedToken.jti,
|
||||
@@ -211,6 +239,7 @@ app.get("/account/api/oauth/verify", verifyToken, (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/account/api/oauth/exchange", verifyToken, (req, res) => {
|
||||
log.debug("GET /account/api/oauth/exchange called");
|
||||
return res.status(400).json({
|
||||
"error": "This endpoint is deprecated, please use the discord bot to generate an exchange code."
|
||||
});
|
||||
@@ -241,12 +270,15 @@ app.get("/account/api/oauth/exchange", verifyToken, (req, res) => {
|
||||
});
|
||||
|
||||
app.delete("/account/api/oauth/sessions/kill", (req, res) => {
|
||||
log.debug("DELETE /account/api/oauth/sessions/kill called");
|
||||
res.status(204).end();
|
||||
});
|
||||
|
||||
app.delete("/account/api/oauth/sessions/kill/:token", (req, res) => {
|
||||
let token = req.params.token;
|
||||
|
||||
log.debug(`DELETE /account/api/oauth/sessions/kill/${token} called`);
|
||||
|
||||
let accessIndex = global.accessTokens.findIndex(i => i.token == token);
|
||||
|
||||
if (accessIndex != -1) {
|
||||
@@ -276,4 +308,4 @@ function DateAddHours(pdate, number) {
|
||||
return date;
|
||||
}
|
||||
|
||||
module.exports = app;
|
||||
module.exports = app;
|
||||
+13
-1
@@ -2,6 +2,7 @@ const express = require("express");
|
||||
const app = express.Router();
|
||||
|
||||
const functions = require("../structs/functions.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const Friends = require("../model/friends.js");
|
||||
const friendManager = require("../structs/friend.js");
|
||||
@@ -9,18 +10,22 @@ const friendManager = require("../structs/friend.js");
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
|
||||
app.get("/friends/api/v1/*/settings", (req, res) => {
|
||||
log.debug("GET /friends/api/v1/*/settings called");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
app.get("/friends/api/v1/*/blocklist", (req, res) => {
|
||||
log.debug("GET /friends/api/v1/*/blocklist called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.get("/friends/api/public/list/fortnite/*/recentPlayers", (req, res) => {
|
||||
log.debug("GET /friends/api/public/list/fortnite/*/recentPlayers called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.all("/friends/api/v1/*/friends/:friendId/alias", verifyToken, getRawBody, async (req, res) => {
|
||||
log.debug(`ALL /friends/api/v1/*/friends/${req.params.friendId}/alias called with method ${req.method}`);
|
||||
let friends = await Friends.findOne({ accountId: req.user.accountId });
|
||||
|
||||
let validationFail = () => error.createError(
|
||||
@@ -38,7 +43,7 @@ app.all("/friends/api/v1/*/friends/:friendId/alias", verifyToken, getRawBody, as
|
||||
if (!friends.list.accepted.find(i => i.accountId == req.params.friendId)) return error.createError(
|
||||
"errors.com.epicgames.friends.friendship_not_found",
|
||||
`Friendship between ${req.user.accountId} and ${req.params.friendId} does not exist`,
|
||||
[req.user.accountId,req.params.friendId], 14004, undefined, 404, res
|
||||
[req.user.accountId, req.params.friendId], 14004, undefined, 404, res
|
||||
);
|
||||
|
||||
const friendIndex = friends.list.accepted.findIndex(i => i.accountId == req.params.friendId);
|
||||
@@ -63,6 +68,7 @@ app.all("/friends/api/v1/*/friends/:friendId/alias", verifyToken, getRawBody, as
|
||||
});
|
||||
|
||||
app.get("/friends/api/public/friends/:accountId", verifyToken, async (req, res) => {
|
||||
log.debug(`GET /friends/api/public/friends/${req.params.accountId} called`);
|
||||
let response = [];
|
||||
|
||||
const friends = await Friends.findOne({ accountId: req.user.accountId }).lean();
|
||||
@@ -101,6 +107,7 @@ app.get("/friends/api/public/friends/:accountId", verifyToken, async (req, res)
|
||||
});
|
||||
|
||||
app.post("/friends/api/*/friends*/:receiverId", verifyToken, async (req, res) => {
|
||||
log.debug(`POST /friends/api/*/friends*/${req.params.receiverId} called`);
|
||||
let sender = await Friends.findOne({ accountId: req.user.accountId });
|
||||
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
|
||||
if (!sender || !receiver) return res.status(403).end();
|
||||
@@ -118,6 +125,7 @@ app.post("/friends/api/*/friends*/:receiverId", verifyToken, async (req, res) =>
|
||||
});
|
||||
|
||||
app.delete("/friends/api/*/friends*/:receiverId", verifyToken, async (req, res) => {
|
||||
log.debug(`DELETE /friends/api/*/friends*/${req.params.receiverId} called`);
|
||||
let sender = await Friends.findOne({ accountId: req.user.accountId });
|
||||
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
|
||||
if (!sender || !receiver) return res.status(403).end();
|
||||
@@ -131,6 +139,7 @@ app.delete("/friends/api/*/friends*/:receiverId", verifyToken, async (req, res)
|
||||
});
|
||||
|
||||
app.post("/friends/api/*/blocklist*/:receiverId", verifyToken, async (req, res) => {
|
||||
log.debug(`POST /friends/api/*/blocklist*/${req.params.receiverId} called`);
|
||||
let sender = await Friends.findOne({ accountId: req.user.accountId });
|
||||
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
|
||||
if (!sender || !receiver) return res.status(403).end();
|
||||
@@ -144,6 +153,7 @@ app.post("/friends/api/*/blocklist*/:receiverId", verifyToken, async (req, res)
|
||||
});
|
||||
|
||||
app.delete("/friends/api/*/blocklist*/:receiverId", verifyToken, async (req, res) => {
|
||||
log.debug(`DELETE /friends/api/*/blocklist*/${req.params.receiverId} called`);
|
||||
let sender = await Friends.findOne({ accountId: req.user.accountId });
|
||||
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
|
||||
if (!sender || !receiver) return res.status(403).end();
|
||||
@@ -154,6 +164,7 @@ app.delete("/friends/api/*/blocklist*/:receiverId", verifyToken, async (req, res
|
||||
});
|
||||
|
||||
app.get("/friends/api/v1/:accountId/summary", verifyToken, async (req, res) => {
|
||||
log.debug(`GET /friends/api/v1/${req.params.accountId}/summary called`);
|
||||
let response = {
|
||||
"friends": [],
|
||||
"incoming": [],
|
||||
@@ -205,6 +216,7 @@ app.get("/friends/api/v1/:accountId/summary", verifyToken, async (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/friends/api/public/blocklist/*", verifyToken, async (req, res) => {
|
||||
log.debug("GET /friends/api/public/blocklist/* called");
|
||||
let friends = await Friends.findOne({ accountId: req.user.accountId }).lean();
|
||||
|
||||
res.json({
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
const express = require("express")
|
||||
const app = express.Router();
|
||||
const fs = require("fs")
|
||||
const eulaJson = JSON.parse(fs.readFileSync('./responses/SharedAgreements.json', 'utf8'));
|
||||
|
||||
app.get("/eulatracking/api/shared/agreements/fn", async (req, res) => {
|
||||
res.json(eulaJson);
|
||||
});
|
||||
|
||||
app.get("/eulatracking/api/public/agreements/fn/account/:accountId", async (req, res) => {
|
||||
res.status(204).send();
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
+24
-1
@@ -1,23 +1,28 @@
|
||||
const express = require("express");
|
||||
const functions = require("../structs/functions.js");
|
||||
const fs = require("fs");
|
||||
const app = express.Router();
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
|
||||
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
|
||||
|
||||
app.post("/fortnite/api/game/v2/chat/*/*/*/pc", (req, res) => {
|
||||
log.debug("POST /fortnite/api/game/v2/chat/*/*/*/pc called");
|
||||
let resp = config.chat.EnableGlobalChat ? { "GlobalChatRooms": [{ "roomName": "reloadbackendglobal" }] } : {};
|
||||
|
||||
res.json(resp);
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/game/v2/tryPlayOnPlatform/account/*", (req, res) => {
|
||||
log.debug("POST /fortnite/api/game/v2/tryPlayOnPlatform/account/* called");
|
||||
res.setHeader("Content-Type", "text/plain");
|
||||
res.send(true);
|
||||
});
|
||||
|
||||
app.get("/launcher/api/public/distributionpoints/", (req, res) => {
|
||||
log.debug("GET /launcher/api/public/distributionpoints/ called");
|
||||
res.json({
|
||||
"distributions": [
|
||||
"https://download.epicgames.com/",
|
||||
@@ -30,11 +35,13 @@ app.get("/launcher/api/public/distributionpoints/", (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/waitingroom/api/waitingroom", (req, res) => {
|
||||
log.debug("GET /waitingroom/api/waitingroom called");
|
||||
res.status(204);
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/socialban/api/public/v1/*", (req, res) => {
|
||||
log.debug("GET /socialban/api/public/v1/* called");
|
||||
res.json({
|
||||
"bans": [],
|
||||
"warnings": []
|
||||
@@ -42,10 +49,12 @@ app.get("/socialban/api/public/v1/*", (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/events/tournamentandhistory/*/EU/WindowsClient", (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/events/tournamentandhistory/*/EU/WindowsClient called");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/statsv2/account/:accountId", (req, res) => {
|
||||
log.debug(`GET /fortnite/api/statsv2/account/${req.params.accountId} called`);
|
||||
res.json({
|
||||
"startTime": 0,
|
||||
"endTime": 0,
|
||||
@@ -55,6 +64,7 @@ app.get("/fortnite/api/statsv2/account/:accountId", (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/statsproxy/api/statsv2/account/:accountId", (req, res) => {
|
||||
log.debug(`GET /statsproxy/api/statsv2/account/${req.params.accountId} called`);
|
||||
res.json({
|
||||
"startTime": 0,
|
||||
"endTime": 0,
|
||||
@@ -64,6 +74,7 @@ app.get("/statsproxy/api/statsv2/account/:accountId", (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/stats/accountId/:accountId/bulk/window/alltime", (req, res) => {
|
||||
log.debug(`GET /fortnite/api/stats/accountId/${req.params.accountId}/bulk/window/alltime called`);
|
||||
res.json({
|
||||
"startTime": 0,
|
||||
"endTime": 0,
|
||||
@@ -73,53 +84,65 @@ app.get("/fortnite/api/stats/accountId/:accountId/bulk/window/alltime", (req, re
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/feedback/*", (req, res) => {
|
||||
log.debug("POST /fortnite/api/feedback/* called");
|
||||
res.status(200);
|
||||
res.end();
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/statsv2/query", (req, res) => {
|
||||
log.debug("POST /fortnite/api/statsv2/query called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.post("/statsproxy/api/statsv2/query", (req, res) => {
|
||||
log.debug("POST /statsproxy/api/statsv2/query called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/game/v2/events/v2/setSubgroup/*", (req, res) => {
|
||||
log.debug("POST /fortnite/api/game/v2/events/v2/setSubgroup/* called");
|
||||
res.status(204);
|
||||
res.end();
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/enabled_features", (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/enabled_features called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.get("/api/v1/events/Fortnite/download/*", (req, res) => {
|
||||
log.debug("GET /api/v1/events/Fortnite/download/* called");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/twitch/*", (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/twitch/* called");
|
||||
res.status(200);
|
||||
res.end();
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/world/info", (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/world/info called");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/game/v2/chat/*/recommendGeneralChatRooms/pc", (req, res) => {
|
||||
log.debug("POST /fortnite/api/game/v2/chat/*/recommendGeneralChatRooms/pc called");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/receipts/v1/account/*/receipts", (req, res) => {
|
||||
log.debug("GET /fortnite/api/receipts/v1/account/*/receipts called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/leaderboards/cohort/*", (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/leaderboards/cohort/* called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
app.post("/datarouter/api/v1/public/data", (req, res) => {
|
||||
log.debug("POST /datarouter/api/v1/public/data called");
|
||||
res.status(204);
|
||||
res.end();
|
||||
});
|
||||
|
||||
+11
-2
@@ -2,18 +2,23 @@ const express = require("express");
|
||||
const app = express.Router();
|
||||
const fs = require("fs");
|
||||
const functions = require("../structs/functions.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
|
||||
let buildUniqueId = {};
|
||||
|
||||
app.get("/fortnite/api/matchmaking/session/findPlayer/*", (req, res) => {
|
||||
log.debug("GET /fortnite/api/matchmaking/session/findPlayer/* called");
|
||||
res.status(200).end();
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/matchmakingservice/ticket/player/*", verifyToken, (req, res) => {
|
||||
log.debug("GET /fortnite/api/game/v2/matchmakingservice/ticket/player/* called");
|
||||
if (typeof req.query.bucketId != "string") return res.status(400).end();
|
||||
if (req.query.bucketId.split(":").length != 4) return res.status(400).end();
|
||||
if (req.user.isServer == true) return res.status(403).end();
|
||||
if (req.user.matchmakingId == null) return res.status(400).end();
|
||||
|
||||
buildUniqueId[req.user.accountId] = req.query.bucketId.split(":")[0];
|
||||
|
||||
@@ -22,13 +27,14 @@ app.get("/fortnite/api/game/v2/matchmakingservice/ticket/player/*", verifyToken,
|
||||
res.json({
|
||||
"serviceUrl": `ws://${config.matchmakerIP}`,
|
||||
"ticketType": "mms-player",
|
||||
"payload": "69=",
|
||||
"signature": "420="
|
||||
"payload": `${req.user.matchmakingId}`,
|
||||
"signature": "account"
|
||||
});
|
||||
res.end();
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/game/v2/matchmaking/account/:accountId/session/:sessionId", (req, res) => {
|
||||
log.debug(`GET /fortnite/api/game/v2/matchmaking/account/${req.params.accountId}/session/${req.params.sessionId} called`);
|
||||
res.json({
|
||||
"accountId": req.params.accountId,
|
||||
"sessionId": req.params.sessionId,
|
||||
@@ -37,6 +43,7 @@ app.get("/fortnite/api/game/v2/matchmaking/account/:accountId/session/:sessionId
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/matchmaking/session/:sessionId", verifyToken, (req, res) => {
|
||||
log.debug(`GET /fortnite/api/matchmaking/session/${req.params.sessionId} called`);
|
||||
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
|
||||
|
||||
let gameServerInfo = {
|
||||
@@ -98,10 +105,12 @@ app.get("/fortnite/api/matchmaking/session/:sessionId", verifyToken, (req, res)
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/matchmaking/session/*/join", (req, res) => {
|
||||
log.debug("POST /fortnite/api/matchmaking/session/*/join called");
|
||||
res.status(204).end();
|
||||
});
|
||||
|
||||
app.post("/fortnite/api/matchmaking/session/matchMakingRequest", (req, res) => {
|
||||
log.debug("POST /fortnite/api/matchmaking/session/matchMakingRequest called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
|
||||
+810
-613
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
const profile = require("./../model/profiles.js")
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
|
||||
|
||||
app.get("/fortnite/api/game/v2/privacy/account/:accountId", verifyToken , async (req, res) => {
|
||||
const profiles = await profile.findOne({ accountId: req.user.accountId });
|
||||
|
||||
if(!profiles) return res.status(400).end();
|
||||
|
||||
res.json({
|
||||
accountId: profiles.accountId,
|
||||
optOutOfPublicLeaderboards: profiles.profiles.athena.stats.attributes.optOutOfPublicLeaderboards
|
||||
}).end();
|
||||
})
|
||||
|
||||
app.post("/fortnite/api/game/v2/privacy/account/:accountId", verifyToken , async (req, res) => {
|
||||
const profiles = await profile.findOne({ accountId: req.user.accountId });
|
||||
|
||||
if(!profiles) return res.status(400).end();
|
||||
|
||||
let profile = profiles.profiles.athena;
|
||||
|
||||
profile.stats.attributes.optOutOfPublicLeaderboards = req.body.optOutOfPublicLeaderboards
|
||||
|
||||
await profiles.updateOne({ $set: { [`profiles.athena`]: profile} });
|
||||
|
||||
res.json({
|
||||
accountId: profiles.accountId,
|
||||
optOutOfPublicLeaderboards: profile.stats.attributes.optOutOfPublicLeaderboards
|
||||
}).end();
|
||||
})
|
||||
|
||||
module.exports = app;
|
||||
@@ -3,17 +3,19 @@ const app = express.Router();
|
||||
const Profile = require("../model/profiles.js");
|
||||
const Friends = require("../model/friends.js");
|
||||
const functions = require("../structs/functions.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
const keychain = require("../responses/keychain.json");
|
||||
|
||||
app.get("/fortnite/api/storefront/v2/catalog", (req, res) => {
|
||||
log.debug("Request to /fortnite/api/storefront/v2/catalog");
|
||||
if (req.headers["user-agent"].includes("2870186")) return res.status(404).end();
|
||||
|
||||
res.json(functions.getItemShop());
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/storefront/v2/gift/check_eligibility/recipient/:recipientId/offer/:offerId", verifyToken, async (req, res) => {
|
||||
log.debug(`Request to /fortnite/api/storefront/v2/gift/check_eligibility/recipient/${req.params.recipientId}/offer/${req.params.offerId}`);
|
||||
const findOfferId = functions.getOfferID(req.params.offerId);
|
||||
if (!findOfferId) return error.createError(
|
||||
"errors.com.epicgames.fortnite.id_invalid",
|
||||
@@ -26,7 +28,7 @@ app.get("/fortnite/api/storefront/v2/gift/check_eligibility/recipient/:recipient
|
||||
if (!sender.list.accepted.find(i => i.accountId == req.params.recipientId) && req.params.recipientId != req.user.accountId) return error.createError(
|
||||
"errors.com.epicgames.friends.no_relationship",
|
||||
`User ${req.user.accountId} is not friends with ${req.params.recipientId}`,
|
||||
[req.user.accountId,req.params.recipientId], 28004, undefined, 403, res
|
||||
[req.user.accountId, req.params.recipientId], 28004, undefined, 403, res
|
||||
);
|
||||
|
||||
const profiles = await Profile.findOne({ accountId: req.params.recipientId });
|
||||
@@ -38,7 +40,7 @@ app.get("/fortnite/api/storefront/v2/gift/check_eligibility/recipient/:recipient
|
||||
if (itemGrant.templateId.toLowerCase() == athena.items[itemId].templateId.toLowerCase()) return error.createError(
|
||||
"errors.com.epicgames.modules.gamesubcatalog.purchase_not_allowed",
|
||||
`Could not purchase catalog offer ${findOfferId.offerId.devName}, item ${itemGrant.templateId}`,
|
||||
[findOfferId.offerId.devName,itemGrant.templateId], 28004, undefined, 403, res
|
||||
[findOfferId.offerId.devName, itemGrant.templateId], 28004, undefined, 403, res
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -50,11 +52,13 @@ app.get("/fortnite/api/storefront/v2/gift/check_eligibility/recipient/:recipient
|
||||
});
|
||||
|
||||
app.get("/fortnite/api/storefront/v2/keychain", (req, res) => {
|
||||
log.debug("Request to /fortnite/api/storefront/v2/keychain");
|
||||
res.json(keychain);
|
||||
});
|
||||
|
||||
app.get("/catalog/api/shared/bulk/offers", (req, res) => {
|
||||
log.debug("Request to /catalog/api/shared/bulk/offers");
|
||||
res.json({});
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
module.exports = app;
|
||||
@@ -2,11 +2,13 @@ const express = require("express");
|
||||
const app = express.Router();
|
||||
|
||||
const error = require("../structs/error.js");
|
||||
const log = require("../structs/log.js");
|
||||
|
||||
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
|
||||
const User = require("../model/user.js");
|
||||
|
||||
app.get("/account/api/public/account", async (req, res) => {
|
||||
log.debug("GET /account/api/public/account called");
|
||||
let response = [];
|
||||
|
||||
if (typeof req.query.accountId == "string") {
|
||||
@@ -41,12 +43,19 @@ app.get("/account/api/public/account", async (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/account/api/public/account/displayName/:displayName", async (req, res) => {
|
||||
log.debug(`GET /account/api/public/account/displayName/${req.params.displayName} called`);
|
||||
let user = await User.findOne({ username_lower: req.params.displayName.toLowerCase(), banned: false }).lean();
|
||||
if (!user) return error.createError(
|
||||
"errors.com.epicgames.account.account_not_found",
|
||||
`Sorry, we couldn't find an account for ${req.params.displayName}`,
|
||||
[req.params.displayName], 18007, undefined, 404, res
|
||||
);
|
||||
|
||||
if (user.isServer == true) return error.createError(
|
||||
"errors.com.epicgames.account.account_not_found",
|
||||
`Sorry, we couldn't find an account for ${req.params.displayName}`,
|
||||
[req.params.displayName], 18007, undefined, 404, res
|
||||
);
|
||||
|
||||
res.json({
|
||||
id: user.accountId,
|
||||
@@ -56,6 +65,7 @@ app.get("/account/api/public/account/displayName/:displayName", async (req, res)
|
||||
});
|
||||
|
||||
app.get("/persona/api/public/account/lookup", async (req, res) => {
|
||||
log.debug("GET /persona/api/public/account/lookup called");
|
||||
if (typeof req.query.q != "string" || !req.query.q) return error.createError(
|
||||
"errors.com.epicgames.bad_request",
|
||||
"Required String parameter 'q' is invalid or not present",
|
||||
@@ -77,6 +87,7 @@ app.get("/persona/api/public/account/lookup", async (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/api/v1/search/:accountId", async (req, res) => {
|
||||
log.debug(`GET /api/v1/search/${req.params.accountId} called`);
|
||||
let response = [];
|
||||
|
||||
if (typeof req.query.prefix != "string" || !req.query.prefix) return error.createError(
|
||||
@@ -108,6 +119,7 @@ app.get("/api/v1/search/:accountId", async (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/account/api/public/account/:accountId", verifyToken, (req, res) => {
|
||||
log.debug(`GET /account/api/public/account/${req.params.accountId} called`);
|
||||
res.json({
|
||||
id: req.user.accountId,
|
||||
displayName: req.user.username,
|
||||
@@ -131,6 +143,7 @@ app.get("/account/api/public/account/:accountId", verifyToken, (req, res) => {
|
||||
});
|
||||
|
||||
app.get("/account/api/public/account/*/externalAuths", (req, res) => {
|
||||
log.debug("GET /account/api/public/account/*/externalAuths called");
|
||||
res.json([]);
|
||||
});
|
||||
|
||||
|
||||
+30
-1
@@ -9,6 +9,7 @@ const User = require("../model/user.js");
|
||||
const Profile = require("../model/profiles.js");
|
||||
const profileManager = require("../structs/profile.js");
|
||||
const Friends = require("../model/friends.js");
|
||||
const SaCCodes = require("../model/saccodes.js");
|
||||
|
||||
async function sleep(ms) {
|
||||
await new Promise((resolve, reject) => {
|
||||
@@ -271,6 +272,7 @@ async function registerUser(discordId, username, email, plainPassword) {
|
||||
if (await User.findOne({ discordId })) return { message: "You already created an account!", status: 400 };
|
||||
|
||||
const accountId = MakeID().replace(/-/ig, "");
|
||||
const matchmakingId = MakeID().replace(/-/ig, "");
|
||||
|
||||
// filters
|
||||
const emailFilter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
|
||||
@@ -289,7 +291,7 @@ async function registerUser(discordId, username, email, plainPassword) {
|
||||
const hashedPassword = await bcrypt.hash(plainPassword, 10);
|
||||
|
||||
try {
|
||||
await User.create({ created: new Date().toISOString(), discordId, accountId, username, username_lower: username.toLowerCase(), email, password: hashedPassword }).then(async (i) => {
|
||||
await User.create({ created: new Date().toISOString(), discordId, accountId, username, username_lower: username.toLowerCase(), email, password: hashedPassword, matchmakingId }).then(async (i) => {
|
||||
await Profile.create({ created: i.created, accountId: i.accountId, profiles: profileManager.createProfiles(i.accountId) });
|
||||
await Friends.create({ created: i.created, accountId: i.accountId });
|
||||
});
|
||||
@@ -302,6 +304,32 @@ async function registerUser(discordId, username, email, plainPassword) {
|
||||
return { message: `Successfully created an account with the username ${username}`, status: 200 };
|
||||
}
|
||||
|
||||
async function createSAC(code, username, creator) {
|
||||
if (!code || !username) return {message: "**Code** or **Ingame Username** is required.", status: 400 };
|
||||
|
||||
const account = await User.findOne({ username })
|
||||
|
||||
if (account == null) return { message: `**${username}** dosent exist!`}
|
||||
|
||||
if (await SaCCodes.findOne({ code })) return { message: `**${code}** already exist!`, status: 400};
|
||||
|
||||
if (await SaCCodes.findOne({ owneraccountId: account.accountId })) return { message: "That User already has an **Code**!", status: 400};
|
||||
const creatorprofile = (await User.findOne({ discordId: creator }))
|
||||
|
||||
const allowedCharacters = ("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~").split("");
|
||||
for (let character of allowedCharacters) {
|
||||
if (!allowedCharacters.includes(character)) return { message: "The Code has special Characters!", status: 400 };
|
||||
}
|
||||
|
||||
try {
|
||||
await SaCCodes.create({ created: new Date().toISOString(), createdby: creatorprofile.accountId, owneraccountId: account.accountId , code, code_lower: code.toLowerCase(), code_higher: code.toUpperCase()})
|
||||
} catch (error) {
|
||||
return { message: error, status: 400}
|
||||
}
|
||||
|
||||
return { message: "You successfully created an **Support a Creator** Code!", status: 200}
|
||||
}
|
||||
|
||||
function DecodeBase64(str) {
|
||||
return Buffer.from(str, 'base64').toString();
|
||||
}
|
||||
@@ -325,6 +353,7 @@ module.exports = {
|
||||
sendXmppMessageToId,
|
||||
getPresenceFromUser,
|
||||
registerUser,
|
||||
createSAC,
|
||||
DecodeBase64,
|
||||
UpdateTokens
|
||||
}
|
||||
+20
-29
@@ -1,46 +1,37 @@
|
||||
function backend() {
|
||||
let msg = "";
|
||||
|
||||
for (let i in backend.arguments) {
|
||||
msg += `${i == "0" ? "" : " "}${backend.arguments[i]}`;
|
||||
}
|
||||
const fs = require("fs");
|
||||
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
|
||||
|
||||
function backend(...args) {
|
||||
let msg = args.join(" ");
|
||||
console.log(`\x1b[32mReload Backend Log\x1b[0m: ${msg}`);
|
||||
}
|
||||
|
||||
function bot() {
|
||||
let msg = "";
|
||||
|
||||
for (let i in bot.arguments) {
|
||||
msg += `${i == "0" ? "" : " "}${bot.arguments[i]}`;
|
||||
}
|
||||
|
||||
function bot(...args) {
|
||||
let msg = args.join(" ");
|
||||
console.log(`\x1b[33mReload Bot Log\x1b[0m: ${msg}`);
|
||||
}
|
||||
|
||||
function xmpp() {
|
||||
let msg = "";
|
||||
|
||||
for (let i in xmpp.arguments) {
|
||||
msg += `${i == "0" ? "" : " "}${xmpp.arguments[i]}`;
|
||||
}
|
||||
|
||||
function xmpp(...args) {
|
||||
let msg = args.join(" ");
|
||||
console.log(`\x1b[34mReload Xmpp Log\x1b[0m: ${msg}`);
|
||||
}
|
||||
|
||||
function error() {
|
||||
let msg = "";
|
||||
|
||||
for (let i in error.arguments) {
|
||||
msg += `${i == "0" ? "" : " "}${error.arguments[i]}`;
|
||||
}
|
||||
|
||||
function error(...args) {
|
||||
let msg = args.join(" ");
|
||||
console.log(`\x1b[31mReload Error Log\x1b[0m: ${msg}`);
|
||||
}
|
||||
|
||||
function debug(...args) {
|
||||
if (config.bEnableDebugLogs === true) {
|
||||
let msg = args.join(" ");
|
||||
console.log(`\x1b[35mReload Debug Log\x1b[0m: ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
backend,
|
||||
bot,
|
||||
xmpp,
|
||||
error
|
||||
}
|
||||
error,
|
||||
debug
|
||||
};
|
||||
Reference in New Issue
Block a user