diff --git a/controllers/games.js b/controllers/games.js index 530ef6b..4682672 100644 --- a/controllers/games.js +++ b/controllers/games.js @@ -4,6 +4,7 @@ import Game from "../models/Game.js"; import steamScraper from "../scripts/scraper.js"; import asyncHandler from "../middleware/async.js"; import ErrorResponse from "../utils/errorResponse.js"; +import normalizeSteamId from "../utils/normalizeSteamId.js"; import { decode, isValid } from "js-base64"; const checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); @@ -77,11 +78,16 @@ export const show = asyncHandler(async (req, res, next) => { */ export const create = asyncHandler(async (req, res, next) => { let oldGame; - let steamId; - if (req.body.steamId.includes("store.steampowered.com")) - steamId = req.body.steamId.match(/\d+/)[0]; - else steamId = req.body.steamId; + const steamId = normalizeSteamId(req.body.steamId); + if (steamId === null) + return next( + new ErrorResponse( + "Enter a Steam app ID or a store.steampowered.com URL.", + 400, + ), + ); + req.body.steamId = steamId; if (req.body.shortDesc && isValid(req.body.shortDesc)) req.body.shortDesc = decode(req.body.shortDesc); @@ -166,6 +172,14 @@ export const create = asyncHandler(async (req, res, next) => { const data = req.body.scrape === true ? await steamScraper(req.body) : req.body; + if ( + req.body.scrape === true && + (!data || typeof data !== "object" || !data.title || !data.frontImage) + ) + return next( + new ErrorResponse("Steam lookup failed for that ID/URL.", 400), + ); + const game = await Game.create(data); res.status(200).json({ diff --git a/utils/normalizeSteamId.js b/utils/normalizeSteamId.js new file mode 100644 index 0000000..909dc6c --- /dev/null +++ b/utils/normalizeSteamId.js @@ -0,0 +1,24 @@ +/** + * normalizeSteamId() + * + * @description Accepts either a plain numeric Steam app ID or a + * store.steampowered.com URL and returns the numeric app ID. + * Returns "" when the input is empty/missing (manual non-scrape flow + * looks games up by title instead) and `null` when the input is + * neither digits nor a recognized Steam Store URL. + */ +const normalizeSteamId = (value) => { + const raw = String(value ?? "").trim(); + if (!raw) return ""; + + const urlMatch = raw.match( + /store\.steampowered\.com\/(?:agecheck\/)?app\/(\d+)/, + ); + if (urlMatch) return urlMatch[1]; + + if (/^\d+$/.test(raw)) return raw; + + return null; +}; + +export default normalizeSteamId;