diff --git a/src/controllers/api/addFriendImageController.ts b/src/controllers/api/addFriendImageController.ts index a5a164c6..979bb9fb 100644 --- a/src/controllers/api/addFriendImageController.ts +++ b/src/controllers/api/addFriendImageController.ts @@ -1,10 +1,11 @@ import { RequestHandler } from "express"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { IUpdateGlyphRequest } from "@/src/types/requestTypes"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; 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 inventory = await getInventory(accountId); inventory.ActiveAvatarImageType = json.AvatarImageType; diff --git a/src/controllers/api/artifactsController.ts b/src/controllers/api/artifactsController.ts index a56c586c..65041eca 100644 --- a/src/controllers/api/artifactsController.ts +++ b/src/controllers/api/artifactsController.ts @@ -1,12 +1,13 @@ import { parseString } from "@/src/helpers/general"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { upgradeMod } from "@/src/services/inventoryService"; import { IArtifactsRequest } from "@/src/types/requestTypes"; import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const artifactsController: RequestHandler = async (req, res) => { - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); try { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index 37a8536b..291516ef 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -6,6 +6,7 @@ import { logger } from "@/src/utils/logger"; import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService"; import { IOid } from "@/src/types/commonTypes"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; @@ -16,7 +17,7 @@ export interface IClaimCompletedRecipeRequest { // eslint-disable-next-line @typescript-eslint/no-misused-promises export const claimCompletedRecipeController: RequestHandler = async (req, res) => { 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"); console.log(claimCompletedRecipeRequest); diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index 88cace67..f0f56f1b 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -1,10 +1,12 @@ import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; import { ICreateGuildRequest } from "@/src/types/guildTypes"; const createGuildController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); const payload: ICreateGuildRequest = getJSONfromString(req.body.toString()); // Create guild on database @@ -14,7 +16,7 @@ const createGuildController: RequestHandler = async (req, res) => { await guild.save(); // Update inventory - const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); + const inventory = await Inventory.findOne({ accountOwnerId: accountId }); if (inventory) { // Set GuildId inventory.GuildId = guild._id; diff --git a/src/controllers/api/genericUpdateController.ts b/src/controllers/api/genericUpdateController.ts index 4e96ac6e..f2d29fc1 100644 --- a/src/controllers/api/genericUpdateController.ts +++ b/src/controllers/api/genericUpdateController.ts @@ -1,10 +1,11 @@ +import { getAccountIdForRequest } from "@/src/services/loginService"; import { updateGeneric } from "@/src/services/inventoryService"; import { RequestHandler } from "express"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const genericUpdateController: RequestHandler = async (request, response) => { - const accountId = request.query.accountId as string; + const accountId = await getAccountIdForRequest(request); const update = getJSONfromString(request.body.toString()); response.json(await updateGeneric(update, accountId)); }; diff --git a/src/controllers/api/getCreditsController.ts b/src/controllers/api/getCreditsController.ts index e7be097e..e6b88241 100644 --- a/src/controllers/api/getCreditsController.ts +++ b/src/controllers/api/getCreditsController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { config } from "@/src/services/configService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; -import { parseString } from "@/src/helpers/general"; // eslint-disable-next-line @typescript-eslint/no-misused-promises export const getCreditsController: RequestHandler = async (req, res) => { @@ -15,7 +15,7 @@ export const getCreditsController: RequestHandler = async (req, res) => { return; } - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); res.json({ diff --git a/src/controllers/api/getGuildController.ts b/src/controllers/api/getGuildController.ts index a91bf5dd..d112f996 100644 --- a/src/controllers/api/getGuildController.ts +++ b/src/controllers/api/getGuildController.ts @@ -1,14 +1,12 @@ import { RequestHandler } from "express"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { toOid } from "@/src/helpers/inventoryHelpers"; const getGuildController: RequestHandler = async (req, res) => { - if (!req.query.accountId) { - res.status(400).json({ error: "accountId was not provided" }); - return; - } - const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); + const accountId = await getAccountIdForRequest(req); + const inventory = await Inventory.findOne({ accountOwnerId: accountId }); if (!inventory) { res.status(400).json({ error: "inventory was undefined" }); return; diff --git a/src/controllers/api/getShipController.ts b/src/controllers/api/getShipController.ts index de89bdc1..3459548e 100644 --- a/src/controllers/api/getShipController.ts +++ b/src/controllers/api/getShipController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { config } from "@/src/services/configService"; 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 { getShip } from "@/src/services/shipService"; 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 export const getShipController: RequestHandler = async (req, res) => { - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); const personalRooms = await getPersonalRooms(accountId); const loadout = await getLoadout(accountId); const ship = await getShip(personalRooms.activeShipId, "ShipInteriorColors ShipAttachments SkinFlavourItem"); diff --git a/src/controllers/api/hostSessionController.ts b/src/controllers/api/hostSessionController.ts index 7adaee90..1745d994 100644 --- a/src/controllers/api/hostSessionController.ts +++ b/src/controllers/api/hostSessionController.ts @@ -1,12 +1,14 @@ import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { createNewSession } from "@/src/managers/sessionManager"; import { logger } from "@/src/utils/logger"; 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; 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 }); res.json({ sessionId: { $oid: session.sessionId }, rewardSeed: 99999999 }); diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 4f64314a..22a0e3d3 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ +import { getAccountIdForRequest } from "@/src/services/loginService"; import { toInventoryResponse } from "@/src/helpers/inventoryHelpers"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Request, RequestHandler, Response } from "express"; @@ -11,10 +12,17 @@ import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { IShipInventory, IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes"; const inventoryController: RequestHandler = async (request: Request, response: Response) => { - const accountId = request.query.accountId; - - if (!accountId) { - response.status(400).json({ error: "accountId was not provided" }); + let accountId; + try { + accountId = await getAccountIdForRequest(request); + } 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; } diff --git a/src/controllers/api/inventorySlotsController.ts b/src/controllers/api/inventorySlotsController.ts index 52976e15..fc3c68a7 100644 --- a/src/controllers/api/inventorySlotsController.ts +++ b/src/controllers/api/inventorySlotsController.ts @@ -1,4 +1,4 @@ -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { updateCurrency } from "@/src/services/inventoryService"; import { RequestHandler } from "express"; 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 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; //console.log(body); diff --git a/src/controllers/api/loginController.ts b/src/controllers/api/loginController.ts index 17481713..4b0dc26b 100644 --- a/src/controllers/api/loginController.ts +++ b/src/controllers/api/loginController.ts @@ -8,7 +8,7 @@ import { toLoginRequest } from "@/src/helpers/loginHelpers"; import { Account } from "@/src/models/loginModel"; import { createAccount, isCorrectPassword } from "@/src/services/loginService"; 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"; // eslint-disable-next-line @typescript-eslint/no-misused-promises @@ -18,6 +18,7 @@ const loginController: RequestHandler = async (request, response) => { const loginRequest = toLoginRequest(body); 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") { try { @@ -30,7 +31,8 @@ const loginController: RequestHandler = async (request, response) => { CrossPlatformAllowed: true, ForceLogoutVersion: 0, ConsentNeeded: false, - TrackedSettings: [] + TrackedSettings: [], + Nonce: nonce }); logger.debug("created new account"); // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -39,7 +41,6 @@ const loginController: RequestHandler = async (request, response) => { ...databaseAccount, Groups: groups, platformCDNs: platformCDNs, - Nonce: Nonce, NRS: [config.myAddress], DTLS: DTLS, IRC: [config.myAddress], @@ -63,12 +64,16 @@ const loginController: RequestHandler = async (request, response) => { return; } + if (account.Nonce == 0 || loginRequest.ClientType != "webui") { + account.Nonce = nonce; + account.save(); + } + const { email, password, ...databaseAccount } = account.toJSON(); const newLoginResponse: ILoginResponse = { ...databaseAccount, Groups: groups, platformCDNs: platformCDNs, - Nonce: Nonce, NRS: [config.myAddress], DTLS: DTLS, IRC: [config.myAddress], diff --git a/src/controllers/api/logoutController.ts b/src/controllers/api/logoutController.ts index 6dab1cc8..16181d7f 100644 --- a/src/controllers/api/logoutController.ts +++ b/src/controllers/api/logoutController.ts @@ -1,6 +1,15 @@ 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, { "Content-Type": "text/html", "Content-Length": 1 diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index e53ff359..79b4632e 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -2,7 +2,7 @@ import { RequestHandler } from "express"; import { missionInventoryUpdate } from "@/src/services/inventoryService"; import { combineRewardAndLootInventory, getRewards } from "@/src/services/missionInventoryUpdateService "; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes"; /* **** INPUT **** @@ -46,7 +46,7 @@ import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const missionInventoryUpdateController: RequestHandler = async (req, res): Promise => { - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); try { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call diff --git a/src/controllers/api/purchaseController.ts b/src/controllers/api/purchaseController.ts index c0c34e47..cf32a95d 100644 --- a/src/controllers/api/purchaseController.ts +++ b/src/controllers/api/purchaseController.ts @@ -1,11 +1,11 @@ -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { toPurchaseRequest } from "@/src/helpers/purchaseHelpers"; import { handlePurchase } from "@/src/services/purchaseService"; import { Request, Response } from "express"; export const purchaseController = async (req: Request, res: Response) => { 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); res.json(response); }; diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 3942a3ea..e5c180ed 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,13 +1,13 @@ import { RequestHandler } from "express"; import { ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutService"; -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { logger } from "@/src/utils/logger"; // eslint-disable-next-line @typescript-eslint/no-misused-promises export const saveLoadoutController: RequestHandler = async (req, res) => { //validate here - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); try { const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; diff --git a/src/controllers/api/sellController.ts b/src/controllers/api/sellController.ts index c80dfb7a..0eb9fc46 100644 --- a/src/controllers/api/sellController.ts +++ b/src/controllers/api/sellController.ts @@ -1,10 +1,12 @@ import { RequestHandler } from "express"; import { ISellRequest } from "@/src/types/sellTypes"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; export const sellController: RequestHandler = async (req, res) => { 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 if (payload.SellCurrency == "SC_RegularCredits") { diff --git a/src/controllers/api/setActiveShipController.ts b/src/controllers/api/setActiveShipController.ts index 2b7f7868..eec3e8f4 100644 --- a/src/controllers/api/setActiveShipController.ts +++ b/src/controllers/api/setActiveShipController.ts @@ -1,11 +1,12 @@ import { getPersonalRooms } from "@/src/services/personalRoomsService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { parseString } from "@/src/helpers/general"; import { RequestHandler } from "express"; import { Types } from "mongoose"; // eslint-disable-next-line @typescript-eslint/no-misused-promises 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 personalRooms = await getPersonalRooms(accountId); diff --git a/src/controllers/api/setBootLocationController.ts b/src/controllers/api/setBootLocationController.ts index 62fcd680..599044a0 100644 --- a/src/controllers/api/setBootLocationController.ts +++ b/src/controllers/api/setBootLocationController.ts @@ -1,9 +1,11 @@ import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { TBootLocation } from "@/src/types/shipTypes"; 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; await personalRooms.save(); res.end(); diff --git a/src/controllers/api/setSupportedSyndicateController.ts b/src/controllers/api/setSupportedSyndicateController.ts index 78ef26f3..e22b659f 100644 --- a/src/controllers/api/setSupportedSyndicateController.ts +++ b/src/controllers/api/setSupportedSyndicateController.ts @@ -1,8 +1,10 @@ import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; 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; await inventory.save(); res.end(); diff --git a/src/controllers/api/shipDecorationsController.ts b/src/controllers/api/shipDecorationsController.ts index 97230d5e..414bd5a2 100644 --- a/src/controllers/api/shipDecorationsController.ts +++ b/src/controllers/api/shipDecorationsController.ts @@ -1,4 +1,4 @@ -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { IShipDecorationsRequest } from "@/src/types/shipTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; @@ -6,7 +6,7 @@ import { handleSetShipDecorations } from "@/src/services/shipCustomizationsServi // eslint-disable-next-line @typescript-eslint/no-misused-promises 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; try { diff --git a/src/controllers/api/startRecipeController.ts b/src/controllers/api/startRecipeController.ts index 1ce3da22..5f770476 100644 --- a/src/controllers/api/startRecipeController.ts +++ b/src/controllers/api/startRecipeController.ts @@ -1,4 +1,4 @@ -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { startRecipe } from "@/src/services/recipeService"; 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; logger.debug("StartRecipe Request", { startRecipeRequest }); - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); const newRecipeId = await startRecipe(startRecipeRequest.RecipeName, accountId); res.json(newRecipeId); diff --git a/src/controllers/api/trainingResultController.ts b/src/controllers/api/trainingResultController.ts index 09aa0fc6..fcfe6734 100644 --- a/src/controllers/api/trainingResultController.ts +++ b/src/controllers/api/trainingResultController.ts @@ -1,4 +1,4 @@ -import { parseString } from "@/src/helpers/general"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory } from "@/src/services/inventoryService"; import { IMongoDate } from "@/src/types/commonTypes"; @@ -17,7 +17,7 @@ interface ITrainingResultsResponse { // eslint-disable-next-line @typescript-eslint/no-misused-promises const trainingResultController: RequestHandler = async (req, res): Promise => { - const accountId = parseString(req.query.accountId); + const accountId = await getAccountIdForRequest(req); const trainingResults = getJSONfromString(req.body.toString()) as ITrainingResultsRequest; diff --git a/src/controllers/api/updateThemeController.ts b/src/controllers/api/updateThemeController.ts index 5da05cb3..3736aa60 100644 --- a/src/controllers/api/updateThemeController.ts +++ b/src/controllers/api/updateThemeController.ts @@ -1,3 +1,4 @@ +import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { updateTheme } from "@/src/services/inventoryService"; import { IThemeUpdateRequest } from "@/src/types/requestTypes"; @@ -5,7 +6,7 @@ import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const updateThemeController: RequestHandler = async (request, response) => { - const accountId = request.query.accountId as string; + const accountId = await getAccountIdForRequest(request); const body = String(request.body); try { diff --git a/src/controllers/api/upgradesController.ts b/src/controllers/api/upgradesController.ts index 1b18511f..f617b70a 100644 --- a/src/controllers/api/upgradesController.ts +++ b/src/controllers/api/upgradesController.ts @@ -2,10 +2,11 @@ import { RequestHandler } from "express"; import { IUpgradesRequest } from "@/src/types/requestTypes"; import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IGenericItemDatabase, IMiscItem, TGenericItemKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; 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 inventory = await getInventory(accountId); const InventoryChanges: any = {}; diff --git a/src/controllers/stats/viewController.ts b/src/controllers/stats/viewController.ts index 374c0d8e..2e014507 100644 --- a/src/controllers/stats/viewController.ts +++ b/src/controllers/stats/viewController.ts @@ -1,4 +1,5 @@ import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { IStatsView } from "@/src/types/statTypes"; 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"; const viewController: RequestHandler = async (req, res) => { - if (!req.query.accountId) { - res.status(400).json({ error: "accountId was not provided" }); - return; - } + const accountId = await getAccountIdForRequest(req); const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); if (!inventory) { res.status(400).json({ error: "inventory was undefined" }); diff --git a/src/helpers/customHelpers/customHelpers.ts b/src/helpers/customHelpers/customHelpers.ts index d96c7680..cb4d154a 100644 --- a/src/helpers/customHelpers/customHelpers.ts +++ b/src/helpers/customHelpers/customHelpers.ts @@ -47,7 +47,8 @@ const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount => ConsentNeeded: false, CrossPlatformAllowed: true, ForceLogoutVersion: 0, - TrackedSettings: [] + TrackedSettings: [], + Nonce: 0 } satisfies IDatabaseAccount; }; diff --git a/src/models/loginModel.ts b/src/models/loginModel.ts index b21c5906..d100e4c2 100644 --- a/src/models/loginModel.ts +++ b/src/models/loginModel.ts @@ -32,7 +32,8 @@ const databaseAccountSchema = new Schema( AmazonAuthToken: { type: String }, AmazonRefreshToken: { type: String }, ConsentNeeded: { type: Boolean, required: true }, - TrackedSettings: { type: [String], default: [] } + TrackedSettings: { type: [String], default: [] }, + Nonce: { type: Number, required: true } }, opts ); diff --git a/src/services/loginService.ts b/src/services/loginService.ts index aa74732c..3ddb7982 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -6,12 +6,13 @@ import { Types } from "mongoose"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { PersonalRooms } from "@/src/models/personalRoomsModel"; 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; }; -const createAccount = async (accountData: IDatabaseAccount) => { +export const createAccount = async (accountData: IDatabaseAccount) => { const account = new Account(accountData); try { await account.save(); @@ -28,8 +29,6 @@ const createAccount = async (accountData: IDatabaseAccount) => { } }; -export { isCorrectPassword, createAccount }; - export const createLoadout = async (accountId: Types.ObjectId) => { const loadout = new Loadout({ loadoutOwnerId: accountId }); const savedLoadout = await loadout.save(); @@ -44,3 +43,23 @@ export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Typ }); await personalRooms.save(); }; + +export const getAccountIdForRequest = async (req: Request): Promise => { + 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(); +}; diff --git a/src/types/loginTypes.ts b/src/types/loginTypes.ts index 472a5d5f..f5dcfaf6 100644 --- a/src/types/loginTypes.ts +++ b/src/types/loginTypes.ts @@ -1,6 +1,5 @@ export interface ILoginResponse extends Omit { Groups: IGroup[]; - Nonce: number; BuildLabel: string; MatchmakingBuildId: string; platformCDNs: string[]; @@ -32,6 +31,7 @@ export interface IDatabaseAccount { AmazonRefreshToken?: string; ConsentNeeded: boolean; TrackedSettings: string[]; + Nonce: number; } export interface ILoginRequest { diff --git a/static/fixed_responses/login_static.ts b/static/fixed_responses/login_static.ts index ef6213a9..d5e5ea1a 100644 --- a/static/fixed_responses/login_static.ts +++ b/static/fixed_responses/login_static.ts @@ -22,8 +22,6 @@ export const platformCDNs = [ "https://content-mob.warframe.com/" ]; -export const Nonce = 1231231233; - export const DTLS = 99; export const HUB = "https://arbiter.warframe.com/api/";