Skip to content

Commit

Permalink
Feature/add security header (#319)
Browse files Browse the repository at this point in the history
  • Loading branch information
mckenziearts authored Jan 11, 2025
1 parent 1f209f7 commit b7b50b3
Show file tree
Hide file tree
Showing 37 changed files with 333 additions and 178 deletions.
33 changes: 0 additions & 33 deletions app/Http/Controllers/User/DashboardController.php

This file was deleted.

48 changes: 48 additions & 0 deletions app/Http/Middleware/CacheHeaders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

final class CacheHeaders
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var \Illuminate\Http\Response $response
*/
$response = $next($request);

if (Auth::check()) {
$response->setCache(
options: [
'private' => true,
'max_age' => 0,
's_maxage' => 0,
'no_store' => true,
],
);
} else {
$response->setCache(
options: [
'public' => true,
'max_age' => 60,
's_maxage' => 60,
],
);

foreach ($response->headers->getCookies() as $cookie) {
$response->headers->removeCookie(
name: $cookie->getName(),
);
}
}

return $response;
}
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/Security/ContentSecurityPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware\Security;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

final class ContentSecurityPolicy
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);

$response->headers->add([
'Content-Security-Policy' => "default-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src *;",
]);

return $response;
}
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/Security/PermissionsPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware\Security;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

final class PermissionsPolicy
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);

$response->headers->add([
'Permissions-Policy' => 'geolocation=(self), microphone=()',
]);

return $response;
}
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/Security/ReferrerPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware\Security;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

final class ReferrerPolicy
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);

$response->headers->add([
'Referrer-Policy' => 'no-referrer',
]);

return $response;
}
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/Security/StrictTransportSecurity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware\Security;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

final class StrictTransportSecurity
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);

$response->headers->add([
'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains; preload',
]);

return $response;
}
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/Security/XFrameOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware\Security;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

final class XFrameOption
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);

$response->headers->add([
'X-Frame-Options' => 'deny',
]);

return $response;
}
}
28 changes: 0 additions & 28 deletions app/Http/Middleware/TrackLastActivity.php

This file was deleted.

2 changes: 1 addition & 1 deletion app/Livewire/Components/Discussion/Comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function comments(): Collection
$replies = collect();

// @phpstan-ignore-next-line
foreach ($this->discussion->replies->load(['allChildReplies', 'user']) as $reply) {
foreach ($this->discussion->replies->load(['allChildReplies', 'user', 'user.media']) as $reply) {
/** @var Reply $reply */
if ($reply->allChildReplies->isNotEmpty()) {
foreach ($reply->allChildReplies as $childReply) {
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Components/User/Articles.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final class Articles extends Component implements HasActions, HasForms
#[Computed]
public function articles(): LengthAwarePaginator
{
return Article::with(['user', 'tags', 'reactions'])
return Article::with('tags', 'reactions')
->where('user_id', Auth::id())
->latest()
->paginate(10);
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Components/User/Discussions.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class Discussions extends Component implements HasActions, HasForms
#[Computed]
public function discussions(): LengthAwarePaginator
{
return Discussion::with('user')
return Discussion::with('tags', 'replies')
->where('user_id', Auth::id())
->latest()
->paginate(10);
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Components/User/Threads.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class Threads extends Component implements HasActions, HasForms
#[Computed]
public function threads(): LengthAwarePaginator
{
return Thread::with('user')
return Thread::with('channels', 'solutionReply', 'replies')
->scopes('withViewsCount')
->where('user_id', Auth::id())
->latest()
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Pages/Account/Dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class Dashboard extends Component
#[Computed]
public function user(): User
{
return User::query()
return User::with('providers')
->scopes('withCounts')
->find(Auth::id());
}
Expand Down
13 changes: 9 additions & 4 deletions app/Livewire/Pages/Articles/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Models\Tag;
use App\Traits\WithLocale;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Cache;
use Livewire\Component;
use Livewire\WithoutUrlPagination;
use Livewire\WithPagination;
Expand All @@ -26,7 +27,7 @@ public function mount(): void
public function render(): View
{
return view('livewire.pages.articles.index', [
'articles' => Article::with(['tags', 'user', 'user.transactions']) // @phpstan-ignore-line
'articles' => Article::with(['tags', 'user', 'user.transactions', 'user.media', 'media']) // @phpstan-ignore-line
->withCount(['views', 'reactions'])
->orderByDesc('sponsored_at')
->orderByDesc('published_at')
Expand All @@ -35,9 +36,13 @@ public function render(): View
->forLocale($this->locale)
->simplePaginate(21),

'tags' => Tag::query()->whereHas('articles', function ($query): void {
$query->published();
})->orderBy('name')->get(),
'tags' => Cache::remember(
key: 'articles.tags',
ttl: now()->addWeek(),
callback: fn () => Tag::query()->whereHas('articles', function ($query): void {
$query->published();
})->orderBy('name')->get()
),
])
->title(__('pages/article.title'));
}
Expand Down
15 changes: 10 additions & 5 deletions app/Livewire/Pages/Discussions/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Models\Tag;
use App\Traits\WithLocale;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Cache;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithoutUrlPagination;
Expand Down Expand Up @@ -57,15 +58,19 @@ public function tagExists(string $tag): bool
public function render(): View
{
/** @var DiscussionQueryBuilder $query */
$query = Discussion::with(['tags', 'replies', 'user']) // @phpstan-ignore-line
$query = Discussion::with(['tags', 'replies', 'user', 'user.media', 'reactions']) // @phpstan-ignore-line
->withCount('replies')
->forLocale($this->locale)
->notPinned();

$tags = Tag::query()
->whereJsonContains('concerns', ['discussion'])
->orderBy('name')
->get();
$tags = Cache::remember(
key: 'discussions.tags',
ttl: now()->addWeek(),
callback: fn () => Tag::query()
->whereJsonContains('concerns', ['discussion'])
->orderBy('name')
->get()
);

if ($this->currentTag) {
$query->forTag($this->currentTag); // @phpstan-ignore-line
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Pages/Discussions/SingleDiscussion.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function mount(): void
->twitterDescription($this->discussion->excerpt(100))
->withUrl();

$this->discussion->load('tags', 'replies', 'reactions', 'replies.user', 'user');
$this->discussion->load('tags', 'replies', 'reactions', 'user', 'user.media');
}

public function editAction(): Action
Expand Down
7 changes: 4 additions & 3 deletions app/Livewire/Pages/Forum/DetailThread.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ final class DetailThread extends Component implements HasActions, HasForms

public Thread $thread;

public function mount(Thread $thread): void
public function mount(): void
{
views($thread)->cooldown(now()->addHour())->record();
views($this->thread)->cooldown(now()->addHour())->record();

$this->thread = $thread->loadCount('views');
$this->thread->load('channels', 'channels.parent', 'user', 'user.media', 'replies', 'solutionReply')
->loadCount('views');
}

public function editAction(): Action
Expand Down
3 changes: 2 additions & 1 deletion app/Livewire/Pages/Forum/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ protected function applySorting(Builder $query): Builder

public function render(): View
{
$query = Thread::with(['channels', 'user']);
$query = Thread::with(['channels', 'user', 'user.media'])
->withCount('replies');

$query = $this->applyChannel($query);
$query = $this->applySearch($query);
Expand Down
Loading

0 comments on commit b7b50b3

Please sign in to comment.