feat: properly implement nonce (#220)

This commit is contained in:
Sainan 2024-05-28 13:45:06 +02:00 committed by GitHub
parent 8eb11007a7
commit 6294a315a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 112 additions and 58 deletions

View File

@ -1,10 +1,11 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { IUpdateGlyphRequest } from "@/src/types/requestTypes"; import { IUpdateGlyphRequest } from "@/src/types/requestTypes";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
const addFriendImageController: RequestHandler = async (req, res) => { const addFriendImageController: RequestHandler = async (req, res) => {
const accountId = req.query.accountId as string; const accountId = await getAccountIdForRequest(req);
const json = getJSONfromString(req.body.toString()) as IUpdateGlyphRequest; const json = getJSONfromString(req.body.toString()) as IUpdateGlyphRequest;
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
inventory.ActiveAvatarImageType = json.AvatarImageType; inventory.ActiveAvatarImageType = json.AvatarImageType;

View File

@ -1,12 +1,13 @@
import { parseString } from "@/src/helpers/general"; import { parseString } from "@/src/helpers/general";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { upgradeMod } from "@/src/services/inventoryService"; import { upgradeMod } from "@/src/services/inventoryService";
import { IArtifactsRequest } from "@/src/types/requestTypes"; import { IArtifactsRequest } from "@/src/types/requestTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const artifactsController: RequestHandler = async (req, res) => { const artifactsController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
try { try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call

View File

@ -6,6 +6,7 @@ import { logger } from "@/src/utils/logger";
import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService"; import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService";
import { IOid } from "@/src/types/commonTypes"; import { IOid } from "@/src/types/commonTypes";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
@ -16,7 +17,7 @@ export interface IClaimCompletedRecipeRequest {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const claimCompletedRecipeController: RequestHandler = async (req, res) => { export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
const claimCompletedRecipeRequest = getJSONfromString(req.body.toString()) as IClaimCompletedRecipeRequest; const claimCompletedRecipeRequest = getJSONfromString(req.body.toString()) as IClaimCompletedRecipeRequest;
const accountId = req.query.accountId as string; const accountId = await getAccountIdForRequest(req);
if (!accountId) throw new Error("no account id"); if (!accountId) throw new Error("no account id");
console.log(claimCompletedRecipeRequest); console.log(claimCompletedRecipeRequest);

View File

@ -1,10 +1,12 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { Guild } from "@/src/models/guildModel"; import { Guild } from "@/src/models/guildModel";
import { ICreateGuildRequest } from "@/src/types/guildTypes"; import { ICreateGuildRequest } from "@/src/types/guildTypes";
const createGuildController: RequestHandler = async (req, res) => { const createGuildController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const payload: ICreateGuildRequest = getJSONfromString(req.body.toString()); const payload: ICreateGuildRequest = getJSONfromString(req.body.toString());
// Create guild on database // Create guild on database
@ -14,7 +16,7 @@ const createGuildController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
// Update inventory // Update inventory
const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); const inventory = await Inventory.findOne({ accountOwnerId: accountId });
if (inventory) { if (inventory) {
// Set GuildId // Set GuildId
inventory.GuildId = guild._id; inventory.GuildId = guild._id;

View File

@ -1,10 +1,11 @@
import { getAccountIdForRequest } from "@/src/services/loginService";
import { updateGeneric } from "@/src/services/inventoryService"; import { updateGeneric } from "@/src/services/inventoryService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const genericUpdateController: RequestHandler = async (request, response) => { const genericUpdateController: RequestHandler = async (request, response) => {
const accountId = request.query.accountId as string; const accountId = await getAccountIdForRequest(request);
const update = getJSONfromString(request.body.toString()); const update = getJSONfromString(request.body.toString());
response.json(await updateGeneric(update, accountId)); response.json(await updateGeneric(update, accountId));
}; };

View File

@ -1,7 +1,7 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
import { parseString } from "@/src/helpers/general";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const getCreditsController: RequestHandler = async (req, res) => { export const getCreditsController: RequestHandler = async (req, res) => {
@ -15,7 +15,7 @@ export const getCreditsController: RequestHandler = async (req, res) => {
return; return;
} }
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
res.json({ res.json({

View File

@ -1,14 +1,12 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { Guild } from "@/src/models/guildModel"; import { Guild } from "@/src/models/guildModel";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { toOid } from "@/src/helpers/inventoryHelpers"; import { toOid } from "@/src/helpers/inventoryHelpers";
const getGuildController: RequestHandler = async (req, res) => { const getGuildController: RequestHandler = async (req, res) => {
if (!req.query.accountId) { const accountId = await getAccountIdForRequest(req);
res.status(400).json({ error: "accountId was not provided" }); const inventory = await Inventory.findOne({ accountOwnerId: accountId });
return;
}
const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId });
if (!inventory) { if (!inventory) {
res.status(400).json({ error: "inventory was undefined" }); res.status(400).json({ error: "inventory was undefined" });
return; return;

View File

@ -1,7 +1,7 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json"; import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json";
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { getPersonalRooms } from "@/src/services/personalRoomsService";
import { getShip } from "@/src/services/shipService"; import { getShip } from "@/src/services/shipService";
import { PersonalRooms } from "@/src/models/personalRoomsModel"; import { PersonalRooms } from "@/src/models/personalRoomsModel";
@ -12,7 +12,7 @@ import { IGetShipResponse } from "@/src/types/shipTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const getShipController: RequestHandler = async (req, res) => { export const getShipController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const personalRooms = await getPersonalRooms(accountId); const personalRooms = await getPersonalRooms(accountId);
const loadout = await getLoadout(accountId); const loadout = await getLoadout(accountId);
const ship = await getShip(personalRooms.activeShipId, "ShipInteriorColors ShipAttachments SkinFlavourItem"); const ship = await getShip(personalRooms.activeShipId, "ShipInteriorColors ShipAttachments SkinFlavourItem");

View File

@ -1,12 +1,14 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { createNewSession } from "@/src/managers/sessionManager"; import { createNewSession } from "@/src/managers/sessionManager";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { ISession } from "@/src/types/session"; import { ISession } from "@/src/types/session";
const hostSessionController: RequestHandler = (req, res) => { const hostSessionController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const hostSessionRequest = JSON.parse(req.body as string) as ISession; const hostSessionRequest = JSON.parse(req.body as string) as ISession;
logger.debug("HostSession Request", { hostSessionRequest }); logger.debug("HostSession Request", { hostSessionRequest });
const session = createNewSession(hostSessionRequest, req.query.accountId as string); const session = createNewSession(hostSessionRequest, accountId);
logger.debug(`New Session Created`, { session }); logger.debug(`New Session Created`, { session });
res.json({ sessionId: { $oid: session.sessionId }, rewardSeed: 99999999 }); res.json({ sessionId: { $oid: session.sessionId }, rewardSeed: 99999999 });

View File

@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/no-misused-promises */ /* eslint-disable @typescript-eslint/no-misused-promises */
import { getAccountIdForRequest } from "@/src/services/loginService";
import { toInventoryResponse } from "@/src/helpers/inventoryHelpers"; import { toInventoryResponse } from "@/src/helpers/inventoryHelpers";
import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { Request, RequestHandler, Response } from "express"; import { Request, RequestHandler, Response } from "express";
@ -11,10 +12,17 @@ import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
import { IShipInventory, IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IShipInventory, IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
const inventoryController: RequestHandler = async (request: Request, response: Response) => { const inventoryController: RequestHandler = async (request: Request, response: Response) => {
const accountId = request.query.accountId; let accountId;
try {
if (!accountId) { accountId = await getAccountIdForRequest(request);
response.status(400).json({ error: "accountId was not provided" }); } catch (e) {
if ((e as Error).message == "Invalid accountId-nonce pair") {
// TODO: Figure out some way to tell the game to stop trying with this nonce.
// For now, we'll have to be a little nasty.
response.destroy();
return;
}
response.status(400).json({ error: (e as Error).message });
return; return;
} }

View File

@ -1,4 +1,4 @@
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { updateCurrency } from "@/src/services/inventoryService"; import { updateCurrency } from "@/src/services/inventoryService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { updateSlots } from "@/src/services/inventoryService"; import { updateSlots } from "@/src/services/inventoryService";
@ -20,7 +20,7 @@ import { SlotNameToInventoryName } from "@/src/types/purchaseTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const inventorySlotsController: RequestHandler = async (req, res) => { export const inventorySlotsController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
//const body = JSON.parse(req.body as string) as IInventorySlotsRequest; //const body = JSON.parse(req.body as string) as IInventorySlotsRequest;
//console.log(body); //console.log(body);

View File

@ -8,7 +8,7 @@ import { toLoginRequest } from "@/src/helpers/loginHelpers";
import { Account } from "@/src/models/loginModel"; import { Account } from "@/src/models/loginModel";
import { createAccount, isCorrectPassword } from "@/src/services/loginService"; import { createAccount, isCorrectPassword } from "@/src/services/loginService";
import { ILoginResponse } from "@/src/types/loginTypes"; import { ILoginResponse } from "@/src/types/loginTypes";
import { DTLS, groups, HUB, Nonce, platformCDNs } from "@/static/fixed_responses/login_static"; import { DTLS, groups, HUB, platformCDNs } from "@/static/fixed_responses/login_static";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
@ -18,6 +18,7 @@ const loginController: RequestHandler = async (request, response) => {
const loginRequest = toLoginRequest(body); const loginRequest = toLoginRequest(body);
const account = await Account.findOne({ email: loginRequest.email }); //{ _id: 0, __v: 0 } const account = await Account.findOne({ email: loginRequest.email }); //{ _id: 0, __v: 0 }
const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER);
if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") { if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") {
try { try {
@ -30,7 +31,8 @@ const loginController: RequestHandler = async (request, response) => {
CrossPlatformAllowed: true, CrossPlatformAllowed: true,
ForceLogoutVersion: 0, ForceLogoutVersion: 0,
ConsentNeeded: false, ConsentNeeded: false,
TrackedSettings: [] TrackedSettings: [],
Nonce: nonce
}); });
logger.debug("created new account"); logger.debug("created new account");
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -39,7 +41,6 @@ const loginController: RequestHandler = async (request, response) => {
...databaseAccount, ...databaseAccount,
Groups: groups, Groups: groups,
platformCDNs: platformCDNs, platformCDNs: platformCDNs,
Nonce: Nonce,
NRS: [config.myAddress], NRS: [config.myAddress],
DTLS: DTLS, DTLS: DTLS,
IRC: [config.myAddress], IRC: [config.myAddress],
@ -63,12 +64,16 @@ const loginController: RequestHandler = async (request, response) => {
return; return;
} }
if (account.Nonce == 0 || loginRequest.ClientType != "webui") {
account.Nonce = nonce;
account.save();
}
const { email, password, ...databaseAccount } = account.toJSON(); const { email, password, ...databaseAccount } = account.toJSON();
const newLoginResponse: ILoginResponse = { const newLoginResponse: ILoginResponse = {
...databaseAccount, ...databaseAccount,
Groups: groups, Groups: groups,
platformCDNs: platformCDNs, platformCDNs: platformCDNs,
Nonce: Nonce,
NRS: [config.myAddress], NRS: [config.myAddress],
DTLS: DTLS, DTLS: DTLS,
IRC: [config.myAddress], IRC: [config.myAddress],

View File

@ -1,6 +1,15 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { Account } from "@/src/models/loginModel";
import { IDatabaseAccountDocument } from "@/src/types/loginTypes";
const logoutController: RequestHandler = (_req, res) => { const logoutController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const account = await Account.findOne({ _id: accountId });
if (account) {
account.Nonce = 0;
account.save();
}
res.writeHead(200, { res.writeHead(200, {
"Content-Type": "text/html", "Content-Type": "text/html",
"Content-Length": 1 "Content-Length": 1

View File

@ -2,7 +2,7 @@ import { RequestHandler } from "express";
import { missionInventoryUpdate } from "@/src/services/inventoryService"; import { missionInventoryUpdate } from "@/src/services/inventoryService";
import { combineRewardAndLootInventory, getRewards } from "@/src/services/missionInventoryUpdateService "; import { combineRewardAndLootInventory, getRewards } from "@/src/services/missionInventoryUpdateService ";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes"; import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes";
/* /*
**** INPUT **** **** INPUT ****
@ -46,7 +46,7 @@ import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const missionInventoryUpdateController: RequestHandler = async (req, res): Promise<void> => { const missionInventoryUpdateController: RequestHandler = async (req, res): Promise<void> => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
try { try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call

View File

@ -1,11 +1,11 @@
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { toPurchaseRequest } from "@/src/helpers/purchaseHelpers"; import { toPurchaseRequest } from "@/src/helpers/purchaseHelpers";
import { handlePurchase } from "@/src/services/purchaseService"; import { handlePurchase } from "@/src/services/purchaseService";
import { Request, Response } from "express"; import { Request, Response } from "express";
export const purchaseController = async (req: Request, res: Response) => { export const purchaseController = async (req: Request, res: Response) => {
const purchaseRequest = toPurchaseRequest(JSON.parse(String(req.body))); const purchaseRequest = toPurchaseRequest(JSON.parse(String(req.body)));
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const response = await handlePurchase(purchaseRequest, accountId); const response = await handlePurchase(purchaseRequest, accountId);
res.json(response); res.json(response);
}; };

View File

@ -1,13 +1,13 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; import { ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes";
import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutService"; import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutService";
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const saveLoadoutController: RequestHandler = async (req, res) => { export const saveLoadoutController: RequestHandler = async (req, res) => {
//validate here //validate here
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
try { try {
const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest;

View File

@ -1,10 +1,12 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { ISellRequest } from "@/src/types/sellTypes"; import { ISellRequest } from "@/src/types/sellTypes";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
export const sellController: RequestHandler = async (req, res) => { export const sellController: RequestHandler = async (req, res) => {
const payload: ISellRequest = JSON.parse(req.body.toString()); const payload: ISellRequest = JSON.parse(req.body.toString());
const inventory = await getInventory(req.query.accountId as string); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId);
// Give currency // Give currency
if (payload.SellCurrency == "SC_RegularCredits") { if (payload.SellCurrency == "SC_RegularCredits") {

View File

@ -1,11 +1,12 @@
import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { getPersonalRooms } from "@/src/services/personalRoomsService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { parseString } from "@/src/helpers/general"; import { parseString } from "@/src/helpers/general";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { Types } from "mongoose"; import { Types } from "mongoose";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const setActiveShipController: RequestHandler = async (req, res) => { export const setActiveShipController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const shipId = parseString(req.query.shipId); const shipId = parseString(req.query.shipId);
const personalRooms = await getPersonalRooms(accountId); const personalRooms = await getPersonalRooms(accountId);

View File

@ -1,9 +1,11 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { getPersonalRooms } from "@/src/services/personalRoomsService";
import { TBootLocation } from "@/src/types/shipTypes"; import { TBootLocation } from "@/src/types/shipTypes";
export const setBootLocationController: RequestHandler = async (req, res) => { export const setBootLocationController: RequestHandler = async (req, res) => {
const personalRooms = await getPersonalRooms(req.query.accountId as string); const accountId = await getAccountIdForRequest(req);
const personalRooms = await getPersonalRooms(accountId);
personalRooms.Ship.BootLocation = req.query.bootLocation as string as TBootLocation; personalRooms.Ship.BootLocation = req.query.bootLocation as string as TBootLocation;
await personalRooms.save(); await personalRooms.save();
res.end(); res.end();

View File

@ -1,8 +1,10 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
export const setSupportedSyndicateController: RequestHandler = async (req, res) => { export const setSupportedSyndicateController: RequestHandler = async (req, res) => {
const inventory = await getInventory(req.query.accountId as string); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId);
inventory.SupportedSyndicate = req.query.syndicate as string; inventory.SupportedSyndicate = req.query.syndicate as string;
await inventory.save(); await inventory.save();
res.end(); res.end();

View File

@ -1,4 +1,4 @@
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { IShipDecorationsRequest } from "@/src/types/shipTypes"; import { IShipDecorationsRequest } from "@/src/types/shipTypes";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
@ -6,7 +6,7 @@ import { handleSetShipDecorations } from "@/src/services/shipCustomizationsServi
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
export const shipDecorationsController: RequestHandler = async (req, res) => { export const shipDecorationsController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const shipDecorationsRequest = JSON.parse(req.body as string) as IShipDecorationsRequest; const shipDecorationsRequest = JSON.parse(req.body as string) as IShipDecorationsRequest;
try { try {

View File

@ -1,4 +1,4 @@
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { startRecipe } from "@/src/services/recipeService"; import { startRecipe } from "@/src/services/recipeService";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
@ -14,7 +14,7 @@ export const startRecipeController: RequestHandler = async (req, res) => {
const startRecipeRequest = getJSONfromString(req.body.toString()) as IStartRecipeRequest; const startRecipeRequest = getJSONfromString(req.body.toString()) as IStartRecipeRequest;
logger.debug("StartRecipe Request", { startRecipeRequest }); logger.debug("StartRecipe Request", { startRecipeRequest });
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const newRecipeId = await startRecipe(startRecipeRequest.RecipeName, accountId); const newRecipeId = await startRecipe(startRecipeRequest.RecipeName, accountId);
res.json(newRecipeId); res.json(newRecipeId);

View File

@ -1,4 +1,4 @@
import { parseString } from "@/src/helpers/general"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
import { IMongoDate } from "@/src/types/commonTypes"; import { IMongoDate } from "@/src/types/commonTypes";
@ -17,7 +17,7 @@ interface ITrainingResultsResponse {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const trainingResultController: RequestHandler = async (req, res): Promise<void> => { const trainingResultController: RequestHandler = async (req, res): Promise<void> => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const trainingResults = getJSONfromString(req.body.toString()) as ITrainingResultsRequest; const trainingResults = getJSONfromString(req.body.toString()) as ITrainingResultsRequest;

View File

@ -1,3 +1,4 @@
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { updateTheme } from "@/src/services/inventoryService"; import { updateTheme } from "@/src/services/inventoryService";
import { IThemeUpdateRequest } from "@/src/types/requestTypes"; import { IThemeUpdateRequest } from "@/src/types/requestTypes";
@ -5,7 +6,7 @@ import { RequestHandler } from "express";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const updateThemeController: RequestHandler = async (request, response) => { const updateThemeController: RequestHandler = async (request, response) => {
const accountId = request.query.accountId as string; const accountId = await getAccountIdForRequest(request);
const body = String(request.body); const body = String(request.body);
try { try {

View File

@ -2,10 +2,11 @@ import { RequestHandler } from "express";
import { IUpgradesRequest } from "@/src/types/requestTypes"; import { IUpgradesRequest } from "@/src/types/requestTypes";
import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { IGenericItemDatabase, IMiscItem, TGenericItemKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericItemDatabase, IMiscItem, TGenericItemKey } from "@/src/types/inventoryTypes/inventoryTypes";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
export const upgradesController: RequestHandler = async (req, res) => { export const upgradesController: RequestHandler = async (req, res) => {
const accountId = req.query.accountId as string; const accountId = await getAccountIdForRequest(req);
const payload = JSON.parse(req.body.toString()) as IUpgradesRequest; const payload = JSON.parse(req.body.toString()) as IUpgradesRequest;
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
const InventoryChanges: any = {}; const InventoryChanges: any = {};

View File

@ -1,4 +1,5 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { IStatsView } from "@/src/types/statTypes"; import { IStatsView } from "@/src/types/statTypes";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
@ -6,10 +7,7 @@ import view from "@/static/fixed_responses/view.json";
import allScans from "@/static/fixed_responses/allScans.json"; import allScans from "@/static/fixed_responses/allScans.json";
const viewController: RequestHandler = async (req, res) => { const viewController: RequestHandler = async (req, res) => {
if (!req.query.accountId) { const accountId = await getAccountIdForRequest(req);
res.status(400).json({ error: "accountId was not provided" });
return;
}
const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId });
if (!inventory) { if (!inventory) {
res.status(400).json({ error: "inventory was undefined" }); res.status(400).json({ error: "inventory was undefined" });

View File

@ -47,7 +47,8 @@ const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount =>
ConsentNeeded: false, ConsentNeeded: false,
CrossPlatformAllowed: true, CrossPlatformAllowed: true,
ForceLogoutVersion: 0, ForceLogoutVersion: 0,
TrackedSettings: [] TrackedSettings: [],
Nonce: 0
} satisfies IDatabaseAccount; } satisfies IDatabaseAccount;
}; };

View File

@ -32,7 +32,8 @@ const databaseAccountSchema = new Schema<IDatabaseAccountDocument>(
AmazonAuthToken: { type: String }, AmazonAuthToken: { type: String },
AmazonRefreshToken: { type: String }, AmazonRefreshToken: { type: String },
ConsentNeeded: { type: Boolean, required: true }, ConsentNeeded: { type: Boolean, required: true },
TrackedSettings: { type: [String], default: [] } TrackedSettings: { type: [String], default: [] },
Nonce: { type: Number, required: true }
}, },
opts opts
); );

View File

@ -6,12 +6,13 @@ import { Types } from "mongoose";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
import { PersonalRooms } from "@/src/models/personalRoomsModel"; import { PersonalRooms } from "@/src/models/personalRoomsModel";
import new_personal_rooms from "@/static/fixed_responses/personalRooms.json"; import new_personal_rooms from "@/static/fixed_responses/personalRooms.json";
import { Request } from "express";
const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => { export const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => {
return requestPassword === databasePassword; return requestPassword === databasePassword;
}; };
const createAccount = async (accountData: IDatabaseAccount) => { export const createAccount = async (accountData: IDatabaseAccount) => {
const account = new Account(accountData); const account = new Account(accountData);
try { try {
await account.save(); await account.save();
@ -28,8 +29,6 @@ const createAccount = async (accountData: IDatabaseAccount) => {
} }
}; };
export { isCorrectPassword, createAccount };
export const createLoadout = async (accountId: Types.ObjectId) => { export const createLoadout = async (accountId: Types.ObjectId) => {
const loadout = new Loadout({ loadoutOwnerId: accountId }); const loadout = new Loadout({ loadoutOwnerId: accountId });
const savedLoadout = await loadout.save(); const savedLoadout = await loadout.save();
@ -44,3 +43,23 @@ export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Typ
}); });
await personalRooms.save(); await personalRooms.save();
}; };
export const getAccountIdForRequest = async (req: Request): Promise<string> => {
if (!req.query.accountId) {
throw new Error("Request is missing accountId parameter");
}
if (!req.query.nonce || parseInt(req.query.nonce as string) === 0) {
throw new Error("Request is missing nonce parameter");
}
const account = await Account.findOne(
{
_id: req.query.accountId,
Nonce: req.query.nonce
},
"_id"
);
if (!account) {
throw new Error("Invalid accountId-nonce pair");
}
return account._id.toString();
};

View File

@ -1,6 +1,5 @@
export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> { export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> {
Groups: IGroup[]; Groups: IGroup[];
Nonce: number;
BuildLabel: string; BuildLabel: string;
MatchmakingBuildId: string; MatchmakingBuildId: string;
platformCDNs: string[]; platformCDNs: string[];
@ -32,6 +31,7 @@ export interface IDatabaseAccount {
AmazonRefreshToken?: string; AmazonRefreshToken?: string;
ConsentNeeded: boolean; ConsentNeeded: boolean;
TrackedSettings: string[]; TrackedSettings: string[];
Nonce: number;
} }
export interface ILoginRequest { export interface ILoginRequest {

View File

@ -22,8 +22,6 @@ export const platformCDNs = [
"https://content-mob.warframe.com/" "https://content-mob.warframe.com/"
]; ];
export const Nonce = 1231231233;
export const DTLS = 99; export const DTLS = 99;
export const HUB = "https://arbiter.warframe.com/api/"; export const HUB = "https://arbiter.warframe.com/api/";