Skip to content

Conversation

Copy link

Copilot AI commented Sep 3, 2025

This PR refactors the Power User Script to prepare for integration with the official openfoodfacts-js library by creating a clean abstraction layer for API interactions.

Changes Made

API Abstraction Layer

  • Added OFFApiHelpers utility object that centralizes all API interactions
  • Replaced manual API calls with helper functions that mirror the openfoodfacts-js API structure
  • Standardized URL building using centralized helper functions
  • Improved barcode handling with validation and extraction utilities

Code Improvements

  • Centralized product API calls: OFFApiHelpers.getProduct() and getProductImages()
  • Unified URL construction: buildProductUrls() generates view, edit, API, and image URLs consistently
  • Enhanced barcode utilities: formatBarcode() and extractBarcodeFromUrl() with validation
  • Domain detection: getCurrentDomain() automatically detects country and language settings

Before/After Examples

Before (manual API calls):

var _productUrl = "/api/v2/product/" + barcode + ".json?fields=images";
$.getJSON(_productUrl, function(productData) { ... });

After (using helpers):

OFFApiHelpers.getProductImages(barcode).done(function(productData) { ... });

Future Integration Path

The helper functions are designed to be easily replaceable with openfoodfacts-js library calls:

  • OFFApiHelpers.getProduct()offClient.getProductV2()
  • OFFApiHelpers.getProductImages()offClient.getProductV2(barcode, "images")
  • URL builders → Library's built-in URL utilities

Functions Ready for Upstreaming

Several utility functions could benefit the broader Open Food Facts ecosystem:

  • Barcode formatting and validation
  • Product image URL construction (similar to existing getProductImageUrl())
  • URL parsing utilities
  • Domain detection helpers

See UPSTREAM_CANDIDATES.md for detailed documentation.

Integration Blockers

Currently blocked on openfoodfacts-js needing a UMD/browser build for userscript compatibility. The current ESM/CJS builds don't work in userscript environments due to module system constraints.

This PR maintains full backward compatibility while creating a clear migration path for when the library becomes userscript-compatible.

Fixes #110.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdn.jsdelivr.net
    • Triggering command: curl -s REDACTED (dns block)
  • data.jsdelivr.com
    • Triggering command: curl -s REDACTED (dns block)
  • unpkg.com
    • Triggering command: curl -s REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copy link
Author

Copilot AI commented Sep 3, 2025

@teolemon 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Comment on lines +694 to +697
var apiProductURL = OFFApiHelpers.buildProductApiUrl(code);
log("API: " + apiProductURL);
// build edit url
var editURL = document.location.protocol + "//" + document.location.host + "/cgi/product.pl?type=edit&code=" + code;
var productUrls = OFFApiHelpers.buildProductUrls(code);

Check failure

Code scanning / CodeQL

Client-side cross-site scripting High

Cross-site scripting vulnerability due to
user-provided value
.

Copilot Autofix

AI 3 months ago

To fix this vulnerability, we should ensure that user-provided input is properly encoded/escaped before being inserted into an HTML context—especially within dynamically constructed strings given to jQuery's .append(). The best practice here is to avoid building HTML strings with embedded untrusted data; instead, create elements using jQuery or the DOM API and set attributes/contents safely to be escaped automatically. Specifically:

  • Instead of constructing the <span>/<a> HTML as a string, we use jQuery to create the <span> and <a> elements, set their attributes using .attr(), and append them, so that values are safely escaped.
  • This change should be made where sameBrandProductsURL (line 797) and the surrounding HTML is inserted via .append() on line 796.
  • No new methods or imports are necessary; jQuery is already present.

Suggested changeset 1
OpenFoodFactsPower.user.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/OpenFoodFactsPower.user.js b/OpenFoodFactsPower.user.js
--- a/OpenFoodFactsPower.user.js
+++ b/OpenFoodFactsPower.user.js
@@ -792,11 +792,15 @@
                 "//" + document.location.host +
                 '/state/brands-to-be-completed/code/' +
                 sameBrandProducts;
-            $("#barcode_paragraph")
-                .append(' <span id="sameBrandProductLink" class="productLink">[<a href="' +
-                        sameBrandProductsURL +
-                        '" title="Products without brand that might be from this brand">'+
-                        'Non-branded ϵ same brand?</a>]</span>');
+            // Construct link safely using jQuery to avoid XSS
+            var $brandSpan = $('<span>', { id: 'sameBrandProductLink', class: 'productLink' }).append(
+                '[', $('<a>', {
+                    href: sameBrandProductsURL,
+                    title: 'Products without brand that might be from this brand',
+                    text: 'Non-branded ϵ same brand?'
+                }), ']'
+            );
+            $("#barcode_paragraph").append(' ', $brandSpan);
             // Google Link
             var googleLink = 'https://www.google.com/search?q=' + code;
             $("#barcode_paragraph")
EOF
@@ -792,11 +792,15 @@
"//" + document.location.host +
'/state/brands-to-be-completed/code/' +
sameBrandProducts;
$("#barcode_paragraph")
.append(' <span id="sameBrandProductLink" class="productLink">[<a href="' +
sameBrandProductsURL +
'" title="Products without brand that might be from this brand">'+
'Non-branded ϵ same brand?</a>]</span>');
// Construct link safely using jQuery to avoid XSS
var $brandSpan = $('<span>', { id: 'sameBrandProductLink', class: 'productLink' }).append(
'[', $('<a>', {
href: sameBrandProductsURL,
title: 'Products without brand that might be from this brand',
text: 'Non-branded ϵ same brand?'
}), ']'
);
$("#barcode_paragraph").append(' ', $brandSpan);
// Google Link
var googleLink = 'https://www.google.com/search?q=' + code;
$("#barcode_paragraph")
Copilot is powered by AI and may make mistakes. Always verify output.
Copilot AI changed the title [WIP] Use openfoodfacts-js in the Power User Script Refactor API calls and prepare for openfoodfacts-js integration Sep 3, 2025
Copilot finished work on behalf of teolemon September 3, 2025 17:09
Copilot AI requested a review from teolemon September 3, 2025 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🆕 New

Development

Successfully merging this pull request may close these issues.

Use openfoodfacts-js in the Power User Script

2 participants