username = 'attacker';
$verify->email = 'attacker@example.com';
$verify->reason_to_join = "\nsecond line";
$verify->save();
$applicationHtml = (new CuratedRegisterNotifyAdmin($verify))->render();
expect($applicationHtml)->not->toContain('');
expect($applicationHtml)->toContain('<script>');
// Line breaks preserved via nl2br.
expect($applicationHtml)->toContain('
register_id = $verify->id;
$activity->message = '';
$activity->save();
$responseHtml = (new CuratedRegisterNotifyAdminUserResponse($activity))->render();
expect($responseHtml)->not->toContain('');
expect($responseHtml)->toContain('<script>');
});
/*
| request-details-from-user is rendered as an HTTP response by the admin
| previewDetailsMessageShow endpoint, which reflects a GET `message` param into
| $activity->message. It must escape the message to prevent reflected XSS, the
| same way its sibling admin templates do.
*/
it('escapes the message in the request-details-from-user mailable', function () {
$verify = new CuratedRegister;
$verify->username = 'attacker';
$verify->email = 'attacker@example.com';
$verify->save();
$activity = new CuratedRegisterActivity;
$activity->register_id = $verify->id;
$activity->message = '
';
$activity->save();
$detailsHtml = (new CuratedRegisterRequestDetailsFromUser($verify, $activity))->render();
// The raw
tag and its onerror handler must not survive as live HTML.
expect($detailsHtml)->not->toContain('