diff --git a/app/api/deps.py b/app/api/deps.py index 011e2a47..c831e786 100644 --- a/app/api/deps.py +++ b/app/api/deps.py @@ -728,6 +728,12 @@ def get_current_store_from_cookie_or_header( logger.warning(f"Store auth failed: No token for {request.url.path}") raise InvalidTokenException("Store authentication required") + # Paired terminal-device tokens authenticate to the store API too. + # Cookie path won't carry a device JWT; this only matters for header. + device_ctx = _try_authenticate_terminal_device(token, db, request) + if device_ctx is not None: + return device_ctx + # Validate token and get user user = _validate_user_token(token, db) diff --git a/app/modules/loyalty/static/shared/js/loyalty-devices-list.js b/app/modules/loyalty/static/shared/js/loyalty-devices-list.js index 2c331ba0..8de43ea8 100644 --- a/app/modules/loyalty/static/shared/js/loyalty-devices-list.js +++ b/app/modules/loyalty/static/shared/js/loyalty-devices-list.js @@ -95,9 +95,15 @@ function loyaltyDevicesList(config) { async loadLocations() { try { const response = await apiClient.get(locationsPrefix + '/locations'); - if (response) { - this.locations = Array.isArray(response) ? response : (response.locations || []); - } + if (!response) return; + const raw = Array.isArray(response) ? response : (response.locations || []); + // Endpoint returns {id, name, code}; templates bind to store_id/store_name. + // Normalize so callers don't have to care about either shape. + this.locations = raw.map(loc => ({ + store_id: loc.store_id ?? loc.id, + store_name: loc.store_name ?? loc.name, + store_code: loc.store_code ?? loc.code, + })); } catch (error) { loyaltyDevicesListLog.warn('Failed to load locations:', error.message); }