Escape text outputs in includes

This commit is contained in:
Igor Scheller 2023-12-04 23:33:07 +01:00
parent b8095492ec
commit efda1ffc1c
31 changed files with 213 additions and 273 deletions

View File

@ -72,7 +72,7 @@ function angeltype_delete_controller()
} }
return [ return [
sprintf(__('Delete angeltype %s'), $angeltype->name), sprintf(__('Delete angeltype %s'), htmlspecialchars($angeltype->name)),
AngelType_delete_view($angeltype), AngelType_delete_view($angeltype),
]; ];
} }
@ -152,7 +152,7 @@ function angeltype_edit_controller()
} }
return [ return [
sprintf(__('Edit %s'), $angeltype->name), sprintf(__('Edit %s'), htmlspecialchars((string) $angeltype->name)),
AngelType_edit_view($angeltype, $supporter_mode), AngelType_edit_view($angeltype, $supporter_mode),
]; ];
} }
@ -193,7 +193,7 @@ function angeltype_controller()
$isSupporter = !is_null($user_angeltype) && $user_angeltype->supporter; $isSupporter = !is_null($user_angeltype) && $user_angeltype->supporter;
return [ return [
sprintf(__('Team %s'), $angeltype->name), sprintf(__('Team %s'), htmlspecialchars($angeltype->name)),
AngelType_view( AngelType_view(
$angeltype, $angeltype,
$members, $members,
@ -323,7 +323,7 @@ function angeltypes_list_controller()
$angeltype->name = '<a href="' $angeltype->name = '<a href="'
. page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]) . page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id])
. '">' . '">'
. $angeltype->name . htmlspecialchars($angeltype->name)
. '</a>'; . '</a>';
$angeltype->actions = table_buttons($actions); $angeltype->actions = table_buttons($actions);

View File

@ -53,7 +53,7 @@ function room_controller(): array
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter); $shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
return [ return [
$room->name, htmlspecialchars($room->name),
Room_view($room, $shiftsFilterRenderer, $shiftCalendarRenderer), Room_view($room, $shiftsFilterRenderer, $shiftCalendarRenderer),
]; ];
} }

View File

@ -194,7 +194,7 @@ function shift_edit_controller()
foreach ($angeltypes as $angeltype_id => $angeltype_name) { foreach ($angeltypes as $angeltype_id => $angeltype_name) {
$angel_types_spinner .= form_spinner( $angel_types_spinner .= form_spinner(
'angeltype_count_' . $angeltype_id, 'angeltype_count_' . $angeltype_id,
$angeltype_name, htmlspecialchars($angeltype_name),
$needed_angel_types[$angeltype_id] $needed_angel_types[$angeltype_id]
); );
} }
@ -213,7 +213,10 @@ function shift_edit_controller()
form_text('start', __('Start:'), $start->format('Y-m-d H:i')), form_text('start', __('Start:'), $start->format('Y-m-d H:i')),
form_text('end', __('End:'), $end->format('Y-m-d H:i')), form_text('end', __('End:'), $end->format('Y-m-d H:i')),
form_textarea('description', __('Additional description'), $description), form_textarea('description', __('Additional description'), $description),
form_info('', __('This description is for single shifts, otherwise please use the description in shift type.')), form_info(
'',
__('This description is for single shifts, otherwise please use the description in shift type.')
),
'<h2>' . __('Needed angels') . '</h2>', '<h2>' . __('Needed angels') . '</h2>',
$angel_types_spinner, $angel_types_spinner,
form_submit('submit', __('Save')), form_submit('submit', __('Save')),
@ -338,7 +341,7 @@ function shift_controller()
} }
return [ return [
$shift->shiftType->name, htmlspecialchars($shift->shiftType->name),
Shift_view($shift, $shifttype, $room, $angeltypes, $shift_signup_state), Shift_view($shift, $shifttype, $room, $angeltypes, $shift_signup_state),
]; ];
} }

View File

@ -33,7 +33,7 @@ function shifttype_delete_controller()
} }
return [ return [
sprintf(__('Delete shifttype %s'), $shifttype->name), sprintf(__('Delete shifttype %s'), htmlspecialchars($shifttype->name)),
ShiftType_delete_view($shifttype), ShiftType_delete_view($shifttype),
]; ];
} }
@ -110,7 +110,7 @@ function shifttype_controller()
$shifttype = ShiftType::findOrFail($request->input('shifttype_id')); $shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
return [ return [
$shifttype->name, htmlspecialchars($shifttype->name),
ShiftType_view($shifttype), ShiftType_view($shifttype),
]; ];
} }

View File

@ -39,7 +39,7 @@ function user_angeltypes_unconfirmed_hint()
foreach ($unconfirmed_user_angeltypes as $user_angeltype) { foreach ($unconfirmed_user_angeltypes as $user_angeltype) {
$unconfirmed_links[] = '<a href="' $unconfirmed_links[] = '<a href="'
. page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $user_angeltype->angel_type_id]) . page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $user_angeltype->angel_type_id])
. '">' . $user_angeltype->angelType->name . '">' . htmlspecialchars($user_angeltype->angelType->name)
. ' (+' . $user_angeltype->count . ')' . ' (+' . $user_angeltype->count . ')'
. '</a>'; . '</a>';
} }
@ -438,7 +438,7 @@ function user_angeltype_join_controller(AngelType $angeltype)
} }
return [ return [
sprintf(__('Become a %s'), $angeltype->name), sprintf(__('Become a %s'), htmlspecialchars($angeltype->name)),
UserAngelType_join_view($user, $angeltype), UserAngelType_join_view($user, $angeltype),
]; ];
} }

View File

@ -91,7 +91,7 @@ function user_delete_controller()
} }
return [ return [
sprintf(__('Delete %s'), $user_source->displayName), sprintf(__('Delete %s'), htmlspecialchars($user_source->displayName)),
User_delete_view($user_source), User_delete_view($user_source),
]; ];
} }
@ -182,7 +182,7 @@ function user_edit_vouchers_controller()
} }
return [ return [
sprintf(__('%s\'s vouchers'), $user_source->displayName), sprintf(__('%s\'s vouchers'), htmlspecialchars($user_source->displayName)),
User_edit_vouchers_view($user_source), User_edit_vouchers_view($user_source),
]; ];
} }
@ -244,7 +244,7 @@ function user_controller()
} }
return [ return [
$user_source->displayName, htmlspecialchars($user_source->displayName),
User_view( User_view(
$user_source, $user_source,
auth()->can('admin_user'), auth()->can('admin_user'),

View File

@ -23,7 +23,7 @@ if ($app->get('config')->get('maintenance')) {
http_response_code(503); http_response_code(503);
$url = $app->get(UrlGeneratorInterface::class); $url = $app->get(UrlGeneratorInterface::class);
$maintenance = file_get_contents(__DIR__ . '/../resources/views/layouts/maintenance.html'); $maintenance = file_get_contents(__DIR__ . '/../resources/views/layouts/maintenance.html');
$maintenance = str_replace('%APP_NAME%', $app->get('config')->get('app_name'), $maintenance); $maintenance = str_replace('%APP_NAME%', htmlspecialchars($app->get('config')->get('app_name')), $maintenance);
$maintenance = str_replace('%ASSETS_PATH%', $url->to(''), $maintenance); $maintenance = str_replace('%ASSETS_PATH%', $url->to(''), $maintenance);
echo $maintenance; echo $maintenance;
die(); die();

View File

@ -17,11 +17,12 @@ function msg()
* *
* @param string $msg * @param string $msg
* @param bool $immediately * @param bool $immediately
* @param bool $immediatelyRaw
* @return string * @return string
*/ */
function info($msg, $immediately = false) function info($msg, $immediately = false, $immediatelyRaw = false)
{ {
return alert(NotificationType::INFORMATION, $msg, $immediately); return alert(NotificationType::INFORMATION, $msg, $immediately, $immediatelyRaw);
} }
/** /**
@ -29,11 +30,12 @@ function info($msg, $immediately = false)
* *
* @param string $msg * @param string $msg
* @param bool $immediately * @param bool $immediately
* @param bool $immediatelyRaw
* @return string * @return string
*/ */
function warning($msg, $immediately = false) function warning($msg, $immediately = false, $immediatelyRaw = false)
{ {
return alert(NotificationType::WARNING, $msg, $immediately); return alert(NotificationType::WARNING, $msg, $immediately, $immediatelyRaw);
} }
/** /**
@ -41,11 +43,12 @@ function warning($msg, $immediately = false)
* *
* @param string $msg * @param string $msg
* @param bool $immediately * @param bool $immediately
* @param bool $immediatelyRaw
* @return string * @return string
*/ */
function error($msg, $immediately = false) function error($msg, $immediately = false, $immediatelyRaw = false)
{ {
return alert(NotificationType::ERROR, $msg, $immediately); return alert(NotificationType::ERROR, $msg, $immediately, $immediatelyRaw);
} }
/** /**
@ -53,24 +56,27 @@ function error($msg, $immediately = false)
* *
* @param string $msg * @param string $msg
* @param bool $immediately * @param bool $immediately
* @param bool $immediatelyRaw
* @return string * @return string
*/ */
function success($msg, $immediately = false) function success($msg, $immediately = false, $immediatelyRaw = false)
{ {
return alert(NotificationType::MESSAGE, $msg, $immediately); return alert(NotificationType::MESSAGE, $msg, $immediately, $immediatelyRaw);
} }
/** /**
* Renders an alert message with the given alert-* class or sets it in session * Renders an alert message with the given alert-* class or sets it in session
* *
* @see \Engelsystem\Controllers\HasUserNotifications
*
* @param NotificationType $type * @param NotificationType $type
* @param string $msg * @param string $msg
* @param bool $immediately * @param bool $immediately
* @param bool $immediatelyRaw
* @return string * @return string
*
* @see \Engelsystem\Controllers\HasUserNotifications
*
*/ */
function alert(NotificationType $type, $msg, $immediately = false) function alert(NotificationType $type, $msg, $immediately = false, $immediatelyRaw = false)
{ {
if (empty($msg)) { if (empty($msg)) {
return ''; return '';
@ -87,6 +93,7 @@ function alert(NotificationType $type, $msg, $immediately = false)
['danger', 'warning', 'info', 'success'], ['danger', 'warning', 'info', 'success'],
$type->value $type->value
); );
$msg = $immediatelyRaw ? $msg : htmlspecialchars($msg);
return '<div class="alert alert-' . $type . '" role="alert">' . $msg . '</div>'; return '<div class="alert alert-' . $type . '" role="alert">' . $msg . '</div>';
} }

View File

@ -100,9 +100,9 @@ function admin_free()
'name' => User_Nick_render($usr) . User_Pronoun_render($usr), 'name' => User_Nick_render($usr) . User_Pronoun_render($usr),
'shift_state' => User_shift_state_render($usr), 'shift_state' => User_shift_state_render($usr),
'last_shift' => User_last_shift_render($usr), 'last_shift' => User_last_shift_render($usr),
'dect' => sprintf('<a href="tel:%s">%1$s</a>', $usr->contact->dect), 'dect' => sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars((string) $usr->contact->dect)),
'email' => $usr->settings->email_human 'email' => $usr->settings->email_human
? sprintf('<a href="mailto:%s">%1$s</a>', $email) ? sprintf('<a href="mailto:%s">%1$s</a>', htmlspecialchars((string) $email))
: icon('eye-slash'), : icon('eye-slash'),
'actions' => 'actions' =>
auth()->can('admin_user') auth()->can('admin_user')

View File

@ -31,11 +31,11 @@ function admin_groups()
$privileges_html = []; $privileges_html = [];
foreach ($privileges as $privilege) { foreach ($privileges as $privilege) {
$privileges_html[] = $privilege['name']; $privileges_html[] = htmlspecialchars($privilege['name']);
} }
$groups_table[] = [ $groups_table[] = [
'name' => $group->name, 'name' => htmlspecialchars($group->name),
'privileges' => join(', ', $privileges_html), 'privileges' => join(', ', $privileges_html),
'actions' => button( 'actions' => button(
page_link_to( page_link_to(
@ -72,15 +72,15 @@ function admin_groups()
foreach ($privileges as $privilege) { foreach ($privileges as $privilege) {
$privileges_form[] = form_checkbox( $privileges_form[] = form_checkbox(
'privileges[]', 'privileges[]',
$privilege->description . ' (' . $privilege->name . ')', htmlspecialchars($privilege->description . ' (' . $privilege->name . ')'),
$privilege->selected != '', $privilege->selected != '',
$privilege->id, $privilege->id,
'privilege-' . $privilege->name 'privilege-' . htmlspecialchars($privilege->name)
); );
} }
$privileges_form[] = form_submit('submit', __('Save')); $privileges_form[] = form_submit('submit', __('Save'));
$html .= page_with_title(__('Edit group') . ' ' . $group->name, [ $html .= page_with_title(__('Edit group') . ' ' . htmlspecialchars($group->name), [
form( form(
$privileges_form, $privileges_form,
page_link_to('admin_groups', ['action' => 'save', 'id' => $group->id]) page_link_to('admin_groups', ['action' => 'save', 'id' => $group->id])

View File

@ -333,7 +333,7 @@ function admin_shifts()
. Room_name_render(Room::find($shift['room_id'])), . Room_name_render(Room::find($shift['room_id'])),
'title' => 'title' =>
ShiftType_name_render(ShiftType::find($shifttype_id)) ShiftType_name_render(ShiftType::find($shifttype_id))
. ($shift['title'] ? '<br />' . $shift['title'] : ''), . ($shift['title'] ? '<br />' . htmlspecialchars($shift['title']) : ''),
'needed_angels' => '', 'needed_angels' => '',
]; ];
foreach ($types as $type) { foreach ($types as $type) {
@ -443,7 +443,7 @@ function admin_shifts()
$angel_types .= '<div class="col-sm-6 col-md-8 col-lg-6 col-xl-4 col-xxl-3">' $angel_types .= '<div class="col-sm-6 col-md-8 col-lg-6 col-xl-4 col-xxl-3">'
. form_spinner( . form_spinner(
'angeltype_count_' . $type->id, 'angeltype_count_' . $type->id,
$type->name, htmlspecialchars($type->name),
$needed_angel_types[$type->id], $needed_angel_types[$type->id],
[ [
'radio-name' => 'angelmode', 'radio-name' => 'angelmode',

View File

@ -48,7 +48,7 @@ function admin_user()
$html .= ' ' . __('If the angel is active, it can claim a goodie. If goodie is set to \'Yes\', the angel already got their goodie.'); $html .= ' ' . __('If the angel is active, it can claim a goodie. If goodie is set to \'Yes\', the angel already got their goodie.');
} }
} }
$html .= '<br /><br />'; $html .= '<br><br>';
$html .= '<form action="' $html .= '<form action="'
. page_link_to('admin_user', ['action' => 'save', 'id' => $user_id]) . page_link_to('admin_user', ['action' => 'save', 'id' => $user_id])
. '" method="post">' . "\n"; . '" method="post">' . "\n";
@ -57,20 +57,32 @@ function admin_user()
$html .= '<input type="hidden" name="Type" value="Normal">' . "\n"; $html .= '<input type="hidden" name="Type" value="Normal">' . "\n";
$html .= '<tr><td>' . "\n"; $html .= '<tr><td>' . "\n";
$html .= '<table>' . "\n"; $html .= '<table>' . "\n";
$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>' . __('Nickname') . '</td><td>'
. '<input size="40" name="eNick" value="' . htmlspecialchars($user_source->name) . '" class="form-control" maxlength="24">'
. '</td></tr>' . "\n";
$html .= ' <tr><td>' . __('Last login') . '</td><td><p class="help-block">' $html .= ' <tr><td>' . __('Last login') . '</td><td><p class="help-block">'
. ($user_source->last_login_at ? $user_source->last_login_at->format(__('Y-m-d H:i')) : '-') . ($user_source->last_login_at ? $user_source->last_login_at->format(__('Y-m-d H:i')) : '-')
. '</p></td></tr>' . "\n"; . '</p></td></tr>' . "\n";
if (config('enable_user_name')) { if (config('enable_user_name')) {
$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>' . __('Prename') . '</td><td>'
$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"; . '<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="' . $user_source->contact->mobile . '" class="form-control" maxlength="40"></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";
if (config('enable_dect')) { if (config('enable_dect')) {
$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>' . __('DECT') . '</td><td>'
. '<input size="40" name="eDECT" value="' . htmlspecialchars((string) $user_source->contact->dect) . '" class="form-control" maxlength="40">'
. '</td></tr>' . "\n";
} }
if ($user_source->settings->email_human) { if ($user_source->settings->email_human) {
$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 .= ' <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";
} }
if ($goodie_tshirt) { if ($goodie_tshirt) {
$html .= ' <tr><td>' . __('user.shirt_size') . '</td><td>' $html .= ' <tr><td>' . __('user.shirt_size') . '</td><td>'
@ -120,11 +132,11 @@ function admin_user()
$html .= '</table>' . "\n" . '</td><td></td></tr>'; $html .= '</table>' . "\n" . '</td><td></td></tr>';
$html .= '</td></tr>' . "\n"; $html .= '</td></tr>' . "\n";
$html .= '</table>' . "\n" . '<br />' . "\n"; $html .= '</table>' . "\n" . '<br>' . "\n";
$html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n"; $html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n";
$html .= '</form>'; $html .= '</form>';
$html .= '<hr />'; $html .= '<hr>';
$html .= form_info('', __('Please visit the angeltypes page or the users profile to manage the users angeltypes.')); $html .= form_info('', __('Please visit the angeltypes page or the users profile to manage the users angeltypes.'));
@ -133,14 +145,18 @@ function admin_user()
. '" method="post">' . "\n"; . '" method="post">' . "\n";
$html .= form_csrf(); $html .= form_csrf();
$html .= '<table>' . "\n"; $html .= '<table>' . "\n";
$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>' . __('Password') . '</td><td>'
$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"; . '<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 .= '</table>' . "\n" . '<br>' . "\n";
$html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n"; $html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n";
$html .= '</form>'; $html .= '</form>';
$html .= '<hr />'; $html .= '<hr>';
/** @var Group $my_highest_group */ /** @var Group $my_highest_group */
$my_highest_group = $user->groups()->orderByDesc('id')->first(); $my_highest_group = $user->groups()->orderByDesc('id')->first();
@ -168,7 +184,9 @@ function admin_user()
$html .= '<div class="form-check">' $html .= '<div class="form-check">'
. '<input class="form-check-input" type="checkbox" id="' . $group->id . '" name="groups[]" value="' . $group->id . '" ' . '<input class="form-check-input" type="checkbox" id="' . $group->id . '" name="groups[]" value="' . $group->id . '" '
. ($group->selected ? ' checked="checked"' : '') . ($group->selected ? ' checked="checked"' : '')
. ' /><label class="form-check-label" for="' . $group->id . '">' . $group->name . '</label></div>'; . ' /><label class="form-check-label" for="' . $group->id . '">'
. htmlspecialchars($group->name)
. '</label></div>';
} }
$html .= '</div><br>'; $html .= '</div><br>';
@ -176,7 +194,7 @@ function admin_user()
$html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n"; $html .= '<button type="submit" class="btn btn-primary">' . __('form.save') . '</button>' . "\n";
$html .= '</form>'; $html .= '</form>';
$html .= '<hr />'; $html .= '<hr>';
} }
$html .= buttons([ $html .= buttons([

View File

@ -86,7 +86,7 @@ function guest_register()
if ($angel_type->hide_register) { if ($angel_type->hide_register) {
continue; continue;
} }
$angel_types[$angel_type->id] = $angel_type->name $angel_types[$angel_type->id] = htmlspecialchars($angel_type->name)
. ($angel_type->restricted ? ' (' . __('Requires introduction') . ')' : ''); . ($angel_type->restricted ? ' (' . __('Requires introduction') . ')' : '');
if (!$angel_type->restricted) { if (!$angel_type->restricted) {
$selected_angel_types[] = $angel_type->id; $selected_angel_types[] = $angel_type->id;
@ -436,7 +436,7 @@ function guest_register()
'email_shiftinfo', 'email_shiftinfo',
__( __(
'settings.profile.email_shiftinfo', 'settings.profile.email_shiftinfo',
[config('app_name')] [htmlspecialchars(config('app_name'))]
), ),
$email_shiftinfo $email_shiftinfo
), ),
@ -459,7 +459,7 @@ function guest_register()
form_checkbox( form_checkbox(
'email_goody', 'email_goody',
__('To receive vouchers, give consent that nick, email address, worked hours and shirt size will be stored until the next similar event.') __('To receive vouchers, give consent that nick, email address, worked hours and shirt size will be stored until the next similar event.')
. (config('privacy_email') ? ' ' . __('To withdraw your approval, send an email to <a href="mailto:%s">%1$s</a>.', [config('privacy_email')]) : ''), . (config('privacy_email') ? ' ' . __('To withdraw your approval, send an email to <a href="mailto:%s">%1$s</a>.', [htmlspecialchars(config('privacy_email'))]) : ''),
$email_goody $email_goody
) : '', ) : '',
]), ]),

View File

@ -377,15 +377,6 @@ function ical_hint()
. '<p id="collapseApiKey" class="collapse"><code>' . $user->api_key . '</code></p>'; . '<p id="collapseApiKey" class="collapse"><code>' . $user->api_key . '</code></p>';
} }
/**
* @param array $array
* @return array
*/
function get_ids_from_array($array)
{
return $array['id'];
}
/** /**
* @param array $items * @param array $items
* @param array $selected * @param array $selected
@ -418,7 +409,7 @@ function make_select($items, $selected, $name, $title = null, $ownSelect = [])
$htmlItems[] = '<div class="form-check">' $htmlItems[] = '<div class="form-check">'
. '<input class="form-check-input" type="checkbox" id="' . $id . '" name="' . $name . '[]" value="' . $i['id'] . '" ' . '<input class="form-check-input" type="checkbox" id="' . $id . '" name="' . $name . '[]" value="' . $i['id'] . '" '
. (in_array($i['id'], $selected) ? ' checked="checked"' : '') . (in_array($i['id'], $selected) ? ' checked="checked"' : '')
. '><label class="form-check-label" for="' . $id . '">' . $i['name'] . '</label>' . '><label class="form-check-label" for="' . $id . '">' . htmlspecialchars($i['name']) . '</label>'
. (!isset($i['enabled']) || $i['enabled'] ? '' : icon('mortarboard-fill')) . (!isset($i['enabled']) || $i['enabled'] ? '' : icon('mortarboard-fill'))
. '</div>'; . '</div>';
} }

View File

@ -128,14 +128,15 @@ function form_checkbox($name, $label, $selected, $value = 'checked', $html_id =
} }
return '<div class="form-check">' return '<div class="form-check">'
. '<input class="form-check-input" type="checkbox" id="' . $html_id . '" name="' . $name . '" value="' . htmlspecialchars((string) $value) . '" ' . '<input class="form-check-input" type="checkbox" id="' . $html_id . '" '
. 'name="' . htmlspecialchars($name) . '" value="' . $value . '" '
. ($selected ? ' checked="checked"' : '') . ' /><label class="form-check-label" for="' . $html_id . '">' . ($selected ? ' checked="checked"' : '') . ' /><label class="form-check-label" for="' . $html_id . '">'
. $label . $label
. '</label></div>'; . '</label></div>';
} }
/** /**
* Rendert einen Radio * Renders a radio button
* *
* @param string $name * @param string $name
* @param string $label * @param string $label
@ -232,26 +233,6 @@ function form_text($name, $label, $value, $disabled = false, $maxlength = null,
); );
} }
/**
* 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-Emailfeld * Rendert ein Formular-Emailfeld
* *
@ -277,22 +258,6 @@ function form_email($name, $label, $value, $disabled = false, $autocomplete = nu
); );
} }
/**
* 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
);
}
/** /**
* Rendert ein Formular-Passwortfeld * Rendert ein Formular-Passwortfeld
* *
@ -308,7 +273,7 @@ function form_password($name, $label, $autocomplete, $disabled = false)
return form_element( return form_element(
$label, $label,
sprintf( sprintf(
'<input class="form-control" id="form_%1$s" type="password" name="%1$s" minlength="%2$s" value="" autocomplete="%3$s"%4$s/>', '<input class="form-control" id="form_%1$s" type="password" name="%1$s" minlength="%2$s" value="" autocomplete="%3$s" %4$s>',
$name, $name,
config('min_password_length'), config('min_password_length'),
$autocomplete, $autocomplete,
@ -318,25 +283,6 @@ function form_password($name, $label, $autocomplete, $disabled = false)
); );
} }
/**
* 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
);
}
/** /**
* Rendert ein Formular-Textfeld * Rendert ein Formular-Textfeld
* *
@ -463,9 +409,13 @@ function html_select_key($dom_id, $name, $rows, $selected, $selectText = '')
} }
foreach ($rows as $key => $row) { foreach ($rows as $key => $row) {
if (($key == $selected) || ($row === $selected)) { if (($key == $selected) || ($row === $selected)) {
$html .= '<option value="' . $key . '" selected="selected">' . $row . '</option>'; $html .= '<option value="' . htmlspecialchars($key) . '" selected="selected">'
. htmlspecialchars($row)
. '</option>';
} else { } else {
$html .= '<option value="' . $key . '">' . $row . '</option>'; $html .= '<option value="' . htmlspecialchars($key) . '">'
. htmlspecialchars($row)
. '</option>';
} }
} }
$html .= '</select>'; $html .= '</select>';

View File

@ -76,15 +76,22 @@ function make_navigation()
} }
$title = ((array) $options)[0]; $title = ((array) $options)[0];
$menu[] = toolbar_item_link(page_link_to($menu_page), '', $title, $menu_page == $page); $menu[] = toolbar_item_link(
page_link_to($menu_page),
'',
$title,
$menu_page == $page
);
} }
$menu = make_room_navigation($menu); $menu = make_room_navigation($menu);
$admin_menu = []; $admin_menu = [];
$admin_pages = [ $admin_pages = [
// path => name // Examples:
// path => [name, permission] // path => name,
// path => [name, permission],
'admin_arrive' => 'Arrive angels', 'admin_arrive' => 'Arrive angels',
'admin_active' => 'Active angels', 'admin_active' => 'Active angels',
'users' => ['All Angels', 'admin_user'], 'users' => ['All Angels', 'admin_user'],
@ -111,7 +118,7 @@ function make_navigation()
$title = ((array) $options)[0]; $title = ((array) $options)[0];
$admin_menu[] = toolbar_dropdown_item( $admin_menu[] = toolbar_dropdown_item(
page_link_to($menu_page), page_link_to($menu_page),
__($title), htmlspecialchars(__($title)),
$menu_page == $page $menu_page == $page
); );
} }

View File

@ -2,9 +2,7 @@
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\Exceptions\HttpTemporaryRedirect; use Engelsystem\Http\Exceptions\HttpTemporaryRedirect;
use Engelsystem\Models\BaseModel;
use Engelsystem\ValidationResult; use Engelsystem\ValidationResult;
use Illuminate\Support\Collection;
/** /**
* Provide page/request helper functions * Provide page/request helper functions
@ -63,41 +61,6 @@ function throw_redirect($url)
throw new HttpTemporaryRedirect($url); throw new HttpTemporaryRedirect($url);
} }
/**
* 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 an int[] from given request param name. * Returns an int[] from given request param name.
* *
@ -185,23 +148,6 @@ function strip_request_item($name, $default_value = null)
return $default_value; return $default_value;
} }
/**
* 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;
}
/** /**
* Testet, ob der angegebene REQUEST Wert ein Integer ist, bzw. * Testet, ob der angegebene REQUEST Wert ein Integer ist, bzw.
* eine ID sein könnte. * eine ID sein könnte.

View File

@ -72,17 +72,6 @@ function tabs($tabs, $selected = 0)
]); ]);
} }
/**
* Display muted (grey) text.
*
* @param string $text
* @return string
*/
function mute($text)
{
return '<span class="text-muted">' . $text . '</span>';
}
/** /**
* Renders a bootstrap label with given content and class. * Renders a bootstrap label with given content and class.
* *
@ -188,7 +177,7 @@ function toolbar_item_link($href, $icon, $label, $active = false)
return '<li class="nav-item">' return '<li class="nav-item">'
. '<a class="nav-link ' . ($active ? 'active" aria-current="page"' : '"') . ' href="' . $href . '">' . '<a class="nav-link ' . ($active ? 'active" aria-current="page"' : '"') . ' href="' . $href . '">'
. ($icon != '' ? '<span class="bi bi-' . $icon . '"></span> ' : '') . ($icon != '' ? '<span class="bi bi-' . $icon . '"></span> ' : '')
. $label . htmlspecialchars($label)
. '</a>' . '</a>'
. '</li>'; . '</li>';
} }
@ -200,7 +189,7 @@ function toolbar_dropdown_item(string $href, string $label, bool $active, string
[ [
'{href}' => $href, '{href}' => $href,
'{icon}' => $icon === null ? '' : '<i class="bi bi-' . $icon . '"></i>', '{icon}' => $icon === null ? '' : '<i class="bi bi-' . $icon . '"></i>',
'{label}' => $label, '{label}' => htmlspecialchars($label),
'{active}' => $active ? ' active' : '', '{active}' => $active ? ' active' : '',
'{aria}' => $active ? ' aria-current="page"' : '', '{aria}' => $active ? ' aria-current="page"' : '',
] ]
@ -235,7 +224,7 @@ EOT;
$template, $template,
[ [
'{class}' => $active ? ' active' : '', '{class}' => $active ? ' active' : '',
'{label}' => $label, '{label}' => htmlspecialchars($label),
'{submenu}' => join("\n", $submenu), '{submenu}' => join("\n", $submenu),
] ]
); );

View File

@ -26,7 +26,7 @@ function AngelType_name_render(AngelType $angeltype, $plain = false)
} }
return '<a href="' . angeltype_link($angeltype->id) . '">' return '<a href="' . angeltype_link($angeltype->id) . '">'
. ($angeltype->restricted ? icon('mortarboard-fill') : '') . $angeltype->name . ($angeltype->restricted ? icon('mortarboard-fill') : '') . htmlspecialchars($angeltype->name)
. '</a>'; . '</a>';
} }
@ -60,7 +60,7 @@ function AngelType_render_membership(AngelType $user_angeltype)
*/ */
function AngelType_delete_view(AngelType $angeltype) function AngelType_delete_view(AngelType $angeltype)
{ {
return page_with_title(sprintf(__('Delete angeltype %s'), $angeltype->name), [ return page_with_title(sprintf(__('Delete angeltype %s'), htmlspecialchars($angeltype->name)), [
info(sprintf(__('Do you want to delete angeltype %s?'), $angeltype->name), true), info(sprintf(__('Do you want to delete angeltype %s?'), $angeltype->name), true),
form([ form([
buttons([ buttons([
@ -80,14 +80,14 @@ function AngelType_delete_view(AngelType $angeltype)
*/ */
function AngelType_edit_view(AngelType $angeltype, bool $supporter_mode) function AngelType_edit_view(AngelType $angeltype, bool $supporter_mode)
{ {
return page_with_title(sprintf(__('Edit %s'), $angeltype->name), [ return page_with_title(sprintf(__('Edit %s'), htmlspecialchars((string) $angeltype->name)), [
buttons([ buttons([
button(page_link_to('angeltypes'), icon('person-lines-fill') . __('Angeltypes'), 'back'), button(page_link_to('angeltypes'), icon('person-lines-fill') . __('Angeltypes'), 'back'),
]), ]),
msg(), msg(),
form([ form([
$supporter_mode $supporter_mode
? form_info(__('Name'), $angeltype->name) ? form_info(__('Name'), htmlspecialchars($angeltype->name))
: form_text('name', __('Name'), $angeltype->name), : form_text('name', __('Name'), $angeltype->name),
$supporter_mode $supporter_mode
? form_info(__('Requires introduction'), $angeltype->restricted ? __('Yes') : __('No')) ? form_info(__('Requires introduction'), $angeltype->restricted ? __('Yes') : __('No'))
@ -244,7 +244,7 @@ function AngelType_view_members(AngelType $angeltype, $members, $admin_user_ange
foreach ($members as $member) { foreach ($members as $member) {
$member->name = User_Nick_render($member) . User_Pronoun_render($member); $member->name = User_Nick_render($member) . User_Pronoun_render($member);
if (config('enable_dect')) { if (config('enable_dect')) {
$member['dect'] = $member->contact->dect; $member['dect'] = htmlspecialchars((string) $member->contact->dect);
} }
if ($angeltype->requires_driver_license) { if ($angeltype->requires_driver_license) {
$member['wants_to_drive'] = icon_bool($member->license->wantsToDrive()); $member['wants_to_drive'] = icon_bool($member->license->wantsToDrive());
@ -405,7 +405,7 @@ function AngelType_view(
ShiftCalendarRenderer $shiftCalendarRenderer, ShiftCalendarRenderer $shiftCalendarRenderer,
$tab $tab
) { ) {
return page_with_title(sprintf(__('Team %s'), $angeltype->name), [ return page_with_title(sprintf(__('Team %s'), htmlspecialchars($angeltype->name)), [
AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user), AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user),
msg(), msg(),
tabs([ tabs([
@ -465,7 +465,7 @@ function AngelType_view_info(
$info[] = '<h3>' . __('Description') . '</h3>'; $info[] = '<h3>' . __('Description') . '</h3>';
$parsedown = new Parsedown(); $parsedown = new Parsedown();
if ($angeltype->description != '') { if ($angeltype->description != '') {
$info[] = $parsedown->parse($angeltype->description); $info[] = $parsedown->parse(htmlspecialchars($angeltype->description));
} }
list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members( list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members(
@ -539,9 +539,20 @@ function AngelType_view_info(
function AngelTypes_render_contact_info(AngelType $angeltype) function AngelTypes_render_contact_info(AngelType $angeltype)
{ {
$info = [ $info = [
__('Name') => [$angeltype->contact_name, $angeltype->contact_name], __('Name') => [
__('DECT') => config('enable_dect') ? [sprintf('<a href="tel:%s">%1$s</a>', $angeltype->contact_dect), $angeltype->contact_dect] : null, htmlspecialchars($angeltype->contact_name),
__('E-Mail') => [sprintf('<a href="mailto:%s">%1$s</a>', $angeltype->contact_email), $angeltype->contact_email], 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),
],
]; ];
$contactInfo = []; $contactInfo = [];
foreach ($info as $name => $data) { foreach ($info as $name => $data) {

View File

@ -19,7 +19,9 @@ function public_dashboard_view($stats, $free_shifts, $important_news)
if ($important_news->isNotEmpty()) { if ($important_news->isNotEmpty()) {
$first_news = $important_news->first(); $first_news = $important_news->first();
$news = div('alert alert-warning text-center', [ $news = div('alert alert-warning text-center', [
'<a href="' . url('/news/' . $first_news->id) . '"><strong>' . $first_news->title . '</strong></a>', '<a href="' . url('/news/' . $first_news->id) . '">'
. '<strong>' . htmlspecialchars($first_news->title) . '</strong>'
. '</a>',
]); ]);
} }
@ -93,17 +95,17 @@ function public_dashboard_shift_render($shift)
$panel_body = icon('clock-history') . $shift['start'] . ' - ' . $shift['end']; $panel_body = icon('clock-history') . $shift['start'] . ' - ' . $shift['end'];
$panel_body .= ' (' . $shift['duration'] . '&nbsp;h)'; $panel_body .= ' (' . $shift['duration'] . '&nbsp;h)';
$panel_body .= '<br>' . icon('list-task') . $shift['shifttype_name']; $panel_body .= '<br>' . icon('list-task') . htmlspecialchars($shift['shifttype_name']);
if (!empty($shift['title'])) { if (!empty($shift['title'])) {
$panel_body .= ' (' . $shift['title'] . ')'; $panel_body .= ' (' . htmlspecialchars($shift['title']) . ')';
} }
$panel_body .= '<br>' . icon('pin-map-fill') . $shift['room_name']; $panel_body .= '<br>' . icon('pin-map-fill') . htmlspecialchars($shift['room_name']);
foreach ($shift['needed_angels'] as $needed_angels) { foreach ($shift['needed_angels'] as $needed_angels) {
$panel_body .= '<br>' . icon('person') $panel_body .= '<br>' . icon('person')
. '<span class="text-' . $shift['style'] . '">' . '<span class="text-' . $shift['style'] . '">'
. $needed_angels['need'] . ' &times; ' . $needed_angels['angeltype_name'] . $needed_angels['need'] . ' &times; ' . htmlspecialchars($needed_angels['angeltype_name'])
. '</span>'; . '</span>';
} }

View File

@ -24,13 +24,13 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
if ($room->description) { if ($room->description) {
$description = '<h3>' . __('Description') . '</h3>'; $description = '<h3>' . __('Description') . '</h3>';
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$description .= $parsedown->parse($room->description); $description .= $parsedown->parse(htmlspecialchars($room->description));
} }
$dect = ''; $dect = '';
if (config('enable_dect') && $room->dect) { if (config('enable_dect') && $room->dect) {
$dect = heading(__('Contact'), 3) $dect = heading(__('Contact'), 3)
. description([__('DECT') => sprintf('<a href="tel:%s">%1$s</a>', $room->dect)]); . description([__('DECT') => sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars($room->dect))]);
} }
$tabs = []; $tabs = [];
@ -39,7 +39,7 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
'<div class="map">' '<div class="map">'
. '<iframe style="width: 100%%; min-height: 400px; border: 0 none;" src="%s"></iframe>' . '<iframe style="width: 100%%; min-height: 400px; border: 0 none;" src="%s"></iframe>'
. '</div>', . '</div>',
$room->map_url htmlspecialchars($room->map_url)
); );
} }
@ -57,7 +57,7 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
$selected_tab = count($tabs) - 1; $selected_tab = count($tabs) - 1;
} }
return page_with_title(icon('pin-map-fill') . $room->name, [ return page_with_title(icon('pin-map-fill') . htmlspecialchars($room->name), [
$assignNotice, $assignNotice,
auth()->can('admin_rooms') ? buttons([ auth()->can('admin_rooms') ? buttons([
button( button(
@ -79,8 +79,8 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
function Room_name_render(Room $room) function Room_name_render(Room $room)
{ {
if (auth()->can('view_rooms')) { if (auth()->can('view_rooms')) {
return '<a href="' . room_link($room) . '">' . icon('pin-map-fill') . $room->name . '</a>'; return '<a href="' . room_link($room) . '">' . icon('pin-map-fill') . htmlspecialchars($room->name) . '</a>';
} }
return icon('pin-map-fill') . $room->name; return icon('pin-map-fill') . htmlspecialchars($room->name);
} }

View File

@ -29,7 +29,7 @@ class ShiftCalendarShiftRenderer
{ {
$info_text = ''; $info_text = '';
if ($shift->title != '') { if ($shift->title != '') {
$info_text = icon('info-circle') . $shift->title . '<br>'; $info_text = icon('info-circle') . htmlspecialchars($shift->title) . '<br>';
} }
list($shift_signup_state, $shifts_row) = $this->renderShiftNeededAngeltypes( list($shift_signup_state, $shifts_row) = $this->renderShiftNeededAngeltypes(
$shift, $shift,
@ -199,7 +199,7 @@ class ShiftCalendarShiftRenderer
: $inner_text . '<br />' : $inner_text . '<br />'
. button( . button(
page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype->id]), page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype->id]),
sprintf(__('Become %s'), $angeltype->name), sprintf(__('Become %s'), htmlspecialchars($angeltype->name)),
'btn-sm' 'btn-sm'
), ),
// Shift collides or user is already signed up: No signup allowed // Shift collides or user is already signed up: No signup allowed
@ -262,7 +262,7 @@ class ShiftCalendarShiftRenderer
} }
$shift_heading = $shift->start->format('H:i') . ' &dash; ' $shift_heading = $shift->start->format('H:i') . ' &dash; '
. $shift->end->format('H:i') . ' &mdash; ' . $shift->end->format('H:i') . ' &mdash; '
. $shift->shiftType->name; . htmlspecialchars($shift->shiftType->name);
if ($needed_angeltypes_count > 0) { if ($needed_angeltypes_count > 0) {
$shift_heading = '<span class="badge bg-light text-danger me-1">' . $needed_angeltypes_count . '</span> ' . $shift_heading; $shift_heading = '<span class="badge bg-light text-danger me-1">' . $needed_angeltypes_count . '</span> ' . $shift_heading;

View File

@ -19,7 +19,7 @@ function ShiftEntry_delete_view_admin(Shift $shift, AngelType $angeltype, User $
return page_with_title(ShiftEntry_delete_title(), [ return page_with_title(ShiftEntry_delete_title(), [
info(sprintf( info(sprintf(
__('Do you want to sign off %s from shift %s from %s to %s as %s?'), __('Do you want to sign off %s from shift %s from %s to %s as %s?'),
User_Nick_render($signoff_user), $signoff_user->displayName,
$shift->shiftType->name, $shift->shiftType->name,
$shift->start->format(__('Y-m-d H:i')), $shift->start->format(__('Y-m-d H:i')),
$shift->end->format(__('Y-m-d H:i')), $shift->end->format(__('Y-m-d H:i')),
@ -92,7 +92,7 @@ function ShiftEntry_create_view_admin(
) { ) {
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $room),
@ -120,7 +120,7 @@ function ShiftEntry_create_view_supporter(Shift $shift, Room $room, AngelType $a
{ {
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $room),
@ -149,7 +149,7 @@ function ShiftEntry_create_view_user(Shift $shift, Room $room, AngelType $angelt
{ {
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . htmlspecialchars($shift->shiftType->name)
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $room),
@ -218,9 +218,9 @@ function ShiftEntry_edit_view(
form([ form([
form_info(__('Angel:'), User_Nick_render($angel)), form_info(__('Angel:'), User_Nick_render($angel)),
form_info(__('Date, Duration:'), $date), form_info(__('Date, Duration:'), $date),
form_info(__('Location:'), $location), form_info(__('Location:'), htmlspecialchars($location)),
form_info(__('Title:'), $title), form_info(__('Title:'), htmlspecialchars($title)),
form_info(__('Type:'), $type), form_info(__('Type:'), htmlspecialchars($type)),
$comment, $comment,
join('', $freeload_form), join('', $freeload_form),
form_submit('submit', __('Save')), form_submit('submit', __('Save')),

View File

@ -10,7 +10,7 @@ use Illuminate\Support\Collection;
function ShiftType_name_render(ShiftType $shifttype) function ShiftType_name_render(ShiftType $shifttype)
{ {
if (auth()->can('shifttypes')) { if (auth()->can('shifttypes')) {
return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype->name . '</a>'; return '<a href="' . shifttype_link($shifttype) . '">' . htmlspecialchars($shifttype->name) . '</a>';
} }
return $shifttype->name; return $shifttype->name;
} }
@ -21,7 +21,7 @@ function ShiftType_name_render(ShiftType $shifttype)
*/ */
function ShiftType_delete_view(ShiftType $shifttype) function ShiftType_delete_view(ShiftType $shifttype)
{ {
return page_with_title(sprintf(__('Delete shifttype %s'), $shifttype->name), [ return page_with_title(sprintf(__('Delete shifttype %s'), htmlspecialchars($shifttype->name)), [
info(sprintf(__('Do you want to delete shifttype %s?'), $shifttype->name), true), info(sprintf(__('Do you want to delete shifttype %s?'), $shifttype->name), true),
form([ form([
buttons([ buttons([
@ -67,7 +67,7 @@ function ShiftType_view(ShiftType $shifttype)
{ {
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$title = $shifttype->name; $title = $shifttype->name;
return page_with_title($title, [ return page_with_title(htmlspecialchars($title), [
msg(), msg(),
buttons([ buttons([
button(page_link_to('shifttypes'), shifttypes_title(), 'back'), button(page_link_to('shifttypes'), shifttypes_title(), 'back'),
@ -81,7 +81,7 @@ function ShiftType_view(ShiftType $shifttype)
), ),
]), ]),
heading(__('Description'), 2), heading(__('Description'), 2),
$parsedown->parse($shifttype->description), $parsedown->parse(htmlspecialchars($shifttype->description)),
], true); ], true);
} }
@ -95,7 +95,7 @@ function ShiftTypes_list_view($shifttypes)
$shifttype->name = '<a href="' $shifttype->name = '<a href="'
. page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id]) . page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id])
. '">' . '">'
. $shifttype->name . htmlspecialchars($shifttype->name)
. '</a>'; . '</a>';
$shifttype->actions = table_buttons([ $shifttype->actions = table_buttons([
button( button(

View File

@ -24,8 +24,8 @@ function Shift_view_header(Shift $shift, Room $room)
'<h4>' . __('Title') . '</h4>', '<h4>' . __('Title') . '</h4>',
'<p class="lead">' '<p class="lead">'
. ($shift->url != '' . ($shift->url != ''
? '<a href="' . $shift->url . '">' . $shift->title . '</a>' ? '<a href="' . htmlspecialchars($shift->url) . '">' . htmlspecialchars($shift->title) . '</a>'
: $shift->title) : htmlspecialchars($shift->title))
. '</p>', . '</p>',
]), ]),
div('col-sm-3 col-xs-6', [ div('col-sm-3 col-xs-6', [
@ -98,7 +98,7 @@ function Shift_signup_button_render(Shift $shift, AngelType $angeltype)
page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]), page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]),
sprintf( sprintf(
__('Become %s'), __('Become %s'),
$angeltype->name htmlspecialchars($angeltype->name)
) )
); );
} }
@ -170,8 +170,15 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
$buttons = [ $buttons = [
$shift_admin ? button(shift_edit_link($shift), icon('pencil') . __('edit')) : '', $shift_admin ? button(shift_edit_link($shift), icon('pencil') . __('edit')) : '',
$shift_admin ? button(shift_delete_link($shift), icon('trash') . __('delete')) : '', $shift_admin ? button(shift_delete_link($shift), icon('trash') . __('delete')) : '',
$admin_shifttypes ? button(shifttype_link($shifttype), $shifttype->name) : '', $admin_shifttypes
$admin_rooms ? button(room_link($room), icon('pin-map-fill') . $room->name) : '', ? button(shifttype_link($shifttype), htmlspecialchars($shifttype->name))
: '',
$admin_rooms
? button(
room_link($room),
icon('pin-map-fill') . htmlspecialchars($room->name)
)
: '',
]; ];
} }
$buttons[] = button(user_link(auth()->user()->id), '<span class="icon-icon_angel"></span> ' . __('My shifts')); $buttons[] = button(user_link(auth()->user()->id), '<span class="icon-icon_angel"></span> ' . __('My shifts'));
@ -185,8 +192,8 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
]), ]),
div('col-sm-6', [ div('col-sm-6', [
'<h2>' . __('Description') . '</h2>', '<h2>' . __('Description') . '</h2>',
$parsedown->parse($shifttype->description), $parsedown->parse(htmlspecialchars($shifttype->description)),
$parsedown->parse($shift->description), $parsedown->parse(htmlspecialchars($shift->description)),
]), ]),
]); ]);
@ -197,7 +204,8 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
$shift->shiftType->name . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', htmlspecialchars($shift->shiftType->name)
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
$content $content
); );
} }

View File

@ -138,7 +138,7 @@ function UserAngelType_add_view(AngelType $angeltype, $users_source, $user_id)
{ {
$users = []; $users = [];
foreach ($users_source as $user_source) { foreach ($users_source as $user_source) {
$users[$user_source->id] = User_Nick_render($user_source); $users[$user_source->id] = $user_source->displayName;
} }
return page_with_title(__('Add user to angeltype'), [ return page_with_title(__('Add user to angeltype'), [
@ -151,7 +151,7 @@ function UserAngelType_add_view(AngelType $angeltype, $users_source, $user_id)
), ),
]), ]),
form([ form([
form_info(__('Angeltype'), $angeltype->name), form_info(__('Angeltype'), htmlspecialchars($angeltype->name)),
form_checkbox('auto_confirm_user', __('Confirm user'), true), form_checkbox('auto_confirm_user', __('Confirm user'), true),
form_select('user_id', __('User'), $users, $user_id), form_select('user_id', __('User'), $users, $user_id),
form_submit('submit', __('Add')), form_submit('submit', __('Add')),
@ -166,7 +166,7 @@ function UserAngelType_add_view(AngelType $angeltype, $users_source, $user_id)
*/ */
function UserAngelType_join_view($user, AngelType $angeltype) function UserAngelType_join_view($user, AngelType $angeltype)
{ {
return page_with_title(sprintf(__('Become a %s'), $angeltype->name), [ return page_with_title(sprintf(__('Become a %s'), htmlspecialchars($angeltype->name)), [
msg(), msg(),
info(sprintf( info(sprintf(
__('Do you really want to add %s to %s?'), __('Do you really want to add %s to %s?'),

View File

@ -20,9 +20,9 @@ class UserHintsRenderer
if (!empty($hint)) { if (!empty($hint)) {
if ($important) { if ($important) {
$this->important = true; $this->important = true;
$this->hints[] = error($hint, true); $this->hints[] = error($hint, true, true);
} else { } else {
$this->hints[] = info($hint, true); $this->hints[] = info($hint, true, true);
} }
} }
} }

View File

@ -92,9 +92,9 @@ function Users_view(
foreach ($users as $user) { foreach ($users as $user) {
$u = []; $u = [];
$u['name'] = User_Nick_render($user) . User_Pronoun_render($user); $u['name'] = User_Nick_render($user) . User_Pronoun_render($user);
$u['first_name'] = $user->personalData->first_name; $u['first_name'] = htmlspecialchars((string) $user->personalData->first_name);
$u['last_name'] = $user->personalData->last_name; $u['last_name'] = htmlspecialchars((string) $user->personalData->last_name);
$u['dect'] = sprintf('<a href="tel:%s">%1$s</a>', $user->contact->dect); $u['dect'] = sprintf('<a href="tel:%s">%1$s</a>', htmlspecialchars((string) $user->contact->dect));
$u['arrived'] = icon_bool($user->state->arrived); $u['arrived'] = icon_bool($user->state->arrived);
if (config('enable_voucher')) { if (config('enable_voucher')) {
$u['got_voucher'] = $user->state->got_voucher; $u['got_voucher'] = $user->state->got_voucher;
@ -273,7 +273,7 @@ function User_view_shiftentries($needed_angel_type)
{ {
$shift_info = '<br><b><a href="' $shift_info = '<br><b><a href="'
. page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $needed_angel_type['id']]) . page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $needed_angel_type['id']])
. '">' . $needed_angel_type['name'] . '</a>:</b> '; . '">' . htmlspecialchars($needed_angel_type['name']) . '</a>:</b> ';
$shift_entries = []; $shift_entries = [];
foreach ($needed_angel_type['users'] as $user_shift) { foreach ($needed_angel_type['users'] as $user_shift) {
@ -299,9 +299,9 @@ function User_view_shiftentries($needed_angel_type)
*/ */
function User_view_myshift(Shift $shift, $user_source, $its_me) function User_view_myshift(Shift $shift, $user_source, $its_me)
{ {
$shift_info = '<a href="' . shift_link($shift) . '">' . $shift->shiftType->name . '</a>'; $shift_info = '<a href="' . shift_link($shift) . '">' . htmlspecialchars($shift->shiftType->name) . '</a>';
if ($shift->title) { if ($shift->title) {
$shift_info .= '<br /><a href="' . shift_link($shift) . '">' . $shift->title . '</a>'; $shift_info .= '<br /><a href="' . shift_link($shift) . '">' . htmlspecialchars($shift->title) . '</a>';
} }
foreach ($shift->needed_angeltypes as $needed_angel_type) { foreach ($shift->needed_angeltypes as $needed_angel_type) {
$shift_info .= User_view_shiftentries($needed_angel_type); $shift_info .= User_view_shiftentries($needed_angel_type);
@ -320,7 +320,7 @@ function User_view_myshift(Shift $shift, $user_source, $its_me)
]; ];
if ($its_me) { if ($its_me) {
$myshift['comment'] = $shift->user_comment; $myshift['comment'] = htmlspecialchars($shift->user_comment);
} }
if ($shift->freeloaded) { if ($shift->freeloaded) {
@ -329,7 +329,9 @@ function User_view_myshift(Shift $shift, $user_source, $its_me)
. '</p>'; . '</p>';
if (auth()->can('user_shifts_admin')) { if (auth()->can('user_shifts_admin')) {
$myshift['comment'] .= '<br />' $myshift['comment'] .= '<br />'
. '<p class="text-danger">' . __('Freeloaded') . ': ' . $shift->freeloaded_comment . '</p>'; . '<p class="text-danger">'
. __('Freeloaded') . ': ' . htmlspecialchars($shift->freeloaded_comment)
. '</p>';
} else { } else {
$myshift['comment'] .= '<br /><p class="text-danger">' . __('Freeloaded') . '</p>'; $myshift['comment'] .= '<br /><p class="text-danger">' . __('Freeloaded') . '</p>';
} }
@ -454,7 +456,7 @@ function User_view_worklog(Worklog $worklog, $admin_user_worklog_privilege)
'duration' => sprintf('%.2f', $worklog->hours) . ' h', 'duration' => sprintf('%.2f', $worklog->hours) . ' h',
'room' => '', 'room' => '',
'shift_info' => __('Work log entry'), 'shift_info' => __('Work log entry'),
'comment' => $worklog->comment . '<br>' 'comment' => htmlspecialchars($worklog->comment) . '<br>'
. sprintf( . sprintf(
__('Added by %s at %s'), __('Added by %s at %s'),
User_Nick_render($worklog->creator), User_Nick_render($worklog->creator),
@ -616,8 +618,8 @@ function User_view(
config('enable_dect') && $user_source->contact->dect ? config('enable_dect') && $user_source->contact->dect ?
heading( heading(
icon('phone') icon('phone')
. ' <a href="tel:' . $user_source->contact->dect . '">' . ' <a href="tel:' . htmlspecialchars($user_source->contact->dect) . '">'
. $user_source->contact->dect . htmlspecialchars($user_source->contact->dect)
. '</a>' . '</a>'
) )
: '', : '',
@ -625,8 +627,8 @@ function User_view(
$user_source->settings->mobile_show ? $user_source->settings->mobile_show ?
heading( heading(
icon('phone') icon('phone')
. ' <a href="tel:' . $user_source->contact->mobile . '">' . ' <a href="tel:' . htmlspecialchars($user_source->contact->mobile) . '">'
. $user_source->contact->mobile . htmlspecialchars($user_source->contact->mobile)
. '</a>' . '</a>'
) )
: '' : ''
@ -647,18 +649,19 @@ function User_view(
($its_me || $admin_user_privilege) ? '<h2>' . __('Shifts') . '</h2>' : '', ($its_me || $admin_user_privilege) ? '<h2>' . __('Shifts') . '</h2>' : '',
$myshifts_table, $myshifts_table,
($its_me && $nightShiftsConfig['enabled'] && $goodie_enabled) ? info( ($its_me && $nightShiftsConfig['enabled'] && $goodie_enabled) ? info(
icon('info-circle') . sprintf( sprintf(
__('Your night shifts between %d and %d am count twice.'), icon('info-circle') . __('Your night shifts between %d and %d am count twice.'),
$nightShiftsConfig['start'], $nightShiftsConfig['start'],
$nightShiftsConfig['end'] $nightShiftsConfig['end']
), ),
true,
true true
) : '', ) : '',
$its_me && count($shifts) == 0 $its_me && count($shifts) == 0
? error(sprintf( ? error(sprintf(
__('Go to the <a href="%s">shifts table</a> to sign yourself up for some shifts.'), __('Go to the <a href="%s">shifts table</a> to sign yourself up for some shifts.'),
page_link_to('user_shifts') page_link_to('user_shifts')
), true) ), true, true)
: '', : '',
$its_me ? ical_hint() : '', $its_me ? ical_hint() : '',
] ]
@ -788,7 +791,7 @@ function User_angeltypes_render($user_angeltypes)
$class = 'text-warning'; $class = 'text-warning';
} }
$output[] = '<a href="' . angeltype_link($angeltype->id) . '" class="' . $class . '">' $output[] = '<a href="' . angeltype_link($angeltype->id) . '" class="' . $class . '">'
. ($angeltype->pivot->supporter ? icon('patch-check') : '') . $angeltype->name . ($angeltype->pivot->supporter ? icon('patch-check') : '') . htmlspecialchars($angeltype->name)
. '</a>'; . '</a>';
} }
return div('col-md-2', [ return div('col-md-2', [
@ -805,7 +808,7 @@ function User_groups_render($user_groups)
{ {
$output = []; $output = [];
foreach ($user_groups as $group) { foreach ($user_groups as $group) {
$output[] = __($group->name); $output[] = __(htmlspecialchars($group->name));
} }
return div('col-md-2', [ return div('col-md-2', [
@ -825,9 +828,11 @@ function User_oauth_render(User $user)
$output = []; $output = [];
foreach ($user->oauth as $oauth) { foreach ($user->oauth as $oauth) {
$output[] = __( $output[] = __(
htmlspecialchars(
isset($config[$oauth->provider]['name']) isset($config[$oauth->provider]['name'])
? $config[$oauth->provider]['name'] ? $config[$oauth->provider]['name']
: Str::ucfirst($oauth->provider) : Str::ucfirst($oauth->provider)
)
); );
} }
@ -968,7 +973,10 @@ function render_user_tshirt_hint()
function render_user_dect_hint() function render_user_dect_hint()
{ {
$user = auth()->user(); $user = auth()->user();
if ($user->state->arrived && config('enable_dect') && !$user->contact->dect) { if (
$user->state->arrived
&& config('enable_dect') && !$user->contact->dect
) {
$text = __('You need to specify a DECT phone number in your settings! If you don\'t have a DECT phone, just enter \'-\'.'); $text = __('You need to specify a DECT phone number in your settings! If you don\'t have a DECT phone, just enter \'-\'.');
return render_profile_link($text); return render_profile_link($text);
} }

View File

@ -3,9 +3,9 @@
{% set url=url('/angeltypes', {'action': 'view', 'angeltype_id': angeltype.id}) %} {% set url=url('/angeltypes', {'action': 'view', 'angeltype_id': angeltype.id}) %}
{% block introduction %} {% block introduction %}
{{ __('notification.angeltype.added.introduction', [angeltype.name, url])|raw }} {{ __('notification.angeltype.added.introduction', [angeltype.name|e, url])|raw }}
{% endblock %} {% endblock %}
{% block message %} {% block message %}
{{ __('notification.angeltype.added.text', [angeltype.name, url])|raw }} {{ __('notification.angeltype.added.text', [angeltype.name|e, url])|raw }}
{% endblock %} {% endblock %}

View File

@ -3,9 +3,9 @@
{% set url=url('/angeltypes', {'action': 'view', 'angeltype_id': angeltype.id}) %} {% set url=url('/angeltypes', {'action': 'view', 'angeltype_id': angeltype.id}) %}
{% block introduction %} {% block introduction %}
{{ __('notification.angeltype.confirmed.introduction', [angeltype.name, url])|raw }} {{ __('notification.angeltype.confirmed.introduction', [angeltype.name|e, url])|raw }}
{% endblock %} {% endblock %}
{% block message %} {% block message %}
{{ __('notification.angeltype.confirmed.text', [angeltype.name, url])|raw }} {{ __('notification.angeltype.confirmed.text', [angeltype.name|e, url])|raw }}
{% endblock %} {% endblock %}

View File

@ -7,7 +7,7 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="row mb-3 mt-5"> <div class="row mb-3 mt-5">
<div class="col-sm-12 text-center" id="welcome-title"> <div class="col-sm-12 text-center" id="welcome-title">
<h2>{{ __('Welcome to the %s!', [config('name') ~ m.angel() ~ (config('app_name')|upper) ])|raw }}</h2> <h2>{{ __('Welcome to the %s!', [config('name')|e ~ m.angel() ~ (config('app_name')|upper|e) ])|raw }}</h2>
</div> </div>
</div> </div>