Commit Graph
4 Commits
Author SHA1 Message Date
babasado 7392fbafca fix(ministra): allow authorized reseller device security changes
Expose User-Agent allowlists and an explicit STB reset for managed customer devices. Enforce restriction permissions and ownership, serialize resets with binding checks, invalidate portal caches, and preserve User-Agent policy on reset.

Fix the CI style violation and keep new translations in en.ini only. Record pre-push validation and translation workflow guidance.
2026-10-20 20:22:06 +02:00
babasado 8e228b8ba1 feat: add reseller bouquet controls and panel customizations
Add per-reseller bouquet limits and per-customer selection and ordering,
while keeping package defaults for new lines and trials.

Integrate the separately installed User Proxy module through core routing
and customer form hooks, with native playback fallback.

Fix connection-counter deep links across admin and reseller pages. Add
proxy availability to dashboard status and a setting to hide Active Codes.

Include migrations 094/095, setup guides and regression coverage. Keep
local skills, installed modules and development dependencies out of Git.
2026-10-13 23:53:27 +02:00
obscuremindandClaude Opus 5.5 e9bfb3e67a fix(reseller): no secret of a sub-reseller, no restriction without the right
- get_user answered a sub-reseller's password hash and API key when
  asked by name (show_columns is taken before the forced hide), and
  failed on in_array(.., null) without hide_columns. getUser() now never
  carries either field, for get_user and for the row create_user and
  edit_user answer with.
- A reseller without allow_restrictions still set allowed addresses and
  user agents, the blocked agents' bypass and the ISP lock on a new line
  or device: the save skipped its restrictions block, but the new row
  had been filled from what was posted. processData() drops the fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AneTzAHPPkYWPQjwyZ2td9
2026-10-10 14:07:25 +00:00
rootandClaude Opus 5 99036f99d0 fix(security): resellers can no longer pair onto or re-trial other lines
ResellerAPI::processData() is the whitelist every reseller line, MAG and
Enigma2 save goes through. Two fields in it could be turned on other
people's subscriptions:

- pair_id: a new line stored whatever id was sent. Pairing copies the paired
  line's expiry and bouquets onto this one on every renewal
  (MagService::syncLineDevices), so a reseller could buy the cheapest line
  paired to another reseller's paying customer and ride that subscription
  for free. MAG and Enigma2 saves already required the paired line to be
  the reseller's own; now every type does.
- trial: accepted on an edit, where it reset the expiry for trial_credits
  (usually 0). The trial quota counts lines by created_at, which an edit
  does not change, so any existing line could be extended forever. The
  forms only send it when creating; the API now does the same.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V2uBUbGApb4A7Rbcoi7dxA
2026-09-17 07:45:14 +00:00