Merge pull request #4540 from pixelfed/staging

Staging
This commit is contained in:
daniel 2023-07-14 04:30:00 -06:00 committed by GitHub
commit ef58c3b304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 172 additions and 52 deletions

View file

@ -33,6 +33,8 @@
- Update SearchApiV2Service, improve resolve query logic to better handle remote posts/profiles and local posts/profiles ([c61d0b91](https://github.com/pixelfed/pixelfed/commit/c61d0b91)) - Update SearchApiV2Service, improve resolve query logic to better handle remote posts/profiles and local posts/profiles ([c61d0b91](https://github.com/pixelfed/pixelfed/commit/c61d0b91))
- Update FollowPipeline, improve follower/following count calculation ([0b515767](https://github.com/pixelfed/pixelfed/commit/0b515767)) - Update FollowPipeline, improve follower/following count calculation ([0b515767](https://github.com/pixelfed/pixelfed/commit/0b515767))
- Update TransformImports command, increment status_count on profile model ([ba7551d8](https://github.com/pixelfed/pixelfed/commit/ba7551d8)) - Update TransformImports command, increment status_count on profile model ([ba7551d8](https://github.com/pixelfed/pixelfed/commit/ba7551d8))
- Update AP Helpers, improve url validation and add optional dns verification, disabled by default ([2bef3e41](https://github.com/pixelfed/pixelfed/commit/2bef3e41))
- Update admin users blade view, show last_active_at and other info ([e0b48b29](https://github.com/pixelfed/pixelfed/commit/e0b48b29))
- ([](https://github.com/pixelfed/pixelfed/commit/)) - ([](https://github.com/pixelfed/pixelfed/commit/))
## [v0.11.8 (2023-05-29)](https://github.com/pixelfed/pixelfed/compare/v0.11.7...v0.11.8) ## [v0.11.8 (2023-05-29)](https://github.com/pixelfed/pixelfed/compare/v0.11.7...v0.11.8)

View file

@ -0,0 +1,28 @@
<?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class DomainService
{
const CACHE_KEY = 'pf:services:domains:';
public static function hasValidDns($domain)
{
if(!$domain || !strlen($domain) || strpos($domain, '.') == -1) {
return false;
}
if(config('security.url.trusted_domains')) {
if(in_array($domain, explode(',', config('security.url.trusted_domains')))) {
return true;
}
}
return Cache::remember(self::CACHE_KEY . 'valid-dns:' . $domain, 14400, function() use($domain) {
return count(dns_get_record($domain, DNS_A | DNS_AAAA)) > 0;
});
}
}

View file

@ -40,6 +40,7 @@ use App\Models\Poll;
use Illuminate\Contracts\Cache\LockTimeoutException; use Illuminate\Contracts\Cache\LockTimeoutException;
use App\Jobs\ProfilePipeline\IncrementPostCount; use App\Jobs\ProfilePipeline\IncrementPostCount;
use App\Jobs\ProfilePipeline\DecrementPostCount; use App\Jobs\ProfilePipeline\DecrementPostCount;
use App\Services\DomainService;
use App\Services\UserFilterService; use App\Services\UserFilterService;
class Helpers { class Helpers {
@ -168,17 +169,24 @@ class Helpers {
$hash = hash('sha256', $url); $hash = hash('sha256', $url);
$key = "helpers:url:valid:sha256-{$hash}"; $key = "helpers:url:valid:sha256-{$hash}";
$ttl = now()->addMinutes(5);
$valid = Cache::remember($key, $ttl, function() use($url) { $valid = Cache::remember($key, 900, function() use($url) {
$localhosts = [ $localhosts = [
'127.0.0.1', 'localhost', '::1' '127.0.0.1', 'localhost', '::1'
]; ];
if(mb_substr($url, 0, 8) !== 'https://') { if(strtolower(mb_substr($url, 0, 8)) !== 'https://') {
return false; return false;
} }
if(substr_count($url, '://') !== 1) {
return false;
}
if(mb_substr($url, 0, 8) !== 'https://') {
$url = 'https://' . substr($url, 8);
}
$valid = filter_var($url, FILTER_VALIDATE_URL); $valid = filter_var($url, FILTER_VALIDATE_URL);
if(!$valid) { if(!$valid) {
@ -187,15 +195,12 @@ class Helpers {
$host = parse_url($valid, PHP_URL_HOST); $host = parse_url($valid, PHP_URL_HOST);
// if(count(dns_get_record($host, DNS_A | DNS_AAAA)) == 0) { if(in_array($host, $localhosts)) {
// return false; return false;
// } }
if(config('costar.enabled') == true) { if(config('security.url.verify_dns')) {
if( if(DomainService::hasValidDns($host) === false) {
(config('costar.domain.block') != null && Str::contains($host, config('costar.domain.block')) == true) ||
(config('costar.actor.block') != null && in_array($url, config('costar.actor.block')) == true)
) {
return false; return false;
} }
} }
@ -207,11 +212,6 @@ class Helpers {
} }
} }
if(in_array($host, $localhosts)) {
return false;
}
return $url; return $url;
}); });
@ -224,7 +224,7 @@ class Helpers {
if($url == true) { if($url == true) {
$domain = config('pixelfed.domain.app'); $domain = config('pixelfed.domain.app');
$host = parse_url($url, PHP_URL_HOST); $host = parse_url($url, PHP_URL_HOST);
$url = $domain === $host ? $url : false; $url = strtolower($domain) === strtolower($host) ? $url : false;
return $url; return $url;
} }
return false; return false;

9
config/security.php Normal file
View file

@ -0,0 +1,9 @@
<?php
return [
'url' => [
'verify_dns' => env('PF_SECURITY_URL_VERIFY_DNS', false),
'trusted_domains' => env('PF_SECURITY_URL_TRUSTED_DOMAINS', 'pixelfed.social,pixelfed.art,mastodon.social'),
]
];

View file

@ -58,42 +58,82 @@
<span class="badge badge-danger badge-sm">ADMIN</span> <span class="badge badge-danger badge-sm">ADMIN</span>
</p> </p>
@endif @endif
<div class="d-flex justify-content-around mt-3">
<div class="mb-0">
<p class="mb-n2 text-center text-dark font-weight-bold">
{{$profile->created_at->diffForHumans()}}
</p>
<p class="mb-0 text-center text-muted"> <p class="mb-0 text-center text-muted">
Joined {{$profile->created_at->diffForHumans()}} <span class="small">Joined</span>
</p> </p>
</div> </div>
<table class="table mb-0"> @if($user->last_active_at)
<tbody> <div class="mb-0">
<tr> <p class="mb-n2 text-center text-dark font-weight-bold">
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">bookmarks</th> {{$user->last_active_at->diffForHumans()}}
<td class="text-right font-weight-bold">{{$profile->bookmarks()->count()}}</td> </p>
</tr> <p class="mb-0 text-center text-muted">
<tr> <span class="small">Last Active</span>
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">collections</th> </p>
<td class="text-right font-weight-bold">{{$profile->collections()->count()}}</td> </div>
</tr> @endif
<tr> </div>
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">likes</th> </div>
<td class="text-right font-weight-bold">{{$profile->likes()->count()}}</td>
</tr> <div class="list-group list-group-flush details-list">
<tr> <div class="list-group-item details-list-item">
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">reports</th> <p class="details-list-item-title">email</p>
<td class="text-right font-weight-bold">{{$profile->reports()->count()}}</td> <p class="details-list-item-value text-truncate" title="{{$user->email}}">{{$user->email}}</p>
</tr> </div>
<tr>
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">reported</th> @if($profile->website)
<td class="text-right font-weight-bold">{{$profile->reported()->count()}}</td> <div class="list-group-item details-list-item">
</tr> <p class="details-list-item-title">website</p>
<tr> <p class="details-list-item-value text-truncate" title="{{$profile->website}}">{{$profile->website}}</p>
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">Active stories</th> </div>
<td class="text-right font-weight-bold">{{$profile->stories()->count()}}</td> @endif
</tr>
<tr> <div class="list-group-item details-list-item">
<th scope="row" class="font-weight-bold text-muted text-uppercase pl-3 small" style="line-height: 2;">storage used</th> <p class="details-list-item-title">bookmarks</p>
<td class="text-right font-weight-bold">{{PrettyNumber::size($profile->media()->sum('size'))}}<span class="text-muted"> / {{PrettyNumber::size(config_cache('pixelfed.max_account_size') * 1000)}}</span></td> <p class="details-list-item-value text-truncate">{{$profile->bookmarks()->count()}}</p>
</tr> </div>
</tbody>
</table> <div class="list-group-item details-list-item">
<p class="details-list-item-title">collections</p>
<p class="details-list-item-value text-truncate">{{$profile->collections()->count()}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">likes</p>
<p class="details-list-item-value text-truncate">{{$profile->likes()->count()}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">reports</p>
<p class="details-list-item-value text-truncate">{{$profile->reports()->count()}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">reported</p>
<p class="details-list-item-value text-truncate">{{$profile->reported()->count()}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">active stories</p>
<p class="details-list-item-value text-truncate">{{$profile->stories()->count()}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">storage used</p>
<p class="details-list-item-value text-truncate">{{PrettyNumber::size($profile->media()->sum('size'))}}<span class="text-muted"> / {{PrettyNumber::size(config_cache('pixelfed.max_account_size') * 1000)}}</p>
</div>
<div class="list-group-item details-list-item">
<p class="details-list-item-title">bio</p>
<p class="details-list-item-value text-wrap text-xs">{{ $profile->bio }}</p>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-12 col-md-8"> <div class="col-12 col-md-8">
@ -119,3 +159,44 @@
</div> </div>
</div> </div>
@endsection @endsection
@push('styles')
<style type="text/css">
.gap-1 {
gap: 5rem;
}
.details-list {
}
.details-list-item {
display: flex;
justify-content: space-between;
align-items: center;
gap: 5rem;
border-left: 0;
border-right: 0;
}
.details-list-item-title {
margin-bottom: 0;
color: #9ca3af !important;
text-transform: uppercase !important;
font-weight: bold;
font-size: 13px;
opacity: 0.69;
}
.details-list-item-value {
font-size: 15px;
font-weight: 600;
margin-bottom: 0;
}
.text-xs {
font-size: 11px !important;
font-weight: normal;
}
</style>
@endpush