CVE-2023-50924 (PHP, published 2023-12-22T21:15Z)
Description: value: Englesystem is a shift planning system for chaos events. Engelsystem prior to v3.4.1 performed insufficient validation of user supplied data for the DECT number, mobile number, and work-log comment fields. The values of those fields would be displayed in corresponding log overviews, allowing the injection and execution of Javascript code in another user's context. This vulnerability enables an authenticated user to inject Javascript into other user's sessions. The injected JS will be executed during normal usage of the system when viewing, e.g., overview pages. This issue has been fixed in version 3.4.1.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/engelsystem/engelsystem
Files changed:
includes/controller/angeltypes_controller.php
includes/controller/rooms_controller.php
includes/controller/shifts_controller.php
includes/controller/shifttypes_controller.php
includes/controller/user_angeltypes_controller.php
includes/controller/users_controller.php
includes/engelsystem.php
includes/helper/message_helper.php
includes/pages/admin_free.php
includes/pages/admin_groups.php
includes/pages/admin_shifts.php
includes/pages/admin_user.php
includes/pages/guest_login.php
includes/pages/user_shifts.php
includes/sys_form.php
includes/sys_menu.php
includes/sys_page.php
includes/sys_template.php
includes/view/AngelTypes_view.php
includes/view/PublicDashboard_view.php
includes/view/Rooms_view.php
includes/view/ShiftCalendarShiftRenderer.php
includes/view/ShiftEntry_view.php
includes/view/ShiftTypes_view.php
includes/view/Shifts_view.php
includes/view/UserAngelTypes_view.php
includes/view/UserHintsRenderer.php
includes/view/User_view.php
resources/views/emails/angeltype-added.twig
resources/views/emails/angeltype-confirmed.twig
resources/views/pages/login.twig
Commit message: Escape text outputs in includes


Vulnerable code:
        sprintf(__('Delete angeltype %s'), $angeltype->name),
        sprintf(__('Edit %s'), $angeltype->name),
        sprintf(__('Team %s'), $angeltype->name),
            . $angeltype->name
        $room->name,
            $angeltype_name,
                form_info('', __('This description is for single shifts, otherwise please use the description in shift type.')),
        $shift->shiftType->name,
        sprintf(__('Delete shifttype %s'), $shifttype->name),
        $shifttype->name,
            . '">' . $user_angeltype->angelType->name
        sprintf(__('Become a %s'), $angeltype->name),
        sprintf(__('Delete %s'), $user_source->displayName),
        sprintf(__('%s\'s vouchers'), $user_source->displayName),
        $user_source->displayName,
    $maintenance = str_replace('%APP_NAME%', $app->get('config')->get('app_name'), $maintenance);
function info($msg, $immediately = false)
    return alert(NotificationType::INFORMATION, $msg, $immediately);
function warning($msg, $immediately = false)
    return alert(NotificationType::WARNING, $msg, $immediately);
function error($msg, $immediately = false)
    return alert(NotificationType::ERROR, $msg, $immediately);
function success($msg, $immediately = false)
    return alert(NotificationType::MESSAGE, $msg, $immediately);
 * @see \Engelsystem\Controllers\HasUserNotifications
 *
function alert(NotificationType $type, $msg, $immediately = false)
            'dect'        => sprintf('<a href="tel:%s">%1$s</a>', $usr->contact->dect),
                ? sprintf('<a href="mailto:%s">%1$s</a>', $email)
                $privileges_html[] = $privilege['name'];
                'name'       => $group->name,
                            $privilege->description . ' (' . $privilege->name . ')',
                            'privilege-' . $privilege->name
                    $html .= page_with_title(__('Edit group') . ' ' . $group->name, [
                        . ($shift['title'] ? '<br />' . $shift['title'] : ''),
                $type->name,
        $html .= '<br /><br />';
        $html .= '  <tr><td>' . __('Nickname') . '</td><td>' . '<input size="40" name="eNick" value="' . $user_source->name . '" class="form-control" maxlength="24"></td></tr>' . "\n";
            $html .= '  <tr><td>' . __('Prename') . '</td><td>' . '<input size="40" name="eName" value="' . $user_source->personalData->last_name . '" class="form-control" maxlength="64"></td></tr>' . "\n";
            $html .= '  <tr><td>' . __('Last name') . '</td><td>' . '<input size="40" name="eVorname" value="' . $user_source->personalData->first_name . '" class="form-control" maxlength="64"></td></tr>' . "\n";
        $html .= '  <tr><td>' . __('Mobile') . '</td><td>' . '<input type= "tel" size="40" name="eHandy" value="' . $user_source->contact->mobile . '" class="form-control" maxlength="40"></td></tr>' . "\n";
            $html .= '  <tr><td>' . __('DECT') . '</td><td>' . '<input size="40" name="eDECT" value="' . $user_source->contact->dect . '" class="form-control" maxlength="40"></td></tr>' . "\n";
            $html .= '  <tr><td>' . __('settings.profile.email') . '</td><td>' . '<input type="email" size="40" name="eemail" value="' . $user_source->email . '" class="form-control" maxlength="254"></td></tr>' . "\n";
        $html .= '</table>' . "\n" . '<br />' . "\n";
        $html .= '<hr />';
        $html .= '  <tr><td>' . __('Password') . '</td><td>' . '<input type="password" size="40" name="new_pw" value="" class="form-control" autocomplete="new-password"></td></tr>' . "\n";
        $html .= '  <tr><td>' . __('Confirm password') . '</td><td>' . '<input type="password" size="40" name="new_pw2" value="" class="form-control" autocomplete="new-password"></td></tr>' . "\n";

        $html .= '</table>' . "\n" . '<br />' . "\n";
        $html .= '<hr />';
                    . ' /><label class="form-check-label" for="' . $group->id . '">' . $group->name . '</label></div>';
            $html .= '<hr />';
        $angel_types[$angel_type->id] = $angel_type->name
                            [config('app_name')]
                            . (config('privacy_email') ? ' ' . __('To withdraw your approval, send an email to <a href="mailto:%s">%1$s</a>.', [config('privacy_email')]) : ''),
/**
 * @param array $array
 * @return array
 */
function get_ids_from_array($array)
{
    return $array['id'];
}

            . '><label class="form-check-label" for="' . $id . '">' . $i['name'] . '</label>'
        . '<input class="form-check-input" type="checkbox" id="' . $html_id . '" name="' . $name . '" value="' . htmlspecialchars((string) $value) . '" '
 * Rendert einen Radio
/**
 * Renders a text input with placeholder instead of label.
 *
 * @param string  $name        Input name
 * @param string  $placeholder Placeholder
 * @param string  $value       The value
 * @param boolean $disabled    Is the field enabled?
 * @return string
 */
function form_text_placeholder($name, $placeholder, $value, $disabled = false)
{
    $disabled = $disabled ? ' disabled="disabled"' : '';
    return form_element(
        '',
        '<input class="form-control" id="form_' . $name . '" type="text" name="' . $name
        . '" value="' . htmlspecialchars((string) $value) . '" placeholder="' . $placeholder
        . '" ' . $disabled . '/>'
    );
}

/**
 * Rendert ein Formular-Dateifeld
 *
 * @param string $name
 * @param string $label
 * @return string
 */
function form_file($name, $label)
{
    return form_element(
        $label,
        sprintf('<input id="form_%1$s" type="file" name="%1$s" />', $name),
        'form_' . $name
    );
}

            '<input class="form-control" id="form_%1$s" type="password" name="%1$s" minlength="%2$s" value="" autocomplete="%3$s"%4$s/>',
/**
 * Renders a password input with placeholder instead of label.
 *
 * @param string $name
 * @param string $placeholder
 * @param bool   $disabled
 * @return string
 */
function form_password_placeholder($name, $placeholder, $disabled = false)
{
    $disabled = $disabled ? ' disabled="disabled"' : '';
    return form_element(
        '',
        '<input class="form-control" id="form_' . $name . '" type="password" name="'
        . $name . '" value="" placeholder="' . $placeholder . '" ' . $disabled . '/>',
        'form_' . $name
    );
}

            $html .= '<option value="' . $key . '" selected="selected">' . $row . '</option>';
            $html .= '<option value="' . $key . '">' . $row . '</option>';
        $menu[] = toolbar_item_link(page_link_to($menu_page), '', $title, $menu_page == $page);
        // path              => name
        // path              => [name, permission]
            __($title),
use Engelsystem\Models\BaseModel;
use Illuminate\Support\Collection;
/**
 * Echoes given output and dies.
 *
 * @param string $output String to display
 */
function raw_output($output = '')
{
    echo $output;
    die();
}

/**
 * Helper function for transforming list of entities into array for select boxes.
 *
 * @param array|Collection $data       The data array
 * @param string           $key_name   name of the column to use as id/key
 * @param string           $value_name name of the column to use as displayed value
 *
 * @return array|Collection
 */
function select_array($data, $key_name, $value_name)
{
    if ($data instanceof Collection) {
        return $data->mapWithKeys(function (BaseModel $model) use ($key_name, $value_name) {
            return [$model->{$key_name} => $model->{$value_name}];
        });
    }

    $return = [];
    foreach ($data as $value) {
        $return[$value[$key_name]] = $value[$value_name];
    }
    return $return;
}

/**
 * Returns REQUEST value or default value (null) if not set.
 *
 * @param string $name
 * @param string|null $default_value
 * @return mixed|null
 */
function strip_request_tags($name, $default_value = null)
{
    $request = request();
    if ($request->has($name)) {
        return strip_tags($request->input($name));
    }

    return $default_value;
}

/**
 * Display muted (grey) text.
 *
 * @param string $text
 * @return string
 */
function mute($text)
{
    return '<span class="text-muted">' . $text . '</span>';
}

        . $label
        '<li><a class="dropdown-item{active}"{aria} href="{href}">{icon} {label}</a></li>',
            '{label}'  => $label,
            '{label}'   => $label,
        . ($angeltype->restricted ? icon('mortarboard-fill') : '') . $angeltype->name
    return page_with_title(sprintf(__('Delete angeltype %s'), $angeltype->name), [
    return page_with_title(sprintf(__('Edit %s'), $angeltype->name), [
                ? form_info(__('Name'), $angeltype->name)
            $member['dect'] = $member->contact->dect;
    return page_with_title(sprintf(__('Team %s'), $angeltype->name), [
        $info[] = $parsedown->parse($angeltype->description);
        __('Name')   => [$angeltype->contact_name, $angeltype->contact_name],
        __('DECT')   => config('enable_dect') ? [sprintf('<a href="tel:%s">%1$s</a>', $angeltype->contact_dect), $angeltype->contact_dect] : null,
        __('E-Mail') => [sprintf('<a href="mailto:%s">%1$s</a>', $angeltype->contact_email), $angeltype->contact_email],
            '<a href="' . url('/news/' . $first_news->id) . '"><strong>' . $first_news->title . '</strong></a>',
    $panel_body .= '<br>' . icon('list-task') . $shift['shifttype_name'];
        $panel_body .= ' (' . $shift['title'] . ')';
    $panel_body .= '<br>' . icon('pin-map-fill') . $shift['room_name'];
            . $needed_angels['need'] . ' &times; ' . $needed_angels['angeltype_name']
        $description .= $parsedown->parse($room->description);
            . description([__('DECT') => sprintf('<a href="tel:%s">%1$s</a>', $room->dect)]);
            $room->map_url
    return page_with_title(icon('pin-map-fill') . $room->name, [
        return '<a href="' . room_link($room) . '">' . icon('pin-map-fill') . $room->name . '</a>';
    return icon('pin-map-fill') . $room->name;
            $info_text = icon('info-circle') . $shift->title . '<br>';
                    sprintf(__('Become %s'), $angeltype->name),
            . $shift->shiftType->name;
            User_Nick_render($signoff_user),
        ShiftEntry_create_title() . ': ' . $shift->shiftType->name
        ShiftEntry_create_title() . ': ' . $shift->shiftType->name
        ShiftEntry_create_title() . ': ' . $shift->shiftType->name
            form_info(__('Location:'), $location),
            form_info(__('Title:'), $title),
            form_info(__('Type:'), $type),
        return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype->name . '</a>';
    return page_with_title(sprintf(__('Delete shifttype %s'), $shifttype->name), [
    return page_with_title($title, [
        $parsedown->parse($shifttype->description),
            . $shifttype->name
                ? '<a href="' . $shift->url . '">' . $shift->title . '</a>'
                : $shift->title)
                $angeltype->name
            $admin_shifttypes ? button(shifttype_link($shifttype), $shifttype->name) : '',
            $admin_rooms ? button(room_link($room), icon('pin-map-fill') . $room->name) : '',
            $parsedown->parse($shifttype->description),
            $parsedown->parse($shift->description),
        $shift->shiftType->name . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
        $users[$user_source->id] = User_Nick_render($user_source);
            form_info(__('Angeltype'), $angeltype->name),
    return page_with_title(sprintf(__('Become a %s'), $angeltype->name), [
                $this->hints[] = error($hint, true);
                $this->hints[] = info($hint, true);
        $u['first_name'] = $user->personalData->first_name;
        $u['last_name'] = $user->personalData->last_name;
        $u['dect'] = sprintf('<a href="tel:%s">%1$s</a>', $user->contact->dect);
        . '">' . $needed_angel_type['name'] . '</a>:</b> ';
    $shift_info = '<a href="' . shift_link($shift) . '">' . $shift->shiftType->name . '</a>';
        $shift_info .= '<br /><a href="' . shift_link($shift) . '">' . $shift->title . '</a>';
        $myshift['comment'] = $shift->user_comment;
                . '<p class="text-danger">' . __('Freeloaded') . ': ' . $shift->freeloaded_comment . '</p>';
        'comment'    => $worklog->comment . '<br>'
                            . ' <a href="tel:' . $user_source->contact->dect . '">'
                            . $user_source->contact->dect
                                . ' <a href="tel:' . $user_source->contact->mobile . '">'
                                . $user_source->contact->mobile
                icon('info-circle') . sprintf(
                    __('Your night shifts between %d and %d am count twice.'),
                ), true)
            . ($angeltype->pivot->supporter ? icon('patch-check') : '') . $angeltype->name
        $output[] = __($group->name);
            isset($config[$oauth->provider]['name'])
                ? $config[$oauth->provider]['name']
                : Str::ucfirst($oauth->provider)
    if ($user->state->arrived && config('enable_dect') && !$user->contact->dect) {
{{ __('notification.angeltype.added.introduction', [angeltype.name, url])|raw }}
{{ __('notification.angeltype.added.text', [angeltype.name, url])|raw }}
{{ __('notification.angeltype.confirmed.introduction', [angeltype.name, url])|raw }}
{{ __('notification.angeltype.confirmed.text', [angeltype.name, url])|raw }}
                <h2>{{ __('Welcome to the %s!', [config('name') ~ m.angel() ~ (config('app_name')|upper) ])|raw }}</h2>

Fixed code:
        sprintf(__('Delete angeltype %s'), htmlspecialchars($angeltype->name)),
        sprintf(__('Edit %s'), htmlspecialchars((string) $angeltype->name)),
        sprintf(__('Team %s'), htmlspecialchars($angeltype->name)),
            . htmlspecialchars($angeltype->name)
        htmlspecialchars($room->name),
            htmlspecialchars($angeltype_name),
                form_info(
                    '',
                    __('This description is for single shifts, otherwise please use the description in shift type.')
                ),
        htmlspecialchars($shift->shiftType->name),
        sprintf(__('Delete shifttype %s'), htmlspecialchars($shifttype->name)),
        htmlspecialchars($shifttype->name),
            . '">' . htmlspecialchars($user_angeltype->angelType->name)
        sprintf(__('Become a %s'), htmlspecialchars($angeltype->name)),
        sprintf(__('Delete %s'), htmlspecialchars($user_source->displayName)),
        sprintf(__('%s\'s vouchers'), htmlspecialchars($user_source->displayName)),
        htmlspecialchars($user_source->displayName),
    $maintenance = str_replace('%APP_NAME%', htmlspecialchars($app->get('config')->get('app_name')), $maintenance);
 * @param bool   $immediatelyRaw
function info($msg, $immediately = false, $immediatelyRaw = false)
    return alert(NotificationType::INFORMATION, $msg, $immediately, $immediatelyRaw);
 * @param bool   $immediatelyRaw
function warning($msg, $immediately = false, $immediatelyRaw = false)
    return alert(NotificationType::WARNING, $msg, $immediately, $immediatelyRaw);
 * @param bool   $immediatelyRaw
function error($msg, $immediately = false, $immediatelyRaw = false)
    return alert(NotificationType::ERROR, $msg, $immediately, $immediatelyRaw);
 * @param bool   $immediatelyRaw
function success($msg, $immediately = false, $immediatelyRaw = false)
    return alert(NotificationType::MESSAGE, $msg, $immediately, $immediatelyRaw);
 * @param bool             $immediatelyRaw
 *
 * @see \Engelsystem\Controllers\HasUserNotifications
 *
function alert(NotificationType $type, $msg, $immediately = false, $immediatelyRaw = false)
        $msg = $immediatelyRaw ? $msg : htmlspecialchars($msg);
            'dect'        => sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars((string) $usr->contact->dect)),
                ? sprintf('<a href="mailto:%s">%1$s</a>', htmlspecialchars((string) $email))
                $privileges_html[] = htmlspecialchars($privilege['name']);
                'name'       => htmlspecialchars($group->name),
                            htmlspecialchars($privilege->description . ' (' . $privilege->name . ')'),
                            'privilege-' . htmlspecialchars($privilege->name)
                    $html .= page_with_title(__('Edit group') . ' ' . htmlspecialchars($group->name), [
                        . ($shift['title'] ? '<br />' . htmlspecialchars($shift['title']) : ''),
                htmlspecialchars($type->name),
        $html .= '<br><br>';
        $html .= '  <tr><td>' . __('Nickname') . '</td><td>'
            . '<input size="40" name="eNick" value="' . htmlspecialchars($user_source->name) . '" class="form-control" maxlength="24">'
            . '</td></tr>' . "\n";
            $html .= '  <tr><td>' . __('Prename') . '</td><td>'
                . '<input size="40" name="eName" value="' . htmlspecialchars((string) $user_source->personalData->last_name) . '" class="form-control" maxlength="64">'
                . '</td></tr>' . "\n";
            $html .= '  <tr><td>' . __('Last name') . '</td><td>'
                . '<input size="40" name="eVorname" value="' . htmlspecialchars((string) $user_source->personalData->first_name) . '" class="form-control" maxlength="64">'
                . '</td></tr>' . "\n";
        $html .= '  <tr><td>' . __('Mobile') . '</td><td>'
            . '<input type= "tel" size="40" name="eHandy" value="' . htmlspecialchars((string) $user_source->contact->mobile) . '" class="form-control" maxlength="40">'
            . '</td></tr>' . "\n";
            $html .= '  <tr><td>' . __('DECT') . '</td><td>'
                . '<input size="40" name="eDECT" value="' . htmlspecialchars((string) $user_source->contact->dect) . '" class="form-control" maxlength="40">'
                . '</td></tr>' . "\n";
            $html .= '  <tr><td>' . __('settings.profile.email') . '</td><td>'
                . '<input type="email" size="40" name="eemail" value="' . htmlspecialchars($user_source->email) . '" class="form-control" maxlength="254">'
                . '</td></tr>' . "\n";
        $html .= '</table>' . "\n" . '<br>' . "\n";
        $html .= '<hr>';
        $html .= '  <tr><td>' . __('Password') . '</td><td>'
            . '<input type="password" size="40" name="new_pw" value="" class="form-control" autocomplete="new-password">'
            . '</td></tr>' . "\n";
        $html .= '  <tr><td>' . __('Confirm password') . '</td><td>'
            . '<input type="password" size="40" name="new_pw2" value="" class="form-control" autocomplete="new-password">'
            . '</td></tr>' . "\n";

        $html .= '</table>' . "\n" . '<br>' . "\n";
        $html .= '<hr>';
                    . ' /><label class="form-check-label" for="' . $group->id . '">'
                    . htmlspecialchars($group->name)
                    . '</label></div>';
            $html .= '<hr>';
        $angel_types[$angel_type->id] = htmlspecialchars($angel_type->name)
                            [htmlspecialchars(config('app_name'))]
                            . (config('privacy_email') ? ' ' . __('To withdraw your approval, send an email to <a href="mailto:%s">%1$s</a>.', [htmlspecialchars(config('privacy_email'))]) : ''),
            . '><label class="form-check-label" for="' . $id . '">' . htmlspecialchars($i['name']) . '</label>'
        . '<input class="form-check-input" type="checkbox" id="' . $html_id . '" '
        . 'name="' . htmlspecialchars($name) . '" value="' . $value . '" '
 * Renders a radio button
            '<input class="form-control" id="form_%1$s" type="password" name="%1$s" minlength="%2$s" value="" autocomplete="%3$s" %4$s>',
            $html .= '<option value="' . htmlspecialchars($key) . '" selected="selected">'
                . htmlspecialchars($row)
                . '</option>';
            $html .= '<option value="' . htmlspecialchars($key) . '">'
                . htmlspecialchars($row)
                . '</option>';
        $menu[] = toolbar_item_link(
            page_link_to($menu_page),
            '',
            $title,
            $menu_page == $page
        );
        // Examples:
        // path              => name,
        // path              => [name, permission],

            htmlspecialchars(__($title)),
        . htmlspecialchars($label)
        '<li><a class="dropdown-item{active}" {aria} href="{href}">{icon} {label}</a></li>',
            '{label}'  => htmlspecialchars($label),
            '{label}'   => htmlspecialchars($label),
        . ($angeltype->restricted ? icon('mortarboard-fill') : '') . htmlspecialchars($angeltype->name)
    return page_with_title(sprintf(__('Delete angeltype %s'), htmlspecialchars($angeltype->name)), [
    return page_with_title(sprintf(__('Edit %s'), htmlspecialchars((string) $angeltype->name)), [
                ? form_info(__('Name'), htmlspecialchars($angeltype->name))
            $member['dect'] = htmlspecialchars((string) $member->contact->dect);
    return page_with_title(sprintf(__('Team %s'), htmlspecialchars($angeltype->name)), [
        $info[] = $parsedown->parse(htmlspecialchars($angeltype->description));
        __('Name')  => [
            htmlspecialchars($angeltype->contact_name),
            htmlspecialchars($angeltype->contact_name),
        ],
        __('DECT')  => config('enable_dect')
            ? [
                sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars($angeltype->contact_dect)),
                htmlspecialchars($angeltype->contact_dect),
            ]
            : null,
        __('E-Mail') => [
            sprintf('<a href="mailto:%s">%1$s</a>', htmlspecialchars($angeltype->contact_email)),
            htmlspecialchars($angeltype->contact_email),
        ],
            '<a href="' . url('/news/' . $first_news->id) . '">'
            . '<strong>' . htmlspecialchars($first_news->title) . '</strong>'
            . '</a>',
    $panel_body .= '<br>' . icon('list-task') . htmlspecialchars($shift['shifttype_name']);
        $panel_body .= ' (' . htmlspecialchars($shift['title']) . ')';
    $panel_body .= '<br>' . icon('pin-map-fill') . htmlspecialchars($shift['room_name']);
            . $needed_angels['need'] . ' &times; ' . htmlspecialchars($needed_angels['angeltype_name'])
        $description .= $parsedown->parse(htmlspecialchars($room->description));
            . description([__('DECT') => sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars($room->dect))]);
            htmlspecialchars($room->map_url)
    return page_with_title(icon('pin-map-fill') . htmlspecialchars($room->name), [
        return '<a href="' . room_link($room) . '">' . icon('pin-map-fill') . htmlspecialchars($room->name) . '</a>';
    return icon('pin-map-fill') . htmlspecialchars($room->name);
            $info_text = icon('info-circle') . htmlspecialchars($shift->title) . '<br>';
                    sprintf(__('Become %s'), htmlspecialchars($angeltype->name)),
            . htmlspecialchars($shift->shiftType->name);
            $signoff_user->displayName,
        ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
        ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
        ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
            form_info(__('Location:'), htmlspecialchars($location)),
            form_info(__('Title:'), htmlspecialchars($title)),
            form_info(__('Type:'), htmlspecialchars($type)),
        return '<a href="' . shifttype_link($shifttype) . '">' . htmlspecialchars($shifttype->name) . '</a>';
    return page_with_title(sprintf(__('Delete shifttype %s'), htmlspecialchars($shifttype->name)), [
    return page_with_title(htmlspecialchars($title), [
        $parsedown->parse(htmlspecialchars($shifttype->description)),
            . htmlspecialchars($shifttype->name)
                ? '<a href="' . htmlspecialchars($shift->url) . '">' . htmlspecialchars($shift->title) . '</a>'
                : htmlspecialchars($shift->title))
                htmlspecialchars($angeltype->name)
            $admin_shifttypes
                ? button(shifttype_link($shifttype), htmlspecialchars($shifttype->name))
                : '',
            $admin_rooms
                ? button(
                    room_link($room),
                    icon('pin-map-fill') . htmlspecialchars($room->name)
                )
                : '',
            $parsedown->parse(htmlspecialchars($shifttype->description)),
            $parsedown->parse(htmlspecialchars($shift->description)),
        htmlspecialchars($shift->shiftType->name)
        . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
        $users[$user_source->id] = $user_source->displayName;
            form_info(__('Angeltype'), htmlspecialchars($angeltype->name)),
    return page_with_title(sprintf(__('Become a %s'), htmlspecialchars($angeltype->name)), [
                $this->hints[] = error($hint, true, true);
                $this->hints[] = info($hint, true, true);
        $u['first_name'] = htmlspecialchars((string) $user->personalData->first_name);
        $u['last_name'] = htmlspecialchars((string) $user->personalData->last_name);
        $u['dect'] = sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars((string) $user->contact->dect));
        . '">' . htmlspecialchars($needed_angel_type['name']) . '</a>:</b> ';
    $shift_info = '<a href="' . shift_link($shift) . '">' . htmlspecialchars($shift->shiftType->name) . '</a>';
        $shift_info .= '<br /><a href="' . shift_link($shift) . '">' . htmlspecialchars($shift->title) . '</a>';
        $myshift['comment'] = htmlspecialchars($shift->user_comment);
                . '<p class="text-danger">'
                . __('Freeloaded') . ': ' . htmlspecialchars($shift->freeloaded_comment)
                . '</p>';
        'comment'    => htmlspecialchars($worklog->comment) . '<br>'
                            . ' <a href="tel:' . htmlspecialchars($user_source->contact->dect) . '">'
                            . htmlspecialchars($user_source->contact->dect)
                                . ' <a href="tel:' . htmlspecialchars($user_source->contact->mobile) . '">'
                                . htmlspecialchars($user_source->contact->mobile)
                sprintf(
                    icon('info-circle') . __('Your night shifts between %d and %d am count twice.'),
                true,
                ), true, true)
            . ($angeltype->pivot->supporter ? icon('patch-check') : '') . htmlspecialchars($angeltype->name)
        $output[] = __(htmlspecialchars($group->name));
            htmlspecialchars(
                isset($config[$oauth->provider]['name'])
                    ? $config[$oauth->provider]['name']
                    : Str::ucfirst($oauth->provider)
            )
    if (
        $user->state->arrived
        && config('enable_dect') && !$user->contact->dect
    ) {
{{ __('notification.angeltype.added.introduction', [angeltype.name|e, url])|raw }}
{{ __('notification.angeltype.added.text', [angeltype.name|e, url])|raw }}
{{ __('notification.angeltype.confirmed.introduction', [angeltype.name|e, url])|raw }}
{{ __('notification.angeltype.confirmed.text', [angeltype.name|e, url])|raw }}
                <h2>{{ __('Welcome to the %s!', [config('name')|e ~ m.angel() ~ (config('app_name')|upper|e) ])|raw }}</h2>