Compare commits

...

2 Commits

3 changed files with 36 additions and 4 deletions

View File

@@ -7,6 +7,10 @@
@extends('layouts.nova')
@section('content')
@php
$sanitizeHtml = fn (?string $value) => \App\Services\ContentSanitizer::sanitizeRenderedHtml($value ?? '');
@endphp
<div class="effect2">
<div class="page-heading">
<h1 class="page-header">Browse Categories</h1>
@@ -24,7 +28,7 @@
<h2 class="panel-title">{{ $ct->name }}</h2>
</div>
<div class="panel-body">
<p>{!! $ct->description ?? '' !!}</p>
<p>{!! $sanitizeHtml($ct->description) !!}</p>
@php
$roots = $categoriesByType[$ct->slug] ?? $ct->rootCategories ?? collect();
@@ -37,7 +41,7 @@
@foreach ($roots as $category)
<li style="display:block;margin-bottom:8px;">
<h4>{{ $category->name }}</h4>
<p>{!! $category->description !!}</p>
<p>{!! $sanitizeHtml($category->description) !!}</p>
<ul style="list-style:none;padding:0;margin:0;">
@foreach ($category->subcategories as $subcategory)
@php
@@ -47,7 +51,7 @@
@endphp
<li style="width:19%;display:inline-block;vertical-align:top;">
<img src="/gfx/icons/{{ $picture }}" width="15" height="15" alt="{{ $subcategoryName }}" />
<a href="{{ $subcategoryUrl }}" title="{{ $subcategoryName }}">{!! $subcategoryName !!}</a>
<a href="{{ $subcategoryUrl }}" title="{{ $subcategoryName }}">{{ $subcategoryName }}</a>
</li>
@endforeach
</ul>

View File

@@ -82,7 +82,7 @@
<i class="fa-solid fa-calendar-day w-4 text-center text-sb-muted"></i>On This Day
</a>
<a class="flex items-center gap-3 px-4 py-2.5 text-sm hover:bg-white/5" href="{{ route('worlds.index') }}">
<i class="fa-solid fa-stars w-4 text-center text-sb-muted"></i>Worlds
<i class="fa-solid fa-globe w-4 text-center text-sb-muted"></i>Worlds
</a>
@auth
<a class="flex items-center gap-3 px-4 py-2.5 text-sm hover:bg-white/5" href="{{ route('discover.for-you') }}">

View File

@@ -77,6 +77,34 @@ test('render adds rel=noopener to external links', function () {
expect($html)->toContain('rel="noopener noreferrer nofollow"');
});
test('sanitizeRenderedHtml keeps allowed formatting tags', function () {
$html = ContentSanitizer::sanitizeRenderedHtml('<p><strong>Bold</strong> and <em>italic</em> with <a href="/categories">link</a></p>');
expect($html)
->toContain('<p>')
->toContain('<strong>Bold</strong>')
->toContain('<em>italic</em>')
->toContain('<a href="/categories"')
->toContain('rel="noopener noreferrer nofollow"');
});
test('sanitizeRenderedHtml strips script tags and event handlers', function () {
$html = ContentSanitizer::sanitizeRenderedHtml('<p onclick="evil()">Hello<script>alert(1)</script></p>');
expect($html)
->not()->toContain('<script')
->not()->toContain('onclick')
->toContain('Hello');
});
test('sanitizeRenderedHtml strips javascript links', function () {
$html = ContentSanitizer::sanitizeRenderedHtml('<a href="javascript:alert(1)">click</a>');
expect($html)
->not()->toContain('javascript:')
->toContain('click');
});
// ── Legacy HTML conversion ────────────────────────────────────────────────────
test('render converts legacy bold HTML to markdown output', function () {