Preserve tokens after backend restart

This commit is contained in:
Lawin0129
2023-05-14 04:08:44 +01:00
parent b06d6d8d3e
commit df08f68da6
9 changed files with 98 additions and 13 deletions
+3
View File
@@ -1,4 +1,5 @@
const User = require("../../model/user.js");
const functions = require("../../structs/functions.js");
const fs = require("fs");
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
@@ -39,6 +40,8 @@ module.exports = {
if (xmppClient) xmppClient.client.close();
}
if (accessToken != -1 || refreshToken != -1) functions.UpdateTokens();
interaction.editReply({ content: `Successfully banned ${targetUser.username}`, ephemeral: true });
}
}
+6 -1
View File
@@ -1,4 +1,5 @@
const User = require("../../model/user.js");
const functions = require("../../structs/functions.js");
const fs = require("fs");
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
@@ -36,7 +37,11 @@ module.exports = {
if (xmppClient) xmppClient.client.close();
}
if (accessToken != -1 || refreshToken != -1) return interaction.editReply({ content: `Successfully kicked ${targetUser.username}`, ephemeral: true });
if (accessToken != -1 || refreshToken != -1) {
functions.UpdateTokens();
return interaction.editReply({ content: `Successfully kicked ${targetUser.username}`, ephemeral: true });
}
interaction.editReply({ content: `There are no current active sessions by ${targetUser.username}`, ephemeral: true });
}
@@ -1,4 +1,5 @@
const User = require("../../model/user.js");
const functions = require("../../structs/functions.js");
module.exports = {
commandInfo: {
@@ -22,7 +23,11 @@ module.exports = {
if (xmppClient) xmppClient.client.close();
}
if (accessToken != -1 || refreshToken != -1) return interaction.editReply({ content: `Successfully signed out of all sessions!`, ephemeral: true });
if (accessToken != -1 || refreshToken != -1) {
functions.UpdateTokens();
return interaction.editReply({ content: `Successfully signed out of all sessions!`, ephemeral: true });
}
interaction.editReply({ content: `You have no current active sessions.`, ephemeral: true });
}
+25 -3
View File
@@ -3,6 +3,7 @@ const app = express();
const mongoose = require("mongoose");
const fs = require("fs");
const rateLimit = require("express-rate-limit");
const jwt = require("jsonwebtoken");
const config = JSON.parse(fs.readFileSync("./Config/config.json").toString());
const log = require("./structs/log.js");
@@ -14,9 +15,23 @@ if (!fs.existsSync("./ClientSettings")) fs.mkdirSync("./ClientSettings");
global.JWT_SECRET = functions.MakeID();
const PORT = 8080;
global.accessTokens = [];
global.refreshTokens = [];
global.clientTokens = [];
const tokens = JSON.parse(fs.readFileSync("./tokenManager/tokens.json").toString());
for (let tokenType in tokens) {
for (let tokenIndex in tokens[tokenType]) {
let decodedToken = jwt.decode(tokens[tokenType][tokenIndex].token.replace("eg1~", ""));
if (DateAddHours(new Date(decodedToken.creation_date), decodedToken.hours_expire).getTime() <= new Date().getTime()) {
tokens[tokenType].splice(Number(tokenIndex), 1);
}
}
}
fs.writeFileSync("./tokenManager/tokens.json", JSON.stringify(tokens, null, 2));
global.accessTokens = tokens.accessTokens;
global.refreshTokens = tokens.refreshTokens;
global.clientTokens = tokens.clientTokens;
global.exchangeCodes = [];
@@ -58,3 +73,10 @@ app.use((req, res, next) => {
undefined, 1004, undefined, 404, res
);
});
function DateAddHours(pdate, number) {
let date = pdate;
date.setHours(date.getHours() + number);
return date;
}
+16 -2
View File
@@ -35,6 +35,9 @@ app.post("/account/api/oauth/token", async (req, res) => {
if (clientToken != -1) global.clientTokens.splice(clientToken, 1);
const token = tokenCreation.createClient(clientId, req.body.grant_type, ip, 4); // expires in 4 hours
functions.UpdateTokens();
const decodedClient = jwt.decode(token);
res.json({
@@ -84,10 +87,17 @@ app.post("/account/api/oauth/token", async (req, res) => {
try {
if (refreshToken == -1) throw new Error("Refresh token invalid.");
let decodedRefreshToken = jwt.decode(refresh_token.replace("eg1~", ""));
jwt.verify(refresh_token.replace("eg1~", ""), global.JWT_SECRET);
if (DateAddHours(new Date(decodedRefreshToken.creation_date), decodedRefreshToken.hours_expire).getTime() <= new Date().getTime()) {
throw new Error("Expired refresh token.");
}
} catch {
if (refreshToken != -1) global.refreshTokens.splice(refreshToken, 1);
if (refreshToken != -1) {
global.refreshTokens.splice(refreshToken, 1);
functions.UpdateTokens();
}
error.createError(
"errors.com.epicgames.account.auth_token.invalid_refresh_token",
@@ -154,6 +164,8 @@ app.post("/account/api/oauth/token", async (req, res) => {
const accessToken = tokenCreation.createAccess(req.user, clientId, req.body.grant_type, deviceId, 8); // expires in 8 hours
const refreshToken = tokenCreation.createRefresh(req.user, clientId, req.body.grant_type, deviceId, 24); // expires in 24 hours
functions.UpdateTokens();
const decodedAccess = jwt.decode(accessToken);
const decodedRefresh = jwt.decode(refreshToken);
@@ -252,6 +264,8 @@ app.delete("/account/api/oauth/sessions/kill/:token", (req, res) => {
let clientIndex = global.clientTokens.findIndex(i => i.token == token);
if (clientIndex != -1) global.clientTokens.splice(clientIndex, 1);
if (accessIndex != -1 || clientIndex != -1) functions.UpdateTokens();
res.status(204).end();
});
+2 -2
View File
@@ -56,7 +56,7 @@ app.get("/account/api/public/account/displayName/:displayName", async (req, res)
});
app.get("/persona/api/public/account/lookup", async (req, res) => {
if (typeof req.query.q != "string") return error.createError(
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",
undefined, 1001, undefined, 400, res
@@ -79,7 +79,7 @@ app.get("/persona/api/public/account/lookup", async (req, res) => {
app.get("/api/v1/search/:accountId", async (req, res) => {
let response = [];
if (typeof req.query.prefix != "string") return error.createError(
if (typeof req.query.prefix != "string" || !req.query.prefix) return error.createError(
"errors.com.epicgames.bad_request",
"Required String parameter 'prefix' is invalid or not present",
undefined, 1001, undefined, 400, res
+10 -1
View File
@@ -301,6 +301,14 @@ function DecodeBase64(str) {
return Buffer.from(str, 'base64').toString();
}
function UpdateTokens() {
fs.writeFileSync("./tokenManager/tokens.json", JSON.stringify({
accessTokens: global.accessTokens,
refreshTokens: global.refreshTokens,
clientTokens: global.clientTokens
}, null, 2));
}
module.exports = {
sleep,
GetVersionInfo,
@@ -312,5 +320,6 @@ module.exports = {
sendXmppMessageToId,
getPresenceFromUser,
registerUser,
DecodeBase64
DecodeBase64,
UpdateTokens
}
+25 -3
View File
@@ -1,6 +1,7 @@
const jwt = require("jsonwebtoken");
const User = require("../model/user.js");
const functions = require("../structs/functions.js");
const error = require("../structs/error.js");
async function verifyToken(req, res, next) {
@@ -15,10 +16,14 @@ async function verifyToken(req, res, next) {
const token = req.headers["authorization"].replace("bearer eg1~", "");
try {
const decodedToken = jwt.verify(token, global.JWT_SECRET);
const decodedToken = jwt.decode(token);
if (!global.accessTokens.find(i => i.token == `eg1~${token}`)) throw new Error("Invalid token.");
if (DateAddHours(new Date(decodedToken.creation_date), decodedToken.hours_expire).getTime() <= new Date().getTime()) {
throw new Error("Expired access token.");
}
req.user = await User.findOne({ accountId: decodedToken.sub }).lean();
if (req.user.banned) return error.createError(
@@ -30,7 +35,11 @@ async function verifyToken(req, res, next) {
next();
} catch {
let accessIndex = global.accessTokens.findIndex(i => i.token == `eg1~${token}`);
if (accessIndex != -1) global.accessTokens.splice(accessIndex, 1);
if (accessIndex != -1) {
global.accessTokens.splice(accessIndex, 1);
functions.UpdateTokens();
}
return authErr();
}
@@ -48,12 +57,16 @@ async function verifyClient(req, res, next) {
const token = req.headers["authorization"].replace("bearer eg1~", "");
try {
const decodedToken = jwt.verify(token, global.JWT_SECRET);
const decodedToken = jwt.decode(token);
let findAccess = global.accessTokens.find(i => i.token == `eg1~${token}`);
if (!findAccess && !global.clientTokens.find(i => i.token == `eg1~${token}`)) throw new Error("Invalid token.");
if (DateAddHours(new Date(decodedToken.creation_date), decodedToken.hours_expire).getTime() <= new Date().getTime()) {
throw new Error("Expired access/client token.");
}
if (findAccess) {
req.user = await User.findOne({ accountId: decodedToken.sub }).lean();
@@ -71,11 +84,20 @@ async function verifyClient(req, res, next) {
let clientIndex = global.clientTokens.findIndex(i => i.token == `eg1~${token}`);
if (clientIndex != -1) global.clientTokens.splice(clientIndex, 1);
if (accessIndex != -1 || clientIndex != -1) functions.UpdateTokens();
return authErr();
}
}
function DateAddHours(pdate, number) {
let date = pdate;
date.setHours(date.getHours() + number);
return date;
}
module.exports = {
verifyToken,
verifyClient
+5
View File
@@ -0,0 +1,5 @@
{
"accessTokens": [],
"refreshTokens": [],
"clientTokens": []
}