Сотрудник сам подключает ящик (autoconfig, вложения, пагинация списка, надёжный IMAP-поиск); в хедере работает /api/search по разделам и сущностям с ACL. Также устойчивость Mattermost-токена для чата.
Co-authored-by: Cursor <cursoragent@cursor.com>
Ранее разделы с perm=None (Новости, Задачи, Дислокация, Документы, Чат,
Календарь, HR-портал, Справка) были доступны любому вошедшему — сотрудник
без назначенной группы видел почти весь портал. Теперь такие разделы
требуют хотя бы одной группы; без групп доступны только базовые:
Главная, Профиль, Поддержка IT.
- user_can_access: BASELINE_OPEN_KEYS + gate «есть ли группа» для perm=None
- PortalSectionAccessMiddleware: барьер по префиксу URL (в т.ч. вложенные
страницы вроде /tasks/5/), /settings/ не гейтим (редирект на свой профиль)
- index.html: пункты меню под can_section (сайдбар, дропдаун, bottom-nav),
секция «Управление» скрывается целиком, если пусто
- тесты: политика без-группы + прямой заход по URL; тест-фабрики выдают
группу (реальный сотрудник её имеет)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hx-post вне формы (кнопка «Синхронизировать чат») слал POST без CSRF —
Forbidden (CSRF token missing). Добавил hx-headers с X-CSRFToken на <body>:
токен уходит со всеми htmx-запросами, работает и при CSRF_COOKIE_HTTPONLY.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Section-based portal access, matrix прав по группам, аккаунтинг-портал,
управление группами пользователей, справочники, дашборд и общий каркас
навигации/стилей.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 2FA: убраны /api/ и /media/ из ALLOWED_PREFIXES — staff-сессия без TOTP
больше не дотягивается до API/медиа (устройства в /api/ идут без staff-сессии)
- Nextcloud «Обмен»: writable только для staff (не для любого logged-in)
- Nextcloud путь отдела/адрес аптеки: safe_component() санитайзит сегмент
(сепараторы/управляющие/ведущие точки) в провижининге и в браузере
- Mattermost: shared secret кнопки «Виконано» перенесён из query string в
context (тело POST) — без утечки в логи/Referer
- Login: throttle на кэше (5 попыток / 5 мин, 429); logout только POST (CSRF),
logout-ссылки в шаблонах → POST-формы
Тесты обновлены под enforcement 2FA (login_2fa helper) и новые правила.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- FIELD_ENCRYPTION_KEY: production требует явный ключ (ImproperlyConfigured
при пустом), local — fallback на SECRET_KEY с предупреждением (crypto.py)
- MATTERMOST_INTERACTIVE_TOKEN: fail-closed токен для интерактивных кнопок
Mattermost (bot_service task-done URL + проверка в mattermost views)
- Ужесточение прав API (employees/visit_manager) + тесты
(employees, mattermost_connector, visit_manager)
- .env.example с описанием переменных; правки шаблонов (index/dislocation/pharmacies)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JS определял плейсхолдер сравнением с захардкоженным «Завантаження...», а
текст загрузчика стал переводиться ({% trans %}) — из-за чего в ru/en
контент не подгружался (и при обычной загрузке, и после смены языка).
Теперь плейсхолдер определяется по #page-loader (язык-независимо).
Переключатель языка возвращает на текущую страницу (next=pathname).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Мультиязычность: русский — базовый (msgid), украинский и английский — переводы.
- Настройки: LocaleMiddleware, LANGUAGES=[ru,uk,en], LOCALE_PATHS, i18n
context_processor; urls: django.conf.urls.i18n (set_language)
- Шелл index.html: {% load i18n %}, все пункты навигации/меню/пользовательского
меню/нижней навигации помечены {% trans %}; динамический <html lang>;
переключатель языков в хедере (select -> set_language)
- Каталоги locale/uk и locale/en: переведены строки меню/шелла (34), собраны .mo
- .gitignore: разрешено трекать locale/**/*.mo (нужны на проде, CI нет)
Остальные страницы пока на украинском (хардкод) — переводятся дальше поэтапно.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ad_connector: restrict provisioning to office employees
(user_location_type='office') in sync service, signals and command;
disable AD account on transfer out of office, re-enable on return
- ad_connector: /ad-mapping/ page (staff only) — match office employees
to AD accounts with suggestions by email/login/full name, link/unlink/
create actions, list of unmatched domain accounts; sidebar nav item
- core: auto-rebuild treenode Directory tree (_path/_depth) after
import-export imports and post_migrate; "rebuild tree" button in
DirectoryAdmin and rebuild_directory_tree management command
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>