diff --git a/CHANGELOG.md b/CHANGELOG.md index c834174d..83546f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Table preferences (header pin and table size) now managed together with centralized state management and localStorage persistence. - - Frontend tests GitHub workflow now uses Node.js 24 (matching Dockerfile) and runs on both `main` and `dev` branch pushes and pull requests for comprehensive CI coverage. - Table preferences architecture refactored: Migrated `table-size` preference from individual `useLocalStorage` calls to centralized `useTablePreferences` hook. All table components now read preferences from the table instance (`table.tableSize`, `table.headerPinned`) instead of calling hooks directly, improving maintainability and providing consistent API across all tables. ### Fixed +- Fixed channel profile filtering to properly restrict content based on assigned channel profiles for all non-admin users (user_level < 10) instead of only streamers (user_level == 0). This corrects the XtreamCodes API endpoints (`get_live_categories` and `get_live_streams`) along with M3U and EPG generation, ensuring standard users (level 1) are properly restricted by their assigned channel profiles. Previously, "Standard" users with channel profiles assigned would see all channels instead of only those in their assigned profiles. - Fixed NumPy baseline detection in Docker entrypoint. Now calls `numpy.show_config()` directly with case-insensitive grep instead of incorrectly wrapping the output. - Fixed SettingsUtils frontend tests for new grouped settings architecture. Updated test suite to properly verify grouped JSON settings (stream_settings, dvr_settings, etc.) instead of individual CharField settings, including tests for type conversions, array-to-CSV transformations, and special handling of proxy_settings and network_access. diff --git a/apps/output/views.py b/apps/output/views.py index 47798ee2..2cdd4dac 100644 --- a/apps/output/views.py +++ b/apps/output/views.py @@ -128,7 +128,7 @@ def generate_m3u(request, profile_name=None, user=None): return HttpResponseForbidden("POST requests with body are not allowed, body is: {}".format(request.body.decode())) if user is not None: - if user.user_level == 0: + if user.user_level < 10: user_profile_count = user.channel_profiles.count() # If user has ALL profiles or NO profiles, give unrestricted access @@ -1258,7 +1258,7 @@ def generate_epg(request, profile_name=None, user=None): # Get channels based on user/profile if user is not None: - if user.user_level == 0: + if user.user_level < 10: user_profile_count = user.channel_profiles.count() # If user has ALL profiles or NO profiles, give unrestricted access @@ -2079,7 +2079,7 @@ def xc_get_live_categories(user): from django.db.models import Min response = [] - if user.user_level == 0: + if user.user_level < 10: user_profile_count = user.channel_profiles.count() # If user has ALL profiles or NO profiles, give unrestricted access @@ -2116,7 +2116,7 @@ def xc_get_live_categories(user): def xc_get_live_streams(request, user, category_id=None): streams = [] - if user.user_level == 0: + if user.user_level < 10: user_profile_count = user.channel_profiles.count() # If user has ALL profiles or NO profiles, give unrestricted access