humanresources 26.600.0 Безопасность

Humanresources 26.600.0: триггер БП на первый вход сотрудника и закрытый селектор физлиц из 1С

4 мин чтения Устаревших API: 4
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Обновление безопасности

Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.

В humanresources 26.600.0 для коробочного Битрикс24 новый конструктор процессов получил триггер «Появился новый сотрудник», который срабатывает на первом входе сотрудника на портал. Ещё в релизе закрыли селектор физлиц из 1С со СНИЛС, который раньше открывался любому пользователю, и сделали одноразовым ПИН для запроса расчётного листка и данных об отпуске в HCM Link. Обновление касается тех, кто строит онбординг на бизнес-процессах, и авторов приложений-коннекторов к 1С.

Новое

Встречайте нового сотрудника бизнес-процессом

В каталоге конструктора появился узел CBPNewEmployeeTrigger в группах STARTER, HR и TEAM_MANAGEMENT. Дальше по сценарию он отдаёт «Сотрудника» (USER, в виде user_N) и «Дату и время появления» (EventDateTime).

В свойстве «Сотрудники, подразделения и команды» выбирают сотрудников, узлы оргструктуры (с подчинёнными или без) и старые отделы, которые модуль сам переводит в узлы. Команда работает как отдел. Пустое свойство значит «любой новый сотрудник». Выражения над параметрами и переменными шаблона в фильтр не пишите. Правила триггера движок проверяет на процессе-заглушке с пустыми параметрами, такое выражение там ничего не находит, и запуск отклоняется. Голый числовой id ядро читает как группу пользователей, его триггер тоже отклонит. Людей и отделы выбирайте в селекторе.

Если узла нет в каталоге, обновите bizproc и ui. .description.php триггера молча ничего не регистрирует, если в bizproc нет типа TRIGGER и нужных групп или в ui нет иконки o-add-person.

Кого модуль считает новым сотрудником

Первый вход ловит Integration\Bizproc\FirstLoginDispatcher, обработчик main:OnAfterUserAuthorize из install/migrations/events.php. Вход считается первым, если выполнено всё сразу:

  • в снимке пользователя пустой LAST_LOGIN;
  • $params['update'] === true, по комментарию в коде так ядро отличает обычный вход от REST-авторизации;
  • сессия не виртуальная (BX_SECURITY_SESSION_VIRTUAL);
  • EXTERNAL_AUTH_ID не из UserTable::getExternalUserTypes(), при этом LDAP и вход через соцсети проходят;
  • способ входа не LoginAs, не AppPassword и не Controller.

Потом отсеиваются экстранет и участники коллаб. Сценарии запускаются один раз на сотрудника, отметку об этом модуль хранит в CUserOptions: категория humanresources, имя new_employee_trigger_launched, значение Y.

Администратор, вошедший под сотрудником, сценарий не запустит. Сотрудники, которые входили до обновления, триггер не вызовут, у них уже заполнен LAST_LOGIN. А давно заведённый аккаунт, который ни разу не входил, вызовет его при первом входе.

Проверять сценарий проще на свежем пользователе.

Обработчик стоит на каждом входе, но любое исключение ловит сам, так что вход из-за него не упадёт. Если сценарий с триггером есть, но не стартовал, причину модуль пишет через AddMessage2Log в файл из константы LOG_FILENAME, а без этой константы не пишет никуда. Туда же уходят пойманные исключения. В записи будет одна из причин: bizprocUnavailable, extranetMember, collabMember, alreadyRun, filteredOut, launchFailed или unexpectedFailure. Отказ по тарифу (BPDesignerConstraint) тоже записывается как launchFailed.

Запускайте сценарии из своего кода

Лаунчер берётся через Service\Container::getBizprocProcessLauncher() (сервис humanresources.integration.bizproc.processLauncher). Его launchForNewEmployee(int $userId) поднимает событие триггера, сам исключений не бросает и отвечает Result. Так можно запустить онбординг сотруднику, который вошёл до обновления. Отметку о запуске ставит обработчик входа, лаунчер её не трогает, а экстранет и коллаберов не отсеивает, это ваша забота. Если сотрудник ещё не входил, без отметки его первый вход запустит сценарии второй раз:

        <?php declare(strict_types=1);

namespace Vendor\Onboarding\Application\Service;

use Bitrix\Bizproc\Starter\Starter;
use Bitrix\Extranet\User as ExtranetUser;
use Bitrix\HumanResources\Service\Container;
use Bitrix\Main\Error;
use Bitrix\Main\Loader;
use Bitrix\Main\Result;

final class NewEmployeeScenarioStarter
{
    // та же отметка, которую проверяет FirstLoginDispatcher
    private const MARKER_CATEGORY = 'humanresources';
    private const MARKER_NAME = 'new_employee_trigger_launched';
    private const MARKER_VALUE = 'Y';

    public function start(int $userId): Result
    {
        if (
            !Loader::includeModule('humanresources')
            || !Loader::includeModule('bizproc')
            || !class_exists(Starter::class)
        ) {
            return (new Result())->addError(new Error('Нет модуля humanresources или bizproc', 'MODULE_MISSING'));
        }

        if (Loader::includeModule('extranet') && (new ExtranetUser($userId))->isExtranet()) {
            return (new Result())->addError(new Error('Пользователь экстранета', 'EXTRANET_USER'));
        }
        // коллаберов модуль отсеивает через getCollaberService()->isCollaberById() из extranet

        $marker = \CUserOptions::GetOption(self::MARKER_CATEGORY, self::MARKER_NAME, false, $userId);
        if ($marker === self::MARKER_VALUE) {
            return (new Result())->addError(new Error('Сценарии уже запускались', 'ALREADY_STARTED'));
        }

        // модуль ставит отметку до запуска, повторяем его порядок
        \CUserOptions::SetOption(self::MARKER_CATEGORY, self::MARKER_NAME, self::MARKER_VALUE, false, $userId);

        return Container::getBizprocProcessLauncher()->launchForNewEmployee($userId);
    }
}

    

Ошибка в Result ещё не значит, что ничего не стартовало. Туда же попадают отказы фильтров других опубликованных сценариев, поэтому модуль дополнительно смотрит StartResult::isTriggerApplied() и getWorkflowIds().

Процесс стартует вне текущего хита. Лаунчер зовёт Starter::getByScenario(Scenario::onEvent) с setDelay(0), а bizproc включает отложенный старт от самого факта переданной задержки, нулевой тоже: $shouldStartLater = $useDelays && $startDelay !== null; в bizproc/classes/general/document.php. Выключает это опция bizproc disable_start_workflow_delay = Y. Тот же setDelay(0) пригодится, когда тяжёлый процесс запускается из вашего обработчика события.

Что сломается

Проверьте свои диалоги с селектором физлиц из 1С

До 26.600.0 PersonDataProvider::isAvailable() у сущности hcmlink-person-data (секция ui.entity-selector) возвращал true без проверки прав. Теперь провайдер спрашивает Container::getHcmLinkAccessService()->canRead(). Это право ACTION_B2E_DOCUMENT_ADD модуля sign, а без sign только администратор.

Если вы открывали этот селектор в своём диалоге, у обычного сотрудника он теперь пустой. Проверьте право тем же canRead() и не показывайте поле тем, кому оно ничего не найдёт.

Переименуйте companyGuid в коннекторе к 1С

В outputData заданий PIN_REQUEST и SALARY_VACATION_REQUEST ключ companyGuid стал companyUid, значение то же, UID организации в 1С. Эти задания уходят в события OnHumanResourcesHcmLinkPinRequested и OnHumanResourcesHcmLinkSalaryVacationRequested. Приложение, которое читает companyGuid, после обновления портала получит пустое значение. Сервис и события появились в humanresources 26.500.0, так что старое имя у кого-то уже в коде. Пока порталы обновляются, читайте оба ключа:

        $companyUid = (string)($outputData['companyUid'] ?? $outputData['companyGuid'] ?? '');

    

Один ПИН на один запрос документа

Когда запрос документа завершился (DONE), SalaryVacationApiService сверяет ПИН через hash_equals, удаляет значение поля PIN на портале и освобождает слоты троттлинга pin_request и document_request. Тот же ПИН с портала больше не достать, а новый ПИН для следующего запроса сотрудник может попросить сразу, не дожидаясь конца интервала. Пока выданный ПИН не использован и не истёк, повторный запрос в пределах интервала вернёт то же задание, и новый запрос в 1С не уйдёт.

Найдите вызовы удалённого Member\Role

Вместе с Controller\Structure\Node\Member\Role пропали действия humanresources.api.Structure.Node.Member.Role.set (назначение роли участнику узла) и humanresources.api.Structure.Node.Member.Role.list (список ролей). JS модуля их не вызывал ни в 26.500.0, ни сейчас. Сломается только ваш код, который звал их через BX.ajax.runAction, поищите Member.Role в /local/.

Мелочи и находки

  • В оргструктуре колесо мыши над карточкой мини-профиля двигает холст или прокручивает список под курсором, Ctrl+колесо масштабирует.
  • Мастер настройки команды предупреждает, что у команды не назначен руководитель или заместитель. По комментарию в коде отчёты получает руководитель или заместитель команды, затем родительские команды, затем руководители отдела.
  • humanresources.hcmlink.field.value.set принимает код РасчетныйЛисток через «е» и сам переводит его в РасчётныйЛисток, который ждёт PayrollType::SALARY. Значения полей типа DOCUMENT теперь пишутся в слот документа из задания. По комментарию в коде, sign кладёт туда id подписанта и по нему читает значение.

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
Bitrix\HumanResources\Controller\Structure\Node\Member\Role::setAction() Удалено —
Bitrix\HumanResources\Controller\Structure\Node\Member\Role::listAction() Удалено —
humanresources.api.Structure.Node.Member.Role.set Удалено —
humanresources.api.Structure.Node.Member.Role.list Удалено —

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

humanresources 26.500.0 Ломающее Свежее

Humanresources 26.500.0: виртуальные пользователи пропали из выборок и счётчиков оргструктуры

В humanresources 26.500.0 (коробочный Битрикс24) фильтры, репозитории и счётчики оргструктуры по умолчанию перестали видеть ботов, пользователей приложений и остальных виртуальных пользователей. В том же релизе поменяли местами перепутанные `ONLY_ACTIVE` и `ONLY_GLOBAL_ACTIVE`, `RolePermissionServic…

3 мин
socialnetwork 26.200.0 Безопасность Свежее

Socialnetwork 26.200.0: XSS в заявках и списке участников, копирование проекта по праву редактирования и курсор в log.blogpost.get

Socialnetwork 26.200.0 закрывает XSS в списке участников проекта и в заявках в группы, подмену ссылок через название группы и утечку задач в контекст AI. Копировать проект теперь можно только с правом на редактирование. Администраторам, у которых стояли 26.100.0 или 26.150.0, стоит проверить права с…

2 мин
sign 26.800.0 Безопасность Свежее

Sign 26.800.0: закрыли доступ к чужим документам, к приглашению на подпись можно дописать текст

Sign 26.800.0 для коробочного Битрикс24 закрывает несколько дыр в проверке прав: часть AJAX-экшенов модуля не проверяла, есть ли у пользователя доступ к конкретному документу, группе или участнику. Если на портале подписывают документы, с сотрудниками или с клиентами, обновляйтесь. Из нового — текст…

2 мин
search 26.100.0 Ломающее Свежее

Search 26.0.0–26.100.0: новые атрибуты Sphinx, переиндексация из консоли и исправленная проверка прав

Модуль поиска обновился сразу на две версии: 25.200.0 → 26.0.0 → 26.100.0. Без правки sphinx.conf индексация на Sphinx перестанет работать, а у встроенного движка и FULLTEXT MySQL/PostgreSQL, судя по коду, заголовки новых записей больше не попадают в индексируемый текст. В 26.100.0 закрыли пропуск п…

2 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти