security fix

This commit is contained in:
Moyasee
2025-09-19 17:15:59 +03:00
parent f4e84e46cc
commit 672ddff9f8
7 changed files with 31 additions and 17 deletions

View File

@@ -10,14 +10,15 @@ const saveGameShopAssets = async (
): Promise<void> => {
const key = levelKeys.game(shop, objectId);
const existingAssets = await gamesShopAssetsSublevel.get(key);
// Preserve existing title if it differs from the incoming title (indicating it was customized)
const shouldPreserveTitle = existingAssets?.title && existingAssets.title !== assets.title;
return gamesShopAssetsSublevel.put(key, {
...existingAssets,
const shouldPreserveTitle =
existingAssets?.title && existingAssets.title !== assets.title;
return gamesShopAssetsSublevel.put(key, {
...existingAssets,
...assets,
title: shouldPreserveTitle ? existingAssets.title : assets.title
title: shouldPreserveTitle ? existingAssets.title : assets.title,
});
};

View File

@@ -24,7 +24,8 @@ const getLibrary = async (): Promise<LibraryGame[]> => {
download: download ?? null,
...gameAssets,
// Ensure compatibility with LibraryGame type
libraryHeroImageUrl: game.libraryHeroImageUrl ?? gameAssets?.libraryHeroImageUrl,
libraryHeroImageUrl:
game.libraryHeroImageUrl ?? gameAssets?.libraryHeroImageUrl,
} as LibraryGame;
})
);

View File

@@ -21,9 +21,16 @@ const updateGameCustomAssets = async (
const updatedGame = {
...existingGame,
title,
customIconUrl: customIconUrl !== undefined ? customIconUrl : existingGame.customIconUrl,
customLogoImageUrl: customLogoImageUrl !== undefined ? customLogoImageUrl : existingGame.customLogoImageUrl,
customHeroImageUrl: customHeroImageUrl !== undefined ? customHeroImageUrl : existingGame.customHeroImageUrl,
customIconUrl:
customIconUrl !== undefined ? customIconUrl : existingGame.customIconUrl,
customLogoImageUrl:
customLogoImageUrl !== undefined
? customLogoImageUrl
: existingGame.customLogoImageUrl,
customHeroImageUrl:
customHeroImageUrl !== undefined
? customHeroImageUrl
: existingGame.customHeroImageUrl,
};
await gamesSublevel.put(gameKey, updatedGame);
@@ -42,4 +49,4 @@ const updateGameCustomAssets = async (
return updatedGame;
};
registerEvent("updateGameCustomAssets", updateGameCustomAssets);
registerEvent("updateGameCustomAssets", updateGameCustomAssets);

View File

@@ -69,8 +69,9 @@ app.whenReady().then(async () => {
request.url.slice("gradient:".length)
);
// Fixed regex to prevent ReDoS - removed nested quantifiers and backtracking
const match = gradientCss.match(
/linear-gradient\(([^,]+),\s*([^,]+),\s*([^)]+)\)/
/^linear-gradient\(([^,()]+),\s*([^,()]+),\s*([^,()]+)\)$/
);
let direction = "45deg";

View File

@@ -120,7 +120,7 @@ export function GameDetailsContent() {
}, [getGameArtifacts]);
const isCustomGame = game?.shop === "custom";
// Helper function to get image with custom asset priority
const getImageWithCustomPriority = (
customUrl: string | null | undefined,
@@ -136,7 +136,7 @@ export function GameDetailsContent() {
game?.customHeroImageUrl,
shopDetails?.assets?.libraryHeroImageUrl
);
const logoImage = isCustomGame
? game?.logoImageUrl || ""
: getImageWithCustomPriority(
@@ -181,7 +181,11 @@ export function GameDetailsContent() {
<button
type="button"
className="game-details__edit-custom-game-button"
onClick={game?.shop === "custom" ? handleEditCustomGameClick : handleEditGameClick}
onClick={
game?.shop === "custom"
? handleEditCustomGameClick
: handleEditGameClick
}
title={t("edit_custom_game")}
>
<PencilIcon size={16} />

View File

@@ -44,4 +44,4 @@
.edit-game-modal__actions button {
min-width: 100px;
}
}

View File

@@ -364,4 +364,4 @@ export function EditGameModal({
</div>
</Modal>
);
}
}