--- title: "1.33.1 — Notification channel master switches, protected-permission floor, stricter S3 audit" description: "Users can switch a whole notification channel off with one reserved \"*\" entry that the send-time check honours first, and apps can register their notification kinds with labels so account pages list them by name. MEMBER_PERMS_PROTECTION from the settings file is now a floor a Setting row cannot weak…" date: "2026-10-07" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-33-1/" --- Users can switch a whole notification channel off with one reserved "*" entry that the send-time check honours first, and apps can register their notification kinds with labels so account pages list them by name. MEMBER_PERMS_PROTECTION from the settings file is now a floor a Setting row cannot weaken, validated Setting values are stored as JSON rather than Python repr, and the fileman S3 public-access audit sets aside the TLS-only deny while parsing policies strictly. No consumer change is required. ### Added - Notification preferences accept the reserved kind `"*"` as a per-channel master switch: `"*": {"email": false}` suppresses every kind on that channel, including kinds set on and kinds added later; master on or absent defers to the per-kind entry. A falsy (transactional) kind is never suppressed. - `register_notification_kinds([...])` / `list_notification_kinds()` in `mojo.apps.account.services.notification_kinds`; `general` is pre-registered. Slugs `[a-z0-9_.-]+` up to 64 chars, label required, `"*"` refused, a batch is all-or-nothing, re-registering replaces in place. - `GET /api/account/notification/preferences` returns `kinds` (registration order) and `channels` beside the unchanged `preferences`. ### Fixed - `MEMBER_PERMS_PROTECTION` from the settings file is a floor: a platform-wide Setting row can only add keys, never remove or loosen a file-set requirement; a malformed or null row refuses member-level permission changes instead of reading as empty, and the write validator refuses storing one. Tuple requirements from the file read as lists. - A validated Setting key saved with a non-string value is stored as JSON, not its Python repr, so what passed validation is what is read back. - Fileman S3 public-access audit: the TLS-only deny that provisioning writes on every bucket no longer forces every hardened bucket to "unknown"; policy text is parsed strictly (repeated members, NaN/Infinity, malformed statements, Not* allows → unknown rather than a wrong public/private answer). - A new group file manager inherits the system manager's public/private flag instead of the model default. ### Upgrade notes - Register each app's notification kinds in `AppConfig.ready()` so web, jobs and realtime processes all carry the registry; unregistered kinds keep working and are still enforced. - If a deployment relied on a Setting row to loosen a file-set `MEMBER_PERMS_PROTECTION` requirement, that row is now ignored for those keys.