feat(backend): add Open Food Facts authentication support
- Add OFF_USERNAME and OFF_PASSWORD env vars - Use Basic Auth when credentials are provided - Improves rate limits for authenticated requests - Auth is optional (works without credentials)
This commit is contained in:
@@ -19,3 +19,8 @@ VAPID_SUBJECT=mailto:admin@example.com
|
||||
# Expo Push Notifications (mobile). Get token from:
|
||||
# https://expo.dev/accounts/[username]/settings/access-tokens
|
||||
EXPO_ACCESS_TOKEN=
|
||||
|
||||
# Open Food Facts (optional, improves rate limits)
|
||||
# Register at: https://world.openfoodfacts.org/
|
||||
OFF_USERNAME=
|
||||
OFF_PASSWORD=
|
||||
|
||||
@@ -4,6 +4,20 @@ import redisClient from './redis-client.js';
|
||||
const OFF_API_BASE = 'https://world.openfoodfacts.org';
|
||||
const CACHE_TTL = 3600;
|
||||
|
||||
// Open Food Facts authentication (optional, improves rate limits)
|
||||
const OFF_USERNAME = process.env.OFF_USERNAME;
|
||||
const OFF_PASSWORD = process.env.OFF_PASSWORD;
|
||||
|
||||
function getOffAuth() {
|
||||
if (OFF_USERNAME && OFF_PASSWORD) {
|
||||
return {
|
||||
username: OFF_USERNAME,
|
||||
password: OFF_PASSWORD,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function transformOFFProduct(offProduct) {
|
||||
if (!offProduct || !offProduct._id || !offProduct.product_name) {
|
||||
return null;
|
||||
@@ -53,6 +67,7 @@ export async function searchBabyProducts(query) {
|
||||
}
|
||||
|
||||
console.log(`Fetching from OFF API: ${searchTerm}`);
|
||||
const auth = getOffAuth();
|
||||
const response = await axios.get(`${OFF_API_BASE}/cgi/search.pl`, {
|
||||
params: {
|
||||
search_terms: searchTerm,
|
||||
@@ -63,6 +78,7 @@ export async function searchBabyProducts(query) {
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: (status) => status === 200,
|
||||
...(auth && { auth }),
|
||||
});
|
||||
|
||||
// Check if response is actually JSON (OFF sometimes returns HTML on error)
|
||||
@@ -108,8 +124,11 @@ export async function getBabyProductDetails(barcode) {
|
||||
}
|
||||
|
||||
console.log(`Fetching OFF product details: ${barcode}`);
|
||||
const auth = getOffAuth();
|
||||
const response = await axios.get(`${OFF_API_BASE}/api/v2/product/${barcode}.json`, {
|
||||
timeout: 10000,
|
||||
validateStatus: (status) => status === 200,
|
||||
...(auth && { auth }),
|
||||
});
|
||||
|
||||
if (response.data && response.data.product) {
|
||||
|
||||
Reference in New Issue
Block a user