diff --git a/.circleci/config.yml b/.circleci/config.yml
index 4725eb32a..ba36559bc 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -21,7 +21,12 @@ jobs:
steps:
- checkout
- - run: sudo apt update && sudo apt install zlib1g-dev libsqlite3-dev
+ - run:
+ name: "Create Environment file and generate app key"
+ command: |
+ mv .env.testing .env
+
+ - run: sudo apt install zlib1g-dev libsqlite3-dev
# Download and cache dependencies
@@ -36,18 +41,17 @@ jobs:
- run: composer install -n --prefer-dist
- save_cache:
- key: composer-v2-{{ checksum "composer.lock" }}
+ key: v2-dependencies-{{ checksum "composer.json" }}
paths:
- vendor
- - run: cp .env.testing .env
- run: php artisan config:cache
- run: php artisan route:clear
- run: php artisan storage:link
- run: php artisan key:generate
# run tests with phpunit or codecept
- - run: ./vendor/bin/phpunit
+ - run: php artisan test
- store_test_results:
path: tests/_output
- store_artifacts:
diff --git a/app/Console/Commands/AvatarStorage.php b/app/Console/Commands/AvatarStorage.php
index 054802f42..a6bb70e3d 100644
--- a/app/Console/Commands/AvatarStorage.php
+++ b/app/Console/Commands/AvatarStorage.php
@@ -82,7 +82,7 @@ class AvatarStorage extends Command
$this->line(' ');
- if(config_cache('pixelfed.cloud_storage')) {
+ if((bool) config_cache('pixelfed.cloud_storage')) {
$this->info('✅ - Cloud storage configured');
$this->line(' ');
}
@@ -92,7 +92,7 @@ class AvatarStorage extends Command
$this->line(' ');
}
- if(config_cache('pixelfed.cloud_storage') && config('instance.avatar.local_to_cloud')) {
+ if((bool) config_cache('pixelfed.cloud_storage') && config('instance.avatar.local_to_cloud')) {
$disk = Storage::disk(config_cache('filesystems.cloud'));
$exists = $disk->exists('cache/avatars/default.jpg');
$state = $exists ? '✅' : '❌';
@@ -100,7 +100,7 @@ class AvatarStorage extends Command
$this->info($msg);
}
- $options = config_cache('pixelfed.cloud_storage') && config('instance.avatar.local_to_cloud') ?
+ $options = (bool) config_cache('pixelfed.cloud_storage') && config('instance.avatar.local_to_cloud') ?
[
'Cancel',
'Upload default avatar to cloud',
@@ -164,7 +164,7 @@ class AvatarStorage extends Command
protected function uploadAvatarsToCloud()
{
- if(!config_cache('pixelfed.cloud_storage') || !config('instance.avatar.local_to_cloud')) {
+ if(!(bool) config_cache('pixelfed.cloud_storage') || !config('instance.avatar.local_to_cloud')) {
$this->error('Enable cloud storage and avatar cloud storage to perform this action');
return;
}
@@ -213,7 +213,7 @@ class AvatarStorage extends Command
return;
}
- if(config_cache('pixelfed.cloud_storage') == false && config_cache('federation.avatars.store_local') == false) {
+ if((bool) config_cache('pixelfed.cloud_storage') == false && config_cache('federation.avatars.store_local') == false) {
$this->error('You have cloud storage disabled and local avatar storage disabled, we cannot refetch avatars.');
return;
}
diff --git a/app/Console/Commands/AvatarStorageDeepClean.php b/app/Console/Commands/AvatarStorageDeepClean.php
index 5840142f5..6f773bd42 100644
--- a/app/Console/Commands/AvatarStorageDeepClean.php
+++ b/app/Console/Commands/AvatarStorageDeepClean.php
@@ -44,7 +44,7 @@ class AvatarStorageDeepClean extends Command
$this->line(' ');
$storage = [
- 'cloud' => boolval(config_cache('pixelfed.cloud_storage')),
+ 'cloud' => (bool) config_cache('pixelfed.cloud_storage'),
'local' => boolval(config_cache('federation.avatars.store_local'))
];
diff --git a/app/Console/Commands/CloudMediaMigrate.php b/app/Console/Commands/CloudMediaMigrate.php
index 0f2d177b8..174b33e83 100644
--- a/app/Console/Commands/CloudMediaMigrate.php
+++ b/app/Console/Commands/CloudMediaMigrate.php
@@ -35,12 +35,16 @@ class CloudMediaMigrate extends Command
*/
public function handle()
{
- $enabled = config('pixelfed.cloud_storage');
+ $enabled = (bool) config_cache('pixelfed.cloud_storage');
if(!$enabled) {
$this->error('Cloud storage not enabled. Exiting...');
return;
}
+ if(!$this->confirm('Are you sure you want to proceed?')) {
+ return;
+ }
+
$limit = $this->option('limit');
$hugeMode = $this->option('huge');
diff --git a/app/Console/Commands/FetchMissingMediaMimeType.php b/app/Console/Commands/FetchMissingMediaMimeType.php
index 16aeb5f59..27ae23e4c 100644
--- a/app/Console/Commands/FetchMissingMediaMimeType.php
+++ b/app/Console/Commands/FetchMissingMediaMimeType.php
@@ -2,11 +2,11 @@
namespace App\Console\Commands;
-use Illuminate\Console\Command;
use App\Media;
-use Illuminate\Support\Facades\Http;
use App\Services\MediaService;
use App\Services\StatusService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Http;
class FetchMissingMediaMimeType extends Command
{
@@ -29,20 +29,20 @@ class FetchMissingMediaMimeType extends Command
*/
public function handle()
{
- foreach(Media::whereNotNull(['remote_url', 'status_id'])->whereNull('mime')->lazyByIdDesc(50, 'id') as $media) {
+ foreach (Media::whereNotNull(['remote_url', 'status_id'])->whereNull('mime')->lazyByIdDesc(50, 'id') as $media) {
$res = Http::retry(2, 100, throw: false)->head($media->remote_url);
- if(!$res->successful()) {
+ if (! $res->successful()) {
continue;
}
- if(!in_array($res->header('content-type'), explode(',',config('pixelfed.media_types')))) {
+ if (! in_array($res->header('content-type'), explode(',', config_cache('pixelfed.media_types')))) {
continue;
}
$media->mime = $res->header('content-type');
- if($res->hasHeader('content-length')) {
+ if ($res->hasHeader('content-length')) {
$media->size = $res->header('content-length');
}
@@ -50,7 +50,7 @@ class FetchMissingMediaMimeType extends Command
MediaService::del($media->status_id);
StatusService::del($media->status_id);
- $this->info('mid:'.$media->id . ' (' . $res->header('content-type') . ':' . $res->header('content-length') . ' bytes)');
+ $this->info('mid:'.$media->id.' ('.$res->header('content-type').':'.$res->header('content-length').' bytes)');
}
}
}
diff --git a/app/Console/Commands/FixMediaDriver.php b/app/Console/Commands/FixMediaDriver.php
index c743d6c64..a20b0574e 100644
--- a/app/Console/Commands/FixMediaDriver.php
+++ b/app/Console/Commands/FixMediaDriver.php
@@ -37,7 +37,7 @@ class FixMediaDriver extends Command
return Command::SUCCESS;
}
- if(config_cache('pixelfed.cloud_storage') == false) {
+ if((bool) config_cache('pixelfed.cloud_storage') == false) {
$this->error('Cloud storage not enabled, exiting...');
return Command::SUCCESS;
}
diff --git a/app/Console/Commands/MediaCloudUrlRewrite.php b/app/Console/Commands/MediaCloudUrlRewrite.php
index 54329f7c7..367c22d1f 100644
--- a/app/Console/Commands/MediaCloudUrlRewrite.php
+++ b/app/Console/Commands/MediaCloudUrlRewrite.php
@@ -47,7 +47,7 @@ class MediaCloudUrlRewrite extends Command implements PromptsForMissingInput
protected function preflightCheck()
{
- if(config_cache('pixelfed.cloud_storage') != true) {
+ if(!(bool) config_cache('pixelfed.cloud_storage')) {
$this->info('Error: Cloud storage is not enabled!');
$this->error('Aborting...');
exit;
diff --git a/app/Console/Commands/MediaS3GarbageCollector.php b/app/Console/Commands/MediaS3GarbageCollector.php
index b6cda43c3..e66fdd2a8 100644
--- a/app/Console/Commands/MediaS3GarbageCollector.php
+++ b/app/Console/Commands/MediaS3GarbageCollector.php
@@ -45,7 +45,7 @@ class MediaS3GarbageCollector extends Command
*/
public function handle()
{
- $enabled = in_array(config_cache('pixelfed.cloud_storage'), ['1', true, 'true']);
+ $enabled = (bool) config_cache('pixelfed.cloud_storage');
if(!$enabled) {
$this->error('Cloud storage not enabled. Exiting...');
return;
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index dcee73ee1..938696a1d 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -33,7 +33,7 @@ class Kernel extends ConsoleKernel
$schedule->command('gc:passwordreset')->dailyAt('09:41')->onOneServer();
$schedule->command('gc:sessions')->twiceDaily(13, 23)->onOneServer();
- if (in_array(config_cache('pixelfed.cloud_storage'), ['1', true, 'true']) && config('media.delete_local_after_cloud')) {
+ if ((bool) config_cache('pixelfed.cloud_storage') && (bool) config_cache('media.delete_local_after_cloud')) {
$schedule->command('media:s3gc')->hourlyAt(15);
}
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 90810008b..7000ace07 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -157,7 +157,7 @@ class AccountController extends Controller
$pid = $request->user()->profile_id;
$count = UserFilterService::muteCount($pid);
- $maxLimit = intval(config('instance.user_filters.max_user_mutes'));
+ $maxLimit = (int) config_cache('instance.user_filters.max_user_mutes');
abort_if($count >= $maxLimit, 422, self::FILTER_LIMIT_MUTE_TEXT . $maxLimit . ' accounts');
if($count == 0) {
$filterCount = UserFilter::whereUserId($pid)->count();
@@ -260,7 +260,7 @@ class AccountController extends Controller
]);
$pid = $request->user()->profile_id;
$count = UserFilterService::blockCount($pid);
- $maxLimit = intval(config('instance.user_filters.max_user_blocks'));
+ $maxLimit = (int) config_cache('instance.user_filters.max_user_blocks');
abort_if($count >= $maxLimit, 422, self::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts');
if($count == 0) {
$filterCount = UserFilter::whereUserId($pid)->whereFilterType('block')->count();
diff --git a/app/Http/Controllers/Admin/AdminDirectoryController.php b/app/Http/Controllers/Admin/AdminDirectoryController.php
index 8d3e4b7fc..ce53ea560 100644
--- a/app/Http/Controllers/Admin/AdminDirectoryController.php
+++ b/app/Http/Controllers/Admin/AdminDirectoryController.php
@@ -2,30 +2,20 @@
namespace App\Http\Controllers\Admin;
-use DB, Cache;
-use App\{
- DiscoverCategory,
- DiscoverCategoryHashtag,
- Hashtag,
- Media,
- Profile,
- Status,
- StatusHashtag,
- User
-};
+use App\Http\Controllers\PixelfedDirectoryController;
use App\Models\ConfigCache;
use App\Services\AccountService;
use App\Services\ConfigCacheService;
use App\Services\StatusService;
-use Carbon\Carbon;
+use App\Status;
+use App\User;
+use Cache;
use Illuminate\Http\Request;
-use Illuminate\Validation\Rule;
-use League\ISO3166\ISO3166;
-use Illuminate\Support\Str;
+use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
-use Illuminate\Support\Facades\Http;
-use App\Http\Controllers\PixelfedDirectoryController;
+use Illuminate\Support\Str;
+use League\ISO3166\ISO3166;
trait AdminDirectoryController
{
@@ -41,37 +31,37 @@ trait AdminDirectoryController
$res['countries'] = collect((new ISO3166)->all())->pluck('name');
$res['admins'] = User::whereIsAdmin(true)
->where('2fa_enabled', true)
- ->get()->map(function($user) {
- return [
- 'uid' => (string) $user->id,
- 'pid' => (string) $user->profile_id,
- 'username' => $user->username,
- 'created_at' => $user->created_at
- ];
- });
+ ->get()->map(function ($user) {
+ return [
+ 'uid' => (string) $user->id,
+ 'pid' => (string) $user->profile_id,
+ 'username' => $user->username,
+ 'created_at' => $user->created_at,
+ ];
+ });
$config = ConfigCache::whereK('pixelfed.directory')->first();
- if($config) {
+ if ($config) {
$data = $config->v ? json_decode($config->v, true) : [];
$res = array_merge($res, $data);
}
- if(empty($res['summary'])) {
+ if (empty($res['summary'])) {
$summary = ConfigCache::whereK('app.short_description')->pluck('v');
$res['summary'] = $summary ? $summary[0] : null;
}
- if(isset($res['banner_image']) && !empty($res['banner_image'])) {
+ if (isset($res['banner_image']) && ! empty($res['banner_image'])) {
$res['banner_image'] = url(Storage::url($res['banner_image']));
}
- if(isset($res['favourite_posts'])) {
- $res['favourite_posts'] = collect($res['favourite_posts'])->map(function($id) {
+ if (isset($res['favourite_posts'])) {
+ $res['favourite_posts'] = collect($res['favourite_posts'])->map(function ($id) {
return StatusService::get($id);
})
- ->filter(function($post) {
- return $post && isset($post['account']);
- })
- ->values();
+ ->filter(function ($post) {
+ return $post && isset($post['account']);
+ })
+ ->values();
}
$res['community_guidelines'] = config_cache('app.rules') ? json_decode(config_cache('app.rules'), true) : [];
@@ -84,22 +74,22 @@ trait AdminDirectoryController
$res['feature_config'] = [
'media_types' => Str::of(config_cache('pixelfed.media_types'))->explode(','),
'image_quality' => config_cache('pixelfed.image_quality'),
- 'optimize_image' => config_cache('pixelfed.optimize_image'),
+ 'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
'max_photo_size' => config_cache('pixelfed.max_photo_size'),
'max_caption_length' => config_cache('pixelfed.max_caption_length'),
'max_altext_length' => config_cache('pixelfed.max_altext_length'),
- 'enforce_account_limit' => config_cache('pixelfed.enforce_account_limit'),
+ 'enforce_account_limit' => (bool) config_cache('pixelfed.enforce_account_limit'),
'max_account_size' => config_cache('pixelfed.max_account_size'),
'max_album_length' => config_cache('pixelfed.max_album_length'),
- 'account_deletion' => config_cache('pixelfed.account_deletion'),
+ 'account_deletion' => (bool) config_cache('pixelfed.account_deletion'),
];
- if(config_cache('pixelfed.directory.testimonials')) {
- $testimonials = collect(json_decode(config_cache('pixelfed.directory.testimonials'),true))
- ->map(function($t) {
+ if (config_cache('pixelfed.directory.testimonials')) {
+ $testimonials = collect(json_decode(config_cache('pixelfed.directory.testimonials'), true))
+ ->map(function ($t) {
return [
'profile' => AccountService::get($t['profile_id']),
- 'body' => $t['body']
+ 'body' => $t['body'],
];
});
$res['testimonials'] = $testimonials;
@@ -108,8 +98,8 @@ trait AdminDirectoryController
$validator = Validator::make($res['feature_config'], [
'media_types' => [
'required',
- function ($attribute, $value, $fail) {
- if (!in_array('image/jpeg', $value->toArray()) || !in_array('image/png', $value->toArray())) {
+ function ($attribute, $value, $fail) {
+ if (! in_array('image/jpeg', $value->toArray()) || ! in_array('image/png', $value->toArray())) {
$fail('You must enable image/jpeg and image/png support.');
}
},
@@ -120,7 +110,7 @@ trait AdminDirectoryController
'max_account_size' => 'required_if:enforce_account_limit,true|integer|min:1000000',
'max_album_length' => 'required|integer|min:4|max:20',
'account_deletion' => 'required|accepted',
- 'max_caption_length' => 'required|integer|min:500|max:10000'
+ 'max_caption_length' => 'required|integer|min:500|max:10000',
]);
$res['requirements_validator'] = $validator->errors();
@@ -146,11 +136,11 @@ trait AdminDirectoryController
foreach (new \DirectoryIterator($path) as $io) {
$name = $io->getFilename();
$skip = ['vendor'];
- if($io->isDot() || in_array($name, $skip)) {
+ if ($io->isDot() || in_array($name, $skip)) {
continue;
}
- if($io->isDir()) {
+ if ($io->isDir()) {
$langs->push(['code' => $name, 'name' => locale_get_display_name($name)]);
}
}
@@ -159,25 +149,26 @@ trait AdminDirectoryController
$res['primary_locale'] = config('app.locale');
$submissionState = Http::withoutVerifying()
- ->post('https://pixelfed.org/api/v1/directory/check-submission', [
- 'domain' => config('pixelfed.domain.app')
- ]);
+ ->post('https://pixelfed.org/api/v1/directory/check-submission', [
+ 'domain' => config('pixelfed.domain.app'),
+ ]);
$res['submission_state'] = $submissionState->json();
+
return $res;
}
protected function validVal($res, $val, $count = false, $minLen = false)
{
- if(!isset($res[$val])) {
+ if (! isset($res[$val])) {
return false;
}
- if($count) {
+ if ($count) {
return count($res[$val]) >= $count;
}
- if($minLen) {
+ if ($minLen) {
return strlen($res[$val]) >= $minLen;
}
@@ -194,11 +185,11 @@ trait AdminDirectoryController
'favourite_posts' => 'array|max:12',
'favourite_posts.*' => 'distinct',
'privacy_pledge' => 'sometimes',
- 'banner_image' => 'sometimes|mimes:jpg,png|dimensions:width=1920,height:1080|max:5000'
+ 'banner_image' => 'sometimes|mimes:jpg,png|dimensions:width=1920,height:1080|max:5000',
]);
$config = ConfigCache::firstOrNew([
- 'k' => 'pixelfed.directory'
+ 'k' => 'pixelfed.directory',
]);
$res = $config->v ? json_decode($config->v, true) : [];
@@ -208,26 +199,27 @@ trait AdminDirectoryController
$res['contact_email'] = $request->input('contact_email');
$res['privacy_pledge'] = (bool) $request->input('privacy_pledge');
- if($request->filled('location')) {
+ if ($request->filled('location')) {
$exists = (new ISO3166)->name($request->location);
- if($exists) {
+ if ($exists) {
$res['location'] = $request->input('location');
}
}
- if($request->hasFile('banner_image')) {
+ if ($request->hasFile('banner_image')) {
collect(Storage::files('public/headers'))
- ->filter(function($name) {
- $protected = [
- 'public/headers/.gitignore',
- 'public/headers/default.jpg',
- 'public/headers/missing.png'
- ];
- return !in_array($name, $protected);
- })
- ->each(function($name) {
- Storage::delete($name);
- });
+ ->filter(function ($name) {
+ $protected = [
+ 'public/headers/.gitignore',
+ 'public/headers/default.jpg',
+ 'public/headers/missing.png',
+ ];
+
+ return ! in_array($name, $protected);
+ })
+ ->each(function ($name) {
+ Storage::delete($name);
+ });
$path = $request->file('banner_image')->storePublicly('public/headers');
$res['banner_image'] = $path;
ConfigCacheService::put('app.banner_image', url(Storage::url($path)));
@@ -240,9 +232,10 @@ trait AdminDirectoryController
ConfigCacheService::put('pixelfed.directory', $config->v);
$updated = json_decode($config->v, true);
- if(isset($updated['banner_image'])) {
+ if (isset($updated['banner_image'])) {
$updated['banner_image'] = url(Storage::url($updated['banner_image']));
}
+
return $updated;
}
@@ -253,7 +246,7 @@ trait AdminDirectoryController
'open_registration' => (bool) config_cache('pixelfed.open_registration'),
'curated_onboarding' => (bool) config_cache('instance.curated_registration.enabled'),
'activitypub_enabled' => config_cache('federation.activitypub.enabled'),
- 'oauth_enabled' => config_cache('pixelfed.oauth_enabled'),
+ 'oauth_enabled' => (bool) config_cache('pixelfed.oauth_enabled'),
'media_types' => Str::of(config_cache('pixelfed.media_types'))->explode(','),
'image_quality' => config_cache('pixelfed.image_quality'),
'optimize_image' => config_cache('pixelfed.optimize_image'),
@@ -273,8 +266,8 @@ trait AdminDirectoryController
'oauth_enabled' => 'required|accepted',
'media_types' => [
'required',
- function ($attribute, $value, $fail) {
- if (!in_array('image/jpeg', $value->toArray()) || !in_array('image/png', $value->toArray())) {
+ function ($attribute, $value, $fail) {
+ if (! in_array('image/jpeg', $value->toArray()) || ! in_array('image/png', $value->toArray())) {
$fail('You must enable image/jpeg and image/png support.');
}
},
@@ -285,10 +278,10 @@ trait AdminDirectoryController
'max_account_size' => 'required_if:enforce_account_limit,true|integer|min:1000000',
'max_album_length' => 'required|integer|min:4|max:20',
'account_deletion' => 'required|accepted',
- 'max_caption_length' => 'required|integer|min:500|max:10000'
+ 'max_caption_length' => 'required|integer|min:500|max:10000',
]);
- if(!$validator->validate()) {
+ if (! $validator->validate()) {
return response()->json($validator->errors(), 422);
}
@@ -297,6 +290,7 @@ trait AdminDirectoryController
$data = (new PixelfedDirectoryController())->buildListing();
$res = Http::withoutVerifying()->post('https://pixelfed.org/api/v1/directory/submission', $data);
+
return 200;
}
@@ -304,7 +298,7 @@ trait AdminDirectoryController
{
$bannerImage = ConfigCache::whereK('app.banner_image')->first();
$directory = ConfigCache::whereK('pixelfed.directory')->first();
- if(!$bannerImage && !$directory || empty($directory->v)) {
+ if (! $bannerImage && ! $directory || empty($directory->v)) {
return;
}
$directoryArr = json_decode($directory->v, true);
@@ -312,12 +306,12 @@ trait AdminDirectoryController
$protected = [
'public/headers/.gitignore',
'public/headers/default.jpg',
- 'public/headers/missing.png'
+ 'public/headers/missing.png',
];
- if(!$path || in_array($path, $protected)) {
+ if (! $path || in_array($path, $protected)) {
return;
}
- if(Storage::exists($directoryArr['banner_image'])) {
+ if (Storage::exists($directoryArr['banner_image'])) {
Storage::delete($directoryArr['banner_image']);
}
@@ -328,12 +322,13 @@ trait AdminDirectoryController
$bannerImage->save();
Cache::forget('api:v1:instance-data-response-v1');
ConfigCacheService::put('pixelfed.directory', $directory);
+
return $bannerImage->v;
}
public function directoryGetPopularPosts(Request $request)
{
- $ids = Cache::remember('admin:api:popular_posts', 86400, function() {
+ $ids = Cache::remember('admin:api:popular_posts', 86400, function () {
return Status::whereLocal(true)
->whereScope('public')
->whereType('photo')
@@ -343,21 +338,21 @@ trait AdminDirectoryController
->pluck('id');
});
- $res = $ids->map(function($id) {
+ $res = $ids->map(function ($id) {
return StatusService::get($id);
})
- ->filter(function($post) {
- return $post && isset($post['account']);
- })
- ->values();
+ ->filter(function ($post) {
+ return $post && isset($post['account']);
+ })
+ ->values();
- return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
+ return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
public function directoryGetAddPostByIdSearch(Request $request)
{
$this->validate($request, [
- 'q' => 'required|integer'
+ 'q' => 'required|integer',
]);
$id = $request->input('q');
@@ -380,11 +375,12 @@ trait AdminDirectoryController
$profile_id = $request->input('profile_id');
$testimonials = ConfigCache::whereK('pixelfed.directory.testimonials')->firstOrFail();
$existing = collect(json_decode($testimonials->v, true))
- ->filter(function($t) use($profile_id) {
+ ->filter(function ($t) use ($profile_id) {
return $t['profile_id'] !== $profile_id;
})
->values();
ConfigCacheService::put('pixelfed.directory.testimonials', $existing);
+
return $existing;
}
@@ -392,13 +388,13 @@ trait AdminDirectoryController
{
$this->validate($request, [
'username' => 'required',
- 'body' => 'required|string|min:5|max:500'
+ 'body' => 'required|string|min:5|max:500',
]);
$user = User::whereUsername($request->input('username'))->whereNull('status')->firstOrFail();
$configCache = ConfigCache::firstOrCreate([
- 'k' => 'pixelfed.directory.testimonials'
+ 'k' => 'pixelfed.directory.testimonials',
]);
$testimonials = $configCache->v ? collect(json_decode($configCache->v, true)) : collect([]);
@@ -409,7 +405,7 @@ trait AdminDirectoryController
$testimonials->push([
'profile_id' => (string) $user->profile_id,
'username' => $request->input('username'),
- 'body' => $request->input('body')
+ 'body' => $request->input('body'),
]);
$configCache->v = json_encode($testimonials->toArray());
@@ -417,8 +413,9 @@ trait AdminDirectoryController
ConfigCacheService::put('pixelfed.directory.testimonials', $configCache->v);
$res = [
'profile' => AccountService::get($user->profile_id),
- 'body' => $request->input('body')
+ 'body' => $request->input('body'),
];
+
return $res;
}
@@ -426,7 +423,7 @@ trait AdminDirectoryController
{
$this->validate($request, [
'profile_id' => 'required',
- 'body' => 'required|string|min:5|max:500'
+ 'body' => 'required|string|min:5|max:500',
]);
$profile_id = $request->input('profile_id');
@@ -434,18 +431,19 @@ trait AdminDirectoryController
$user = User::whereProfileId($profile_id)->firstOrFail();
$configCache = ConfigCache::firstOrCreate([
- 'k' => 'pixelfed.directory.testimonials'
+ 'k' => 'pixelfed.directory.testimonials',
]);
$testimonials = $configCache->v ? collect(json_decode($configCache->v, true)) : collect([]);
- $updated = $testimonials->map(function($t) use($profile_id, $body) {
- if($t['profile_id'] == $profile_id) {
+ $updated = $testimonials->map(function ($t) use ($profile_id, $body) {
+ if ($t['profile_id'] == $profile_id) {
$t['body'] = $body;
}
+
return $t;
})
- ->values();
+ ->values();
$configCache->v = json_encode($updated);
$configCache->save();
diff --git a/app/Http/Controllers/Admin/AdminSettingsController.php b/app/Http/Controllers/Admin/AdminSettingsController.php
index 525f6114c..98e16bbc0 100644
--- a/app/Http/Controllers/Admin/AdminSettingsController.php
+++ b/app/Http/Controllers/Admin/AdminSettingsController.php
@@ -7,7 +7,9 @@ use App\Models\InstanceActor;
use App\Page;
use App\Profile;
use App\Services\AccountService;
+use App\Services\AdminSettingsService;
use App\Services\ConfigCacheService;
+use App\Services\FilesystemService;
use App\User;
use App\Util\Site\Config;
use Artisan;
@@ -71,6 +73,7 @@ trait AdminSettingsController
'admin_account_id' => 'nullable',
'regs' => 'required|in:open,filtered,closed',
'account_migration' => 'nullable',
+ 'rule_delete' => 'sometimes',
]);
$orb = false;
@@ -310,4 +313,573 @@ trait AdminSettingsController
return view('admin.settings.system', compact('sys'));
}
+
+ public function settingsApiFetch(Request $request)
+ {
+ $cloud_storage = ConfigCacheService::get('pixelfed.cloud_storage');
+ $cloud_disk = config('filesystems.cloud');
+ $cloud_ready = ! empty(config('filesystems.disks.'.$cloud_disk.'.key')) && ! empty(config('filesystems.disks.'.$cloud_disk.'.secret'));
+ $types = explode(',', ConfigCacheService::get('pixelfed.media_types'));
+ $rules = ConfigCacheService::get('app.rules') ? json_decode(ConfigCacheService::get('app.rules'), true) : [];
+ $jpeg = in_array('image/jpg', $types) || in_array('image/jpeg', $types);
+ $png = in_array('image/png', $types);
+ $gif = in_array('image/gif', $types);
+ $mp4 = in_array('video/mp4', $types);
+ $webp = in_array('image/webp', $types);
+
+ $availableAdmins = User::whereIsAdmin(true)->get();
+ $currentAdmin = config_cache('instance.admin.pid') ? AccountService::get(config_cache('instance.admin.pid'), true) : null;
+ $openReg = (bool) config_cache('pixelfed.open_registration');
+ $curOnboarding = (bool) config_cache('instance.curated_registration.enabled');
+ $regState = $openReg ? 'open' : ($curOnboarding ? 'filtered' : 'closed');
+ $accountMigration = (bool) config_cache('federation.migration');
+ $autoFollow = config_cache('account.autofollow_usernames');
+ if (strlen($autoFollow) > 3) {
+ $autoFollow = explode(',', $autoFollow);
+ }
+
+ $res = AdminSettingsService::getAll();
+
+ return response()->json($res);
+ }
+
+ public function settingsApiRulesAdd(Request $request)
+ {
+ $this->validate($request, [
+ 'rule' => 'required|string|min:5|max:1000',
+ ]);
+
+ $rules = ConfigCacheService::get('app.rules');
+ $val = $request->input('rule');
+ if (! $rules) {
+ ConfigCacheService::put('app.rules', json_encode([$val]));
+ } else {
+ $json = json_decode($rules, true);
+ $count = count($json);
+ if ($count >= 30) {
+ return response()->json(['message' => 'Max rules limit reached, you can set up to 30 rules at a time.'], 400);
+ }
+ $json[] = $val;
+ ConfigCacheService::put('app.rules', json_encode(array_values($json)));
+ }
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return [$val];
+ }
+
+ public function settingsApiRulesDelete(Request $request)
+ {
+ $this->validate($request, [
+ 'rule' => 'required|string',
+ ]);
+
+ $rules = ConfigCacheService::get('app.rules');
+ $val = $request->input('rule');
+
+ if (! $rules) {
+ return [];
+ } else {
+ $json = json_decode($rules, true);
+ $idx = array_search($val, $json);
+ if ($idx !== false) {
+ unset($json[$idx]);
+ $json = array_values($json);
+ }
+ ConfigCacheService::put('app.rules', json_encode(array_values($json)));
+ }
+
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return response()->json($json);
+ }
+
+ public function settingsApiRulesDeleteAll(Request $request)
+ {
+ $rules = ConfigCacheService::get('app.rules');
+
+ if (! $rules) {
+ return [];
+ } else {
+ ConfigCacheService::put('app.rules', json_encode([]));
+ }
+
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return response()->json([]);
+ }
+
+ public function settingsApiAutofollowDelete(Request $request)
+ {
+ $this->validate($request, [
+ 'username' => 'required|string',
+ ]);
+
+ $username = $request->input('username');
+ $names = [];
+ $existing = config_cache('account.autofollow_usernames');
+ if ($existing) {
+ $names = explode(',', $existing);
+ }
+
+ if (in_array($username, $names)) {
+ $key = array_search($username, $names);
+ if ($key !== false) {
+ unset($names[$key]);
+ }
+ }
+ ConfigCacheService::put('account.autofollow_usernames', implode(',', $names));
+
+ return response()->json(['accounts' => array_values($names)]);
+ }
+
+ public function settingsApiAutofollowAdd(Request $request)
+ {
+ $this->validate($request, [
+ 'username' => 'required|string',
+ ]);
+
+ $username = $request->input('username');
+ $names = [];
+ $existing = config_cache('account.autofollow_usernames');
+ if ($existing) {
+ $names = explode(',', $existing);
+ }
+
+ if ($existing && count($names)) {
+ if (count($names) >= 5) {
+ return response()->json(['message' => 'You can only add up to 5 accounts to be autofollowed.'], 400);
+ }
+ if (in_array(strtolower($username), array_map('strtolower', $names))) {
+ return response()->json(['message' => 'User already exists, please try again.'], 400);
+ }
+ }
+
+ $p = User::whereUsername($username)->whereNull('status')->first();
+ if (! $p || in_array($p->username, $names)) {
+ abort(404);
+ }
+ array_push($names, $p->username);
+ ConfigCacheService::put('account.autofollow_usernames', implode(',', $names));
+
+ return response()->json(['accounts' => array_values($names)]);
+ }
+
+ public function settingsApiUpdateType(Request $request, $type)
+ {
+ abort_unless(in_array($type, [
+ 'posts',
+ 'platform',
+ 'home',
+ 'landing',
+ 'branding',
+ 'media',
+ 'users',
+ 'storage',
+ ]), 400);
+
+ switch ($type) {
+ case 'home':
+ return $this->settingsApiUpdateHomeType($request);
+ break;
+
+ case 'landing':
+ return $this->settingsApiUpdateLandingType($request);
+ break;
+
+ case 'posts':
+ return $this->settingsApiUpdatePostsType($request);
+ break;
+
+ case 'platform':
+ return $this->settingsApiUpdatePlatformType($request);
+ break;
+
+ case 'branding':
+ return $this->settingsApiUpdateBrandingType($request);
+ break;
+
+ case 'media':
+ return $this->settingsApiUpdateMediaType($request);
+ break;
+
+ case 'users':
+ return $this->settingsApiUpdateUsersType($request);
+ break;
+
+ case 'storage':
+ return $this->settingsApiUpdateStorageType($request);
+ break;
+
+ default:
+ abort(404);
+ break;
+ }
+ }
+
+ public function settingsApiUpdateHomeType($request)
+ {
+ $this->validate($request, [
+ 'registration_status' => 'required|in:open,filtered,closed',
+ 'cloud_storage' => 'required',
+ 'activitypub_enabled' => 'required',
+ 'account_migration' => 'required',
+ 'mobile_apis' => 'required',
+ 'stories' => 'required',
+ 'instagram_import' => 'required',
+ 'autospam_enabled' => 'required',
+ ]);
+
+ $regStatus = $request->input('registration_status');
+ ConfigCacheService::put('pixelfed.open_registration', $regStatus === 'open');
+ ConfigCacheService::put('instance.curated_registration.enabled', $regStatus === 'filtered');
+ $cloudStorage = $request->boolean('cloud_storage');
+ if ($cloudStorage !== (bool) config_cache('pixelfed.cloud_storage')) {
+ if (! $cloudStorage) {
+ ConfigCacheService::put('pixelfed.cloud_storage', false);
+ } else {
+ $cloud_disk = config('filesystems.cloud');
+ $cloud_ready = ! empty(config('filesystems.disks.'.$cloud_disk.'.key')) && ! empty(config('filesystems.disks.'.$cloud_disk.'.secret'));
+ if (! $cloud_ready) {
+ return redirect()->back()->withErrors(['cloud_storage' => 'Must configure cloud storage before enabling!']);
+ } else {
+ ConfigCacheService::put('pixelfed.cloud_storage', true);
+ }
+ }
+ }
+ ConfigCacheService::put('federation.activitypub.enabled', $request->boolean('activitypub_enabled'));
+ ConfigCacheService::put('federation.migration', $request->boolean('account_migration'));
+ ConfigCacheService::put('pixelfed.oauth_enabled', $request->boolean('mobile_apis'));
+ ConfigCacheService::put('instance.stories.enabled', $request->boolean('stories'));
+ ConfigCacheService::put('pixelfed.import.instagram.enabled', $request->boolean('instagram_import'));
+ ConfigCacheService::put('pixelfed.bouncer.enabled', $request->boolean('autospam_enabled'));
+
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Cache::forget('api:v1:instance-data:contact');
+ Config::refresh();
+
+ return $request->all();
+ }
+
+ public function settingsApiUpdateLandingType($request)
+ {
+ $this->validate($request, [
+ 'current_admin' => 'required',
+ 'show_directory' => 'required',
+ 'show_explore' => 'required',
+ ]);
+
+ ConfigCacheService::put('instance.admin.pid', $request->input('current_admin'));
+ ConfigCacheService::put('instance.landing.show_directory', $request->boolean('show_directory'));
+ ConfigCacheService::put('instance.landing.show_explore', $request->boolean('show_explore'));
+
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Cache::forget('api:v1:instance-data:contact');
+ Config::refresh();
+
+ return $request->all();
+ }
+
+ public function settingsApiUpdateMediaType($request)
+ {
+ $this->validate($request, [
+ 'image_quality' => 'required|integer|min:1|max:100',
+ 'max_album_length' => 'required|integer|min:1|max:20',
+ 'max_photo_size' => 'required|integer|min:100|max:50000',
+ 'media_types' => 'required',
+ 'optimize_image' => 'required',
+ 'optimize_video' => 'required',
+ ]);
+
+ $mediaTypes = $request->input('media_types');
+ $mediaArray = explode(',', $mediaTypes);
+ foreach ($mediaArray as $mediaType) {
+ if (! in_array($mediaType, ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4'])) {
+ return redirect()->back()->withErrors(['media_types' => 'Invalid media type']);
+ }
+ }
+
+ ConfigCacheService::put('pixelfed.media_types', $request->input('media_types'));
+ ConfigCacheService::put('pixelfed.image_quality', $request->input('image_quality'));
+ ConfigCacheService::put('pixelfed.max_album_length', $request->input('max_album_length'));
+ ConfigCacheService::put('pixelfed.max_photo_size', $request->input('max_photo_size'));
+ ConfigCacheService::put('pixelfed.optimize_image', $request->boolean('optimize_image'));
+ ConfigCacheService::put('pixelfed.optimize_video', $request->boolean('optimize_video'));
+
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Cache::forget('api:v1:instance-data:contact');
+ Config::refresh();
+
+ return $request->all();
+ }
+
+ public function settingsApiUpdateBrandingType($request)
+ {
+ $this->validate($request, [
+ 'name' => 'required',
+ 'short_description' => 'required',
+ 'long_description' => 'required',
+ ]);
+
+ ConfigCacheService::put('app.name', $request->input('name'));
+ ConfigCacheService::put('app.short_description', $request->input('short_description'));
+ ConfigCacheService::put('app.description', $request->input('long_description'));
+
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Cache::forget('api:v1:instance-data:contact');
+ Config::refresh();
+
+ return $request->all();
+ }
+
+ public function settingsApiUpdatePostsType($request)
+ {
+ $this->validate($request, [
+ 'max_caption_length' => 'required|integer|min:5|max:10000',
+ 'max_altext_length' => 'required|integer|min:5|max:40000',
+ ]);
+
+ ConfigCacheService::put('pixelfed.max_caption_length', $request->input('max_caption_length'));
+ ConfigCacheService::put('pixelfed.max_altext_length', $request->input('max_altext_length'));
+ $res = [
+ 'max_caption_length' => $request->input('max_caption_length'),
+ 'max_altext_length' => $request->input('max_altext_length'),
+ ];
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return $res;
+ }
+
+ public function settingsApiUpdatePlatformType($request)
+ {
+ $this->validate($request, [
+ 'allow_app_registration' => 'required',
+ 'app_registration_rate_limit_attempts' => 'required|integer|min:1',
+ 'app_registration_rate_limit_decay' => 'required|integer|min:1',
+ 'app_registration_confirm_rate_limit_attempts' => 'required|integer|min:1',
+ 'app_registration_confirm_rate_limit_decay' => 'required|integer|min:1',
+ 'allow_post_embeds' => 'required',
+ 'allow_profile_embeds' => 'required',
+ 'captcha_enabled' => 'required',
+ 'captcha_on_login' => 'required_if_accepted:captcha_enabled',
+ 'captcha_on_register' => 'required_if_accepted:captcha_enabled',
+ 'captcha_secret' => 'required_if_accepted:captcha_enabled',
+ 'captcha_sitekey' => 'required_if_accepted:captcha_enabled',
+ 'custom_emoji_enabled' => 'required',
+ ]);
+
+ ConfigCacheService::put('pixelfed.allow_app_registration', $request->boolean('allow_app_registration'));
+ ConfigCacheService::put('pixelfed.app_registration_rate_limit_attempts', $request->input('app_registration_rate_limit_attempts'));
+ ConfigCacheService::put('pixelfed.app_registration_rate_limit_decay', $request->input('app_registration_rate_limit_decay'));
+ ConfigCacheService::put('pixelfed.app_registration_confirm_rate_limit_attempts', $request->input('app_registration_confirm_rate_limit_attempts'));
+ ConfigCacheService::put('pixelfed.app_registration_confirm_rate_limit_decay', $request->input('app_registration_confirm_rate_limit_decay'));
+ ConfigCacheService::put('instance.embed.post', $request->boolean('allow_post_embeds'));
+ ConfigCacheService::put('instance.embed.profile', $request->boolean('allow_profile_embeds'));
+ ConfigCacheService::put('federation.custom_emoji.enabled', $request->boolean('custom_emoji_enabled'));
+ $captcha = $request->boolean('captcha_enabled');
+ if ($captcha) {
+ $secret = $request->input('captcha_secret');
+ $sitekey = $request->input('captcha_sitekey');
+ if (config_cache('captcha.secret') != $secret && strpos($secret, '*') === false) {
+ ConfigCacheService::put('captcha.secret', $secret);
+ }
+ if (config_cache('captcha.sitekey') != $sitekey && strpos($sitekey, '*') === false) {
+ ConfigCacheService::put('captcha.sitekey', $sitekey);
+ }
+ ConfigCacheService::put('captcha.active.login', $request->boolean('captcha_on_login'));
+ ConfigCacheService::put('captcha.active.register', $request->boolean('captcha_on_register'));
+ ConfigCacheService::put('captcha.triggers.login.enabled', $request->boolean('captcha_on_login'));
+ ConfigCacheService::put('captcha.enabled', true);
+ } else {
+ ConfigCacheService::put('captcha.enabled', false);
+ }
+ $res = [
+ 'allow_app_registration' => $request->boolean('allow_app_registration'),
+ 'app_registration_rate_limit_attempts' => $request->input('app_registration_rate_limit_attempts'),
+ 'app_registration_rate_limit_decay' => $request->input('app_registration_rate_limit_decay'),
+ 'app_registration_confirm_rate_limit_attempts' => $request->input('app_registration_confirm_rate_limit_attempts'),
+ 'app_registration_confirm_rate_limit_decay' => $request->input('app_registration_confirm_rate_limit_decay'),
+ 'allow_post_embeds' => $request->boolean('allow_post_embeds'),
+ 'allow_profile_embeds' => $request->boolean('allow_profile_embeds'),
+ 'captcha_enabled' => $request->boolean('captcha_enabled'),
+ 'captcha_on_login' => $request->boolean('captcha_on_login'),
+ 'captcha_on_register' => $request->boolean('captcha_on_register'),
+ 'captcha_secret' => $request->input('captcha_secret'),
+ 'captcha_sitekey' => $request->input('captcha_sitekey'),
+ 'custom_emoji_enabled' => $request->boolean('custom_emoji_enabled'),
+ ];
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return $res;
+ }
+
+ public function settingsApiUpdateUsersType($request)
+ {
+ $this->validate($request, [
+ 'require_email_verification' => 'required',
+ 'enforce_account_limit' => 'required',
+ 'max_account_size' => 'required|integer|min:50000',
+ 'admin_autofollow' => 'required',
+ 'admin_autofollow_accounts' => 'sometimes',
+ 'max_user_blocks' => 'required|integer|min:0|max:5000',
+ 'max_user_mutes' => 'required|integer|min:0|max:5000',
+ 'max_domain_blocks' => 'required|integer|min:0|max:5000',
+ ]);
+
+ $adminAutofollow = $request->boolean('admin_autofollow');
+ $adminAutofollowAccounts = $request->input('admin_autofollow_accounts');
+ if ($adminAutofollow) {
+ if ($request->filled('admin_autofollow_accounts')) {
+ $names = [];
+ $existing = config_cache('account.autofollow_usernames');
+ if ($existing) {
+ $names = explode(',', $existing);
+ foreach (array_map('strtolower', $adminAutofollowAccounts) as $afc) {
+ if (in_array(strtolower($afc), array_map('strtolower', $names))) {
+ continue;
+ }
+ $names[] = $afc;
+ }
+ } else {
+ $names = $adminAutofollowAccounts;
+ }
+ if (! $names || count($names) == 0) {
+ return response()->json(['message' => 'You need to assign autofollow accounts before you can enable it.'], 400);
+ }
+ if (count($names) > 5) {
+ return response()->json(['message' => 'You can only add up to 5 accounts to be autofollowed.'.json_encode($names)], 400);
+ }
+ $autofollows = User::whereIn('username', $names)->whereNull('status')->pluck('username');
+ $adminAutofollowAccounts = $autofollows->implode(',');
+ ConfigCacheService::put('account.autofollow_usernames', $adminAutofollowAccounts);
+ } else {
+ return response()->json(['message' => 'You need to assign autofollow accounts before you can enable it.'], 400);
+ }
+ }
+
+ ConfigCacheService::put('pixelfed.enforce_email_verification', $request->boolean('require_email_verification'));
+ ConfigCacheService::put('pixelfed.enforce_account_limit', $request->boolean('enforce_account_limit'));
+ ConfigCacheService::put('pixelfed.max_account_size', $request->input('max_account_size'));
+ ConfigCacheService::put('account.autofollow', $request->boolean('admin_autofollow'));
+ ConfigCacheService::put('instance.user_filters.max_user_blocks', (int) $request->input('max_user_blocks'));
+ ConfigCacheService::put('instance.user_filters.max_user_mutes', (int) $request->input('max_user_mutes'));
+ ConfigCacheService::put('instance.user_filters.max_domain_blocks', (int) $request->input('max_domain_blocks'));
+ $res = [
+ 'require_email_verification' => $request->boolean('require_email_verification'),
+ 'enforce_account_limit' => $request->boolean('enforce_account_limit'),
+ 'admin_autofollow' => $request->boolean('admin_autofollow'),
+ 'admin_autofollow_accounts' => $adminAutofollowAccounts,
+ 'max_user_blocks' => $request->input('max_user_blocks'),
+ 'max_user_mutes' => $request->input('max_user_mutes'),
+ 'max_domain_blocks' => $request->input('max_domain_blocks'),
+ ];
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return $res;
+ }
+
+ public function settingsApiUpdateStorageType($request)
+ {
+ $this->validate($request, [
+ 'primary_disk' => 'required|in:local,cloud',
+ 'update_disk' => 'sometimes',
+ 'disk_config' => 'required_if_accepted:update_disk',
+ 'disk_config.driver' => 'required|in:s3,spaces',
+ 'disk_config.key' => 'required',
+ 'disk_config.secret' => 'required',
+ 'disk_config.region' => 'required',
+ 'disk_config.bucket' => 'required',
+ 'disk_config.visibility' => 'required',
+ 'disk_config.endpoint' => 'required',
+ 'disk_config.url' => 'nullable',
+ ]);
+
+ ConfigCacheService::put('pixelfed.cloud_storage', $request->input('primary_disk') === 'cloud');
+ $res = [
+ 'primary_disk' => $request->input('primary_disk'),
+ ];
+ if ($request->has('update_disk')) {
+ $res['disk_config'] = $request->input('disk_config');
+ $changes = [];
+ $dkey = $request->input('disk_config.driver') === 's3' ? 'filesystems.disks.s3.' : 'filesystems.disks.spaces.';
+ $key = $request->input('disk_config.key');
+ $ckey = null;
+ $secret = $request->input('disk_config.secret');
+ $csecret = null;
+ $region = $request->input('disk_config.region');
+ $bucket = $request->input('disk_config.bucket');
+ $visibility = $request->input('disk_config.visibility');
+ $url = $request->input('disk_config.url');
+ $endpoint = $request->input('disk_config.endpoint');
+ if (strpos($key, '*') === false && $key != config_cache($dkey.'key')) {
+ array_push($changes, 'key');
+ } else {
+ $ckey = config_cache($dkey.'key');
+ }
+ if (strpos($secret, '*') === false && $secret != config_cache($dkey.'secret')) {
+ array_push($changes, 'secret');
+ } else {
+ $csecret = config_cache($dkey.'secret');
+ }
+ if ($region != config_cache($dkey.'region')) {
+ array_push($changes, 'region');
+ }
+ if ($bucket != config_cache($dkey.'bucket')) {
+ array_push($changes, 'bucket');
+ }
+ if ($visibility != config_cache($dkey.'visibility')) {
+ array_push($changes, 'visibility');
+ }
+ if ($url != config_cache($dkey.'url')) {
+ array_push($changes, 'url');
+ }
+ if ($endpoint != config_cache($dkey.'endpoint')) {
+ array_push($changes, 'endpoint');
+ }
+
+ if ($changes && count($changes)) {
+ $isValid = FilesystemService::getVerifyCredentials(
+ $ckey ?? $key,
+ $csecret ?? $secret,
+ $region,
+ $bucket,
+ $endpoint,
+ );
+ if (! $isValid) {
+ return response()->json(['error' => true, 's3_vce' => true, 'message' => "
The S3/Spaces credentials you provided are invalid, or the bucket does not have the proper permissions.
Please check all fields and try again.Any cloud storage configuration changes you made have NOT been saved due to invalid credentials. "], 400);
+ }
+ }
+ $res['changes'] = json_encode($changes);
+ }
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response-v1');
+ Cache::forget('api:v2:instance-data-response-v2');
+ Config::refresh();
+
+ return $res;
+ }
}
diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index e54908a41..102c1a901 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -424,7 +424,7 @@ class AdminController extends Controller
public function customEmojiHome(Request $request)
{
- if(!config('federation.custom_emoji.enabled')) {
+ if(!(bool) config_cache('federation.custom_emoji.enabled')) {
return view('admin.custom-emoji.not-enabled');
}
$this->validate($request, [
@@ -497,7 +497,7 @@ class AdminController extends Controller
public function customEmojiToggleActive(Request $request, $id)
{
- abort_unless(config('federation.custom_emoji.enabled'), 404);
+ abort_unless((bool) config_cache('federation.custom_emoji.enabled'), 404);
$emoji = CustomEmoji::findOrFail($id);
$emoji->disabled = !$emoji->disabled;
$emoji->save();
@@ -508,13 +508,13 @@ class AdminController extends Controller
public function customEmojiAdd(Request $request)
{
- abort_unless(config('federation.custom_emoji.enabled'), 404);
+ abort_unless((bool) config_cache('federation.custom_emoji.enabled'), 404);
return view('admin.custom-emoji.add');
}
public function customEmojiStore(Request $request)
{
- abort_unless(config('federation.custom_emoji.enabled'), 404);
+ abort_unless((bool) config_cache('federation.custom_emoji.enabled'), 404);
$this->validate($request, [
'shortcode' => [
'required',
@@ -545,7 +545,7 @@ class AdminController extends Controller
public function customEmojiDelete(Request $request, $id)
{
- abort_unless(config('federation.custom_emoji.enabled'), 404);
+ abort_unless((bool) config_cache('federation.custom_emoji.enabled'), 404);
$emoji = CustomEmoji::findOrFail($id);
Storage::delete("public/{$emoji->media_path}");
Cache::forget('pf:custom_emoji');
@@ -555,7 +555,7 @@ class AdminController extends Controller
public function customEmojiShowDuplicates(Request $request, $id)
{
- abort_unless(config('federation.custom_emoji.enabled'), 404);
+ abort_unless((bool) config_cache('federation.custom_emoji.enabled'), 404);
$emoji = CustomEmoji::orderBy('id')->whereDisabled(false)->whereShortcode($id)->firstOrFail();
$emojis = CustomEmoji::whereShortcode($id)->where('id', '!=', $emoji->id)->cursorPaginate(10);
return view('admin.custom-emoji.duplicates', compact('emoji', 'emojis'));
diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php
index 0463e681e..fefc85442 100644
--- a/app/Http/Controllers/Api/ApiV1Controller.php
+++ b/app/Http/Controllers/Api/ApiV1Controller.php
@@ -131,7 +131,7 @@ class ApiV1Controller extends Controller
*/
public function apps(Request $request)
{
- abort_if(! config_cache('pixelfed.oauth_enabled'), 404);
+ abort_if(! (bool) config_cache('pixelfed.oauth_enabled'), 404);
$this->validate($request, [
'client_name' => 'required',
@@ -1103,7 +1103,7 @@ class ApiV1Controller extends Controller
}
$count = UserFilterService::blockCount($pid);
- $maxLimit = intval(config('instance.user_filters.max_user_blocks'));
+ $maxLimit = (int) config_cache('instance.user_filters.max_user_blocks');
if ($count == 0) {
$filterCount = UserFilter::whereUserId($pid)
->whereFilterType('block')
@@ -1632,7 +1632,7 @@ class ApiV1Controller extends Controller
return [
'uri' => config('pixelfed.domain.app'),
- 'title' => config('app.name'),
+ 'title' => config_cache('app.name'),
'short_description' => config_cache('app.short_description'),
'description' => config_cache('app.description'),
'email' => config('instance.email'),
@@ -1650,11 +1650,11 @@ class ApiV1Controller extends Controller
'configuration' => [
'media_attachments' => [
'image_matrix_limit' => 16777216,
- 'image_size_limit' => config('pixelfed.max_photo_size') * 1024,
- 'supported_mime_types' => explode(',', config('pixelfed.media_types')),
+ 'image_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
+ 'supported_mime_types' => explode(',', config_cache('pixelfed.media_types')),
'video_frame_rate_limit' => 120,
'video_matrix_limit' => 2304000,
- 'video_size_limit' => config('pixelfed.max_photo_size') * 1024,
+ 'video_size_limit' => config_cache('pixelfed.max_photo_size') * 1024,
],
'polls' => [
'max_characters_per_option' => 50,
@@ -1665,7 +1665,7 @@ class ApiV1Controller extends Controller
'statuses' => [
'characters_reserved_per_url' => 23,
'max_characters' => (int) config_cache('pixelfed.max_caption_length'),
- 'max_media_attachments' => (int) config('pixelfed.max_album_length'),
+ 'max_media_attachments' => (int) config_cache('pixelfed.max_album_length'),
],
],
];
@@ -2145,7 +2145,7 @@ class ApiV1Controller extends Controller
}
$count = UserFilterService::muteCount($pid);
- $maxLimit = intval(config('instance.user_filters.max_user_mutes'));
+ $maxLimit = (int) config_cache('instance.user_filters.max_user_mutes');
if ($count == 0) {
$filterCount = UserFilter::whereUserId($pid)
->whereFilterType('mute')
@@ -3308,9 +3308,9 @@ class ApiV1Controller extends Controller
abort_unless($request->user()->tokenCan('write'), 403);
$this->validate($request, [
- 'status' => 'nullable|string|max:' . config_cache('pixelfed.max_caption_length'),
+ 'status' => 'nullable|string|max:'.(int) config_cache('pixelfed.max_caption_length'),
'in_reply_to_id' => 'nullable',
- 'media_ids' => 'sometimes|array|max:'.config_cache('pixelfed.max_album_length'),
+ 'media_ids' => 'sometimes|array|max:'.(int) config_cache('pixelfed.max_album_length'),
'sensitive' => 'nullable',
'visibility' => 'string|in:private,unlisted,public',
'spoiler_text' => 'sometimes|max:140',
@@ -3436,7 +3436,7 @@ class ApiV1Controller extends Controller
$mimes = [];
foreach ($ids as $k => $v) {
- if ($k + 1 > config_cache('pixelfed.max_album_length')) {
+ if ($k + 1 > (int) config_cache('pixelfed.max_album_length')) {
continue;
}
$m = Media::whereUserId($user->id)->whereNull('status_id')->findOrFail($v);
diff --git a/app/Http/Controllers/Api/V1/DomainBlockController.php b/app/Http/Controllers/Api/V1/DomainBlockController.php
index 5a2698361..3b6730789 100644
--- a/app/Http/Controllers/Api/V1/DomainBlockController.php
+++ b/app/Http/Controllers/Api/V1/DomainBlockController.php
@@ -72,7 +72,7 @@ class DomainBlockController extends Controller
abort_if(config_cache('pixelfed.domain.app') == $domain, 400, 'Cannot ban your own server');
$existingCount = UserDomainBlock::whereProfileId($pid)->count();
- $maxLimit = config('instance.user_filters.max_domain_blocks');
+ $maxLimit = (int) config_cache('instance.user_filters.max_domain_blocks');
$errorMsg = __('profile.block.domain.max', ['max' => $maxLimit]);
abort_if($existingCount >= $maxLimit, 400, $errorMsg);
diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php
index 618c495e2..22562e985 100644
--- a/app/Http/Controllers/Auth/ForgotPasswordController.php
+++ b/app/Http/Controllers/Auth/ForgotPasswordController.php
@@ -62,7 +62,7 @@ class ForgotPasswordController extends Controller
usleep(random_int(100000, 3000000));
- if(config('captcha.enabled')) {
+ if((bool) config_cache('captcha.enabled')) {
$rules = [
'email' => 'required|email',
'h-captcha-response' => 'required|captcha'
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index 627a879cc..86ee52c84 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -74,10 +74,10 @@ class LoginController extends Controller
$messages = [];
if(
- config('captcha.enabled') ||
- config('captcha.active.login') ||
+ (bool) config_cache('captcha.enabled') &&
+ (bool) config_cache('captcha.active.login') ||
(
- config('captcha.triggers.login.enabled') &&
+ (bool) config_cache('captcha.triggers.login.enabled') &&
request()->session()->has('login_attempts') &&
request()->session()->get('login_attempts') >= config('captcha.triggers.login.attempts')
)
diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php
index 8bdd57bf8..7568fca09 100644
--- a/app/Http/Controllers/Auth/RegisterController.php
+++ b/app/Http/Controllers/Auth/RegisterController.php
@@ -137,7 +137,7 @@ class RegisterController extends Controller
'password' => 'required|string|min:'.config('pixelfed.min_password_length').'|confirmed',
];
- if(config('captcha.enabled') || config('captcha.active.register')) {
+ if((bool) config_cache('captcha.enabled') && (bool) config_cache('captcha.active.register')) {
$rules['h-captcha-response'] = 'required|captcha';
}
diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php
index a92c4e38d..166ec01e3 100644
--- a/app/Http/Controllers/Auth/ResetPasswordController.php
+++ b/app/Http/Controllers/Auth/ResetPasswordController.php
@@ -50,7 +50,7 @@ class ResetPasswordController extends Controller
{
usleep(random_int(100000, 3000000));
- if(config('captcha.enabled')) {
+ if((bool) config_cache('captcha.enabled')) {
return [
'token' => 'required',
'email' => 'required|email',
diff --git a/app/Http/Controllers/ComposeController.php b/app/Http/Controllers/ComposeController.php
index 341d56ea8..4c27aa18e 100644
--- a/app/Http/Controllers/ComposeController.php
+++ b/app/Http/Controllers/ComposeController.php
@@ -741,7 +741,7 @@ class ComposeController extends Controller
case 'image/jpeg':
case 'image/png':
case 'video/mp4':
- $finished = config_cache('pixelfed.cloud_storage') ? (bool) $media->cdn_url : (bool) $media->processed_at;
+ $finished = (bool) config_cache('pixelfed.cloud_storage') ? (bool) $media->cdn_url : (bool) $media->processed_at;
break;
default:
diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php
index 55c7b4393..54ad03227 100644
--- a/app/Http/Controllers/FederationController.php
+++ b/app/Http/Controllers/FederationController.php
@@ -2,57 +2,42 @@
namespace App\Http\Controllers;
-use App\Jobs\InboxPipeline\{
- DeleteWorker,
- InboxWorker,
- InboxValidator
-};
-use App\Jobs\RemoteFollowPipeline\RemoteFollowPipeline;
-use App\{
- AccountLog,
- Like,
- Profile,
- Status,
- User
-};
-use App\Util\Lexer\Nickname;
-use App\Util\Webfinger\Webfinger;
-use Auth;
-use Cache;
-use Carbon\Carbon;
-use Illuminate\Http\Request;
-use League\Fractal;
-use App\Util\Site\Nodeinfo;
-use App\Util\ActivityPub\{
- Helpers,
- HttpSignature,
- Outbox
-};
-use Zttp\Zttp;
-use App\Services\InstanceService;
+use App\Jobs\InboxPipeline\DeleteWorker;
+use App\Jobs\InboxPipeline\InboxValidator;
+use App\Jobs\InboxPipeline\InboxWorker;
+use App\Profile;
use App\Services\AccountService;
+use App\Services\InstanceService;
+use App\Status;
+use App\Util\Lexer\Nickname;
+use App\Util\Site\Nodeinfo;
+use App\Util\Webfinger\Webfinger;
+use Cache;
+use Illuminate\Http\Request;
class FederationController extends Controller
{
public function nodeinfoWellKnown()
{
- abort_if(!config('federation.nodeinfo.enabled'), 404);
+ abort_if(! config('federation.nodeinfo.enabled'), 404);
+
return response()->json(Nodeinfo::wellKnown(), 200, [], JSON_UNESCAPED_SLASHES)
- ->header('Access-Control-Allow-Origin','*');
+ ->header('Access-Control-Allow-Origin', '*');
}
public function nodeinfo()
{
- abort_if(!config('federation.nodeinfo.enabled'), 404);
+ abort_if(! config('federation.nodeinfo.enabled'), 404);
+
return response()->json(Nodeinfo::get(), 200, [], JSON_UNESCAPED_SLASHES)
- ->header('Access-Control-Allow-Origin','*');
+ ->header('Access-Control-Allow-Origin', '*');
}
public function webfinger(Request $request)
{
- if (!config('federation.webfinger.enabled') ||
- !$request->has('resource') ||
- !$request->filled('resource')
+ if (! config('federation.webfinger.enabled') ||
+ ! $request->has('resource') ||
+ ! $request->filled('resource')
) {
return response('', 400);
}
@@ -60,55 +45,56 @@ class FederationController extends Controller
$resource = $request->input('resource');
$domain = config('pixelfed.domain.app');
- if(config('federation.activitypub.sharedInbox') &&
- $resource == 'acct:' . $domain . '@' . $domain) {
+ if (config('federation.activitypub.sharedInbox') &&
+ $resource == 'acct:'.$domain.'@'.$domain) {
$res = [
- 'subject' => 'acct:' . $domain . '@' . $domain,
+ 'subject' => 'acct:'.$domain.'@'.$domain,
'aliases' => [
- 'https://' . $domain . '/i/actor'
+ 'https://'.$domain.'/i/actor',
],
'links' => [
[
'rel' => 'http://webfinger.net/rel/profile-page',
'type' => 'text/html',
- 'href' => 'https://' . $domain . '/site/kb/instance-actor'
+ 'href' => 'https://'.$domain.'/site/kb/instance-actor',
],
[
'rel' => 'self',
'type' => 'application/activity+json',
- 'href' => 'https://' . $domain . '/i/actor'
- ]
- ]
+ 'href' => 'https://'.$domain.'/i/actor',
+ ],
+ ],
];
+
return response()->json($res, 200, [], JSON_UNESCAPED_SLASHES);
}
$hash = hash('sha256', $resource);
- $key = 'federation:webfinger:sha256:' . $hash;
- if($cached = Cache::get($key)) {
+ $key = 'federation:webfinger:sha256:'.$hash;
+ if ($cached = Cache::get($key)) {
return response()->json($cached, 200, [], JSON_UNESCAPED_SLASHES);
}
- if(strpos($resource, $domain) == false) {
+ if (strpos($resource, $domain) == false) {
return response('', 400);
}
$parsed = Nickname::normalizeProfileUrl($resource);
- if(empty($parsed) || $parsed['domain'] !== $domain) {
+ if (empty($parsed) || $parsed['domain'] !== $domain) {
return response('', 400);
}
$username = $parsed['username'];
$profile = Profile::whereNull('domain')->whereUsername($username)->first();
- if(!$profile || $profile->status !== null) {
+ if (! $profile || $profile->status !== null) {
return response('', 400);
}
$webfinger = (new Webfinger($profile))->generate();
Cache::put($key, $webfinger, 1209600);
return response()->json($webfinger, 200, [], JSON_UNESCAPED_SLASHES)
- ->header('Access-Control-Allow-Origin','*');
+ ->header('Access-Control-Allow-Origin', '*');
}
public function hostMeta(Request $request)
{
- abort_if(!config('federation.webfinger.enabled'), 404);
+ abort_if(! config('federation.webfinger.enabled'), 404);
$path = route('well-known.webfinger');
$xml = ' ';
@@ -118,19 +104,19 @@ class FederationController extends Controller
public function userOutbox(Request $request, $username)
{
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
- if(!$request->wantsJson()) {
- return redirect('/' . $username);
+ if (! $request->wantsJson()) {
+ return redirect('/'.$username);
}
$id = AccountService::usernameToId($username);
- abort_if(!$id, 404);
+ abort_if(! $id, 404);
$account = AccountService::get($id);
- abort_if(!$account || !isset($account['statuses_count']), 404);
+ abort_if(! $account || ! isset($account['statuses_count']), 404);
$res = [
'@context' => 'https://www.w3.org/ns/activitystreams',
- 'id' => 'https://' . config('pixelfed.domain.app') . '/users/' . $username . '/outbox',
+ 'id' => 'https://'.config('pixelfed.domain.app').'/users/'.$username.'/outbox',
'type' => 'OrderedCollection',
'totalItems' => $account['statuses_count'] ?? 0,
];
@@ -140,135 +126,145 @@ class FederationController extends Controller
public function userInbox(Request $request, $username)
{
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
- abort_if(!config('federation.activitypub.inbox'), 404);
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! config('federation.activitypub.inbox'), 404);
$headers = $request->headers->all();
$payload = $request->getContent();
- if(!$payload || empty($payload)) {
+ if (! $payload || empty($payload)) {
return;
}
$obj = json_decode($payload, true, 8);
- if(!isset($obj['id'])) {
+ if (! isset($obj['id'])) {
return;
}
$domain = parse_url($obj['id'], PHP_URL_HOST);
- if(in_array($domain, InstanceService::getBannedDomains())) {
+ if (in_array($domain, InstanceService::getBannedDomains())) {
return;
}
- if(isset($obj['type']) && $obj['type'] === 'Delete') {
- if(isset($obj['object']) && isset($obj['object']['type']) && isset($obj['object']['id'])) {
- if($obj['object']['type'] === 'Person') {
- if(Profile::whereRemoteUrl($obj['object']['id'])->exists()) {
+ if (isset($obj['type']) && $obj['type'] === 'Delete') {
+ if (isset($obj['object']) && isset($obj['object']['type']) && isset($obj['object']['id'])) {
+ if ($obj['object']['type'] === 'Person') {
+ if (Profile::whereRemoteUrl($obj['object']['id'])->exists()) {
dispatch(new DeleteWorker($headers, $payload))->onQueue('inbox');
+
return;
}
}
- if($obj['object']['type'] === 'Tombstone') {
- if(Status::whereObjectUrl($obj['object']['id'])->exists()) {
+ if ($obj['object']['type'] === 'Tombstone') {
+ if (Status::whereObjectUrl($obj['object']['id'])->exists()) {
dispatch(new DeleteWorker($headers, $payload))->onQueue('delete');
+
return;
}
}
- if($obj['object']['type'] === 'Story') {
+ if ($obj['object']['type'] === 'Story') {
dispatch(new DeleteWorker($headers, $payload))->onQueue('story');
+
return;
}
}
+
return;
- } else if( isset($obj['type']) && in_array($obj['type'], ['Follow', 'Accept'])) {
+ } elseif (isset($obj['type']) && in_array($obj['type'], ['Follow', 'Accept'])) {
dispatch(new InboxValidator($username, $headers, $payload))->onQueue('follow');
} else {
dispatch(new InboxValidator($username, $headers, $payload))->onQueue('high');
}
- return;
+
}
public function sharedInbox(Request $request)
{
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
- abort_if(!config('federation.activitypub.sharedInbox'), 404);
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! config('federation.activitypub.sharedInbox'), 404);
$headers = $request->headers->all();
$payload = $request->getContent();
- if(!$payload || empty($payload)) {
+ if (! $payload || empty($payload)) {
return;
}
$obj = json_decode($payload, true, 8);
- if(!isset($obj['id'])) {
+ if (! isset($obj['id'])) {
return;
}
$domain = parse_url($obj['id'], PHP_URL_HOST);
- if(in_array($domain, InstanceService::getBannedDomains())) {
+ if (in_array($domain, InstanceService::getBannedDomains())) {
return;
}
- if(isset($obj['type']) && $obj['type'] === 'Delete') {
- if(isset($obj['object']) && isset($obj['object']['type']) && isset($obj['object']['id'])) {
- if($obj['object']['type'] === 'Person') {
- if(Profile::whereRemoteUrl($obj['object']['id'])->exists()) {
+ if (isset($obj['type']) && $obj['type'] === 'Delete') {
+ if (isset($obj['object']) && isset($obj['object']['type']) && isset($obj['object']['id'])) {
+ if ($obj['object']['type'] === 'Person') {
+ if (Profile::whereRemoteUrl($obj['object']['id'])->exists()) {
dispatch(new DeleteWorker($headers, $payload))->onQueue('inbox');
+
return;
}
}
- if($obj['object']['type'] === 'Tombstone') {
- if(Status::whereObjectUrl($obj['object']['id'])->exists()) {
+ if ($obj['object']['type'] === 'Tombstone') {
+ if (Status::whereObjectUrl($obj['object']['id'])->exists()) {
dispatch(new DeleteWorker($headers, $payload))->onQueue('delete');
+
return;
}
}
- if($obj['object']['type'] === 'Story') {
+ if ($obj['object']['type'] === 'Story') {
dispatch(new DeleteWorker($headers, $payload))->onQueue('story');
+
return;
}
}
+
return;
- } else if( isset($obj['type']) && in_array($obj['type'], ['Follow', 'Accept'])) {
+ } elseif (isset($obj['type']) && in_array($obj['type'], ['Follow', 'Accept'])) {
dispatch(new InboxWorker($headers, $payload))->onQueue('follow');
} else {
dispatch(new InboxWorker($headers, $payload))->onQueue('shared');
}
- return;
+
}
public function userFollowing(Request $request, $username)
{
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
$id = AccountService::usernameToId($username);
- abort_if(!$id, 404);
+ abort_if(! $id, 404);
$account = AccountService::get($id);
- abort_if(!$account || !isset($account['following_count']), 404);
+ abort_if(! $account || ! isset($account['following_count']), 404);
$obj = [
'@context' => 'https://www.w3.org/ns/activitystreams',
- 'id' => $request->getUri(),
- 'type' => 'OrderedCollection',
+ 'id' => $request->getUri(),
+ 'type' => 'OrderedCollection',
'totalItems' => $account['following_count'] ?? 0,
];
+
return response()->json($obj)->header('Content-Type', 'application/activity+json');
}
public function userFollowers(Request $request, $username)
{
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
$id = AccountService::usernameToId($username);
- abort_if(!$id, 404);
+ abort_if(! $id, 404);
$account = AccountService::get($id);
- abort_if(!$account || !isset($account['followers_count']), 404);
+ abort_if(! $account || ! isset($account['followers_count']), 404);
$obj = [
'@context' => 'https://www.w3.org/ns/activitystreams',
- 'id' => $request->getUri(),
- 'type' => 'OrderedCollection',
+ 'id' => $request->getUri(),
+ 'type' => 'OrderedCollection',
'totalItems' => $account['followers_count'] ?? 0,
];
+
return response()->json($obj)->header('Content-Type', 'application/activity+json');
}
}
diff --git a/app/Http/Controllers/Import/Instagram.php b/app/Http/Controllers/Import/Instagram.php
index 95d290f61..f1b886d52 100644
--- a/app/Http/Controllers/Import/Instagram.php
+++ b/app/Http/Controllers/Import/Instagram.php
@@ -17,7 +17,7 @@ trait Instagram
{
public function instagram()
{
- if(config_cache('pixelfed.import.instagram.enabled') != true) {
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
abort(404, 'Feature not enabled');
}
return view('settings.import.instagram.home');
@@ -25,6 +25,9 @@ trait Instagram
public function instagramStart(Request $request)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$completed = ImportJob::whereProfileId(Auth::user()->profile->id)
->whereService('instagram')
->whereNotNull('completed_at')
@@ -38,6 +41,9 @@ trait Instagram
protected function instagramRedirectOrNew()
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$profile = Auth::user()->profile;
$exists = ImportJob::whereProfileId($profile->id)
->whereService('instagram')
@@ -61,6 +67,9 @@ trait Instagram
public function instagramStepOne(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$profile = Auth::user()->profile;
$job = ImportJob::whereProfileId($profile->id)
->whereNull('completed_at')
@@ -72,6 +81,9 @@ trait Instagram
public function instagramStepOneStore(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$max = 'max:' . config('pixelfed.import.instagram.limits.size');
$this->validate($request, [
'media.*' => 'required|mimes:bin,jpeg,png,gif|'.$max,
@@ -114,6 +126,9 @@ trait Instagram
public function instagramStepTwo(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$profile = Auth::user()->profile;
$job = ImportJob::whereProfileId($profile->id)
->whereNull('completed_at')
@@ -125,6 +140,9 @@ trait Instagram
public function instagramStepTwoStore(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$this->validate($request, [
'media' => 'required|file|max:1000'
]);
@@ -150,6 +168,9 @@ trait Instagram
public function instagramStepThree(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$profile = Auth::user()->profile;
$job = ImportJob::whereProfileId($profile->id)
->whereService('instagram')
@@ -162,6 +183,9 @@ trait Instagram
public function instagramStepThreeStore(Request $request, $uuid)
{
+ if((bool) config_cache('pixelfed.import.instagram.enabled') != true) {
+ abort(404, 'Feature not enabled');
+ }
$profile = Auth::user()->profile;
try {
diff --git a/app/Http/Controllers/ImportPostController.php b/app/Http/Controllers/ImportPostController.php
index 55f575a6e..84f230622 100644
--- a/app/Http/Controllers/ImportPostController.php
+++ b/app/Http/Controllers/ImportPostController.php
@@ -179,7 +179,7 @@ class ImportPostController extends Controller
'required',
'file',
$mimes,
- 'max:' . config('pixelfed.max_photo_size')
+ 'max:' . config_cache('pixelfed.max_photo_size')
]
]);
diff --git a/app/Http/Controllers/LandingController.php b/app/Http/Controllers/LandingController.php
index 5f9f0bba1..f90d84bc2 100644
--- a/app/Http/Controllers/LandingController.php
+++ b/app/Http/Controllers/LandingController.php
@@ -2,44 +2,43 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
-use App\Profile;
-use App\Services\AccountService;
use App\Http\Resources\DirectoryProfile;
+use App\Profile;
+use Illuminate\Http\Request;
class LandingController extends Controller
{
public function directoryRedirect(Request $request)
{
- if($request->user()) {
- return redirect('/');
- }
+ if ($request->user()) {
+ return redirect('/');
+ }
- abort_if(config_cache('instance.landing.show_directory') == false, 404);
+ abort_if((bool) config_cache('instance.landing.show_directory') == false, 404);
- return view('site.index');
+ return view('site.index');
}
public function exploreRedirect(Request $request)
{
- if($request->user()) {
- return redirect('/');
- }
+ if ($request->user()) {
+ return redirect('/');
+ }
- abort_if(config_cache('instance.landing.show_explore') == false, 404);
+ abort_if((bool) config_cache('instance.landing.show_explore') == false, 404);
- return view('site.index');
+ return view('site.index');
}
public function getDirectoryApi(Request $request)
{
- abort_if(config_cache('instance.landing.show_directory') == false, 404);
+ abort_if((bool) config_cache('instance.landing.show_directory') == false, 404);
- return DirectoryProfile::collection(
- Profile::whereNull('domain')
- ->whereIsSuggestable(true)
- ->orderByDesc('updated_at')
- ->cursorPaginate(20)
- );
+ return DirectoryProfile::collection(
+ Profile::whereNull('domain')
+ ->whereIsSuggestable(true)
+ ->orderByDesc('updated_at')
+ ->cursorPaginate(20)
+ );
}
}
diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php
index b10e75795..cbc08cb5a 100644
--- a/app/Http/Controllers/MediaController.php
+++ b/app/Http/Controllers/MediaController.php
@@ -2,30 +2,31 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
use App\Media;
+use Illuminate\Http\Request;
class MediaController extends Controller
{
- public function index(Request $request)
- {
- //return view('settings.drive.index');
- }
+ public function index(Request $request)
+ {
+ //return view('settings.drive.index');
+ abort(404);
+ }
- public function composeUpdate(Request $request, $id)
- {
+ public function composeUpdate(Request $request, $id)
+ {
abort(400, 'Endpoint deprecated');
- }
+ }
- public function fallbackRedirect(Request $request, $pid, $mhash, $uhash, $f)
- {
- abort_if(!config_cache('pixelfed.cloud_storage'), 404);
- $path = 'public/m/_v2/' . $pid . '/' . $mhash . '/' . $uhash . '/' . $f;
- $media = Media::whereProfileId($pid)
- ->whereMediaPath($path)
- ->whereNotNull('cdn_url')
- ->firstOrFail();
+ public function fallbackRedirect(Request $request, $pid, $mhash, $uhash, $f)
+ {
+ abort_if(! (bool) config_cache('pixelfed.cloud_storage'), 404);
+ $path = 'public/m/_v2/'.$pid.'/'.$mhash.'/'.$uhash.'/'.$f;
+ $media = Media::whereProfileId($pid)
+ ->whereMediaPath($path)
+ ->whereNotNull('cdn_url')
+ ->firstOrFail();
- return redirect()->away($media->cdn_url);
- }
+ return redirect()->away($media->cdn_url);
+ }
}
diff --git a/app/Http/Controllers/PixelfedDirectoryController.php b/app/Http/Controllers/PixelfedDirectoryController.php
index cfe3f690a..0d2113a04 100644
--- a/app/Http/Controllers/PixelfedDirectoryController.php
+++ b/app/Http/Controllers/PixelfedDirectoryController.php
@@ -2,37 +2,41 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
use App\Models\ConfigCache;
-use Storage;
use App\Services\AccountService;
use App\Services\StatusService;
+use Illuminate\Http\Request;
use Illuminate\Support\Str;
+use Cache;
+use Storage;
+use App\Status;
+use App\User;
class PixelfedDirectoryController extends Controller
{
public function get(Request $request)
{
- if(!$request->filled('sk')) {
+ if (! $request->filled('sk')) {
abort(404);
}
- if(!config_cache('pixelfed.directory.submission-key')) {
+ if (! config_cache('pixelfed.directory.submission-key')) {
abort(404);
}
- if(!hash_equals(config_cache('pixelfed.directory.submission-key'), $request->input('sk'))) {
+ if (! hash_equals(config_cache('pixelfed.directory.submission-key'), $request->input('sk'))) {
abort(403);
}
$res = $this->buildListing();
- return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
+
+ return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
public function buildListing()
{
$res = config_cache('pixelfed.directory');
- if($res) {
+ if ($res) {
$res = is_string($res) ? json_decode($res, true) : $res;
}
@@ -41,40 +45,40 @@ class PixelfedDirectoryController extends Controller
$res['_ts'] = config_cache('pixelfed.directory.submission-ts');
$res['version'] = config_cache('pixelfed.version');
- if(empty($res['summary'])) {
+ if (empty($res['summary'])) {
$summary = ConfigCache::whereK('app.short_description')->pluck('v');
$res['summary'] = $summary ? $summary[0] : null;
}
- if(isset($res['admin'])) {
+ if (isset($res['admin'])) {
$res['admin'] = AccountService::get($res['admin'], true);
}
- if(isset($res['banner_image']) && !empty($res['banner_image'])) {
+ if (isset($res['banner_image']) && ! empty($res['banner_image'])) {
$res['banner_image'] = url(Storage::url($res['banner_image']));
}
- if(isset($res['favourite_posts'])) {
- $res['favourite_posts'] = collect($res['favourite_posts'])->map(function($id) {
+ if (isset($res['favourite_posts'])) {
+ $res['favourite_posts'] = collect($res['favourite_posts'])->map(function ($id) {
return StatusService::get($id);
})
- ->filter(function($post) {
- return $post && isset($post['account']);
- })
- ->map(function($post) {
- return [
- 'avatar' => $post['account']['avatar'],
- 'display_name' => $post['account']['display_name'],
- 'username' => $post['account']['username'],
- 'media' => $post['media_attachments'][0]['url'],
- 'url' => $post['url']
- ];
- })
- ->values();
+ ->filter(function ($post) {
+ return $post && isset($post['account']);
+ })
+ ->map(function ($post) {
+ return [
+ 'avatar' => $post['account']['avatar'],
+ 'display_name' => $post['account']['display_name'],
+ 'username' => $post['account']['username'],
+ 'media' => $post['media_attachments'][0]['url'],
+ 'url' => $post['url'],
+ ];
+ })
+ ->values();
}
$guidelines = ConfigCache::whereK('app.rules')->first();
- if($guidelines) {
+ if ($guidelines) {
$res['community_guidelines'] = json_decode($guidelines->v, true);
}
@@ -85,27 +89,27 @@ class PixelfedDirectoryController extends Controller
$res['curated_onboarding'] = $curatedOnboarding;
$oauthEnabled = ConfigCache::whereK('pixelfed.oauth_enabled')->first();
- if($oauthEnabled) {
+ if ($oauthEnabled) {
$keys = file_exists(storage_path('oauth-public.key')) && file_exists(storage_path('oauth-private.key'));
$res['oauth_enabled'] = (bool) $oauthEnabled && $keys;
}
$activityPubEnabled = ConfigCache::whereK('federation.activitypub.enabled')->first();
- if($activityPubEnabled) {
+ if ($activityPubEnabled) {
$res['activitypub_enabled'] = (bool) $activityPubEnabled;
}
$res['feature_config'] = [
'media_types' => Str::of(config_cache('pixelfed.media_types'))->explode(','),
'image_quality' => config_cache('pixelfed.image_quality'),
- 'optimize_image' => config_cache('pixelfed.optimize_image'),
+ 'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
'max_photo_size' => config_cache('pixelfed.max_photo_size'),
'max_caption_length' => config_cache('pixelfed.max_caption_length'),
'max_altext_length' => config_cache('pixelfed.max_altext_length'),
- 'enforce_account_limit' => config_cache('pixelfed.enforce_account_limit'),
+ 'enforce_account_limit' => (bool) config_cache('pixelfed.enforce_account_limit'),
'max_account_size' => config_cache('pixelfed.max_account_size'),
'max_album_length' => config_cache('pixelfed.max_album_length'),
- 'account_deletion' => config_cache('pixelfed.account_deletion'),
+ 'account_deletion' => (bool) config_cache('pixelfed.account_deletion'),
];
$res['is_eligible'] = $this->validVal($res, 'admin') &&
@@ -115,29 +119,36 @@ class PixelfedDirectoryController extends Controller
$this->validVal($res, 'privacy_pledge') &&
$this->validVal($res, 'location');
- if(config_cache('pixelfed.directory.testimonials')) {
+ if (config_cache('pixelfed.directory.testimonials')) {
$res['testimonials'] = collect(json_decode(config_cache('pixelfed.directory.testimonials'), true))
- ->map(function($testimonial) {
+ ->map(function ($testimonial) {
$profile = AccountService::get($testimonial['profile_id']);
+
return [
'profile' => [
'username' => $profile['username'],
'display_name' => $profile['display_name'],
'avatar' => $profile['avatar'],
- 'created_at' => $profile['created_at']
+ 'created_at' => $profile['created_at'],
],
- 'body' => $testimonial['body']
+ 'body' => $testimonial['body'],
];
});
}
$res['features_enabled'] = [
- 'stories' => (bool) config_cache('instance.stories.enabled')
+ 'stories' => (bool) config_cache('instance.stories.enabled'),
];
+ $statusesCount = Cache::remember('api:nodeinfo:statuses', 21600, function() {
+ return Status::whereLocal(true)->count();
+ });
+ $usersCount = Cache::remember('api:nodeinfo:users', 43200, function() {
+ return User::count();
+ });
$res['stats'] = [
- 'user_count' => \App\User::count(),
- 'post_count' => \App\Status::whereNull('uri')->count(),
+ 'user_count' => (int) $usersCount,
+ 'post_count' => (int) $statusesCount,
];
$res['primary_locale'] = config('app.locale');
@@ -150,19 +161,18 @@ class PixelfedDirectoryController extends Controller
protected function validVal($res, $val, $count = false, $minLen = false)
{
- if(!isset($res[$val])) {
+ if (! isset($res[$val])) {
return false;
}
- if($count) {
+ if ($count) {
return count($res[$val]) >= $count;
}
- if($minLen) {
+ if ($minLen) {
return strlen($res[$val]) >= $minLen;
}
return $res[$val];
}
-
}
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 6471ed760..65a756eaf 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -172,6 +172,8 @@ class ProfileController extends Controller
$user = $this->getCachedUser($username);
+ abort_if(!$user, 404);
+
return redirect($user->url());
}
@@ -371,7 +373,7 @@ class ProfileController extends Controller
public function stories(Request $request, $username)
{
- abort_if(! config_cache('instance.stories.enabled') || ! $request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
$pid = $profile->id;
$authed = Auth::user()->profile_id;
diff --git a/app/Http/Controllers/RemoteAuthController.php b/app/Http/Controllers/RemoteAuthController.php
index e068f5d75..e0afd82ef 100644
--- a/app/Http/Controllers/RemoteAuthController.php
+++ b/app/Http/Controllers/RemoteAuthController.php
@@ -2,22 +2,20 @@
namespace App\Http\Controllers;
-use Illuminate\Support\Str;
-use Illuminate\Http\Request;
-use App\Services\Account\RemoteAuthService;
use App\Models\RemoteAuth;
-use App\Profile;
-use App\Instance;
-use App\User;
-use Purify;
-use Illuminate\Support\Facades\Auth;
-use Illuminate\Support\Facades\Hash;
-use Illuminate\Auth\Events\Registered;
-use App\Util\Lexer\RestrictedNames;
+use App\Services\Account\RemoteAuthService;
use App\Services\EmailService;
use App\Services\MediaStorageService;
+use App\User;
use App\Util\ActivityPub\Helpers;
+use App\Util\Lexer\RestrictedNames;
+use Illuminate\Auth\Events\Registered;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Str;
use InvalidArgumentException;
+use Purify;
class RemoteAuthController extends Controller
{
@@ -30,9 +28,10 @@ class RemoteAuthController extends Controller
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
- if($request->user()) {
+ if ($request->user()) {
return redirect('/');
}
+
return view('auth.remote.start');
}
@@ -51,25 +50,27 @@ class RemoteAuthController extends Controller
config('remote-auth.mastodon.enabled')
), 404);
- if(config('remote-auth.mastodon.domains.only_custom')) {
+ if (config('remote-auth.mastodon.domains.only_custom')) {
$res = config('remote-auth.mastodon.domains.custom');
- if(!$res || !strlen($res)) {
+ if (! $res || ! strlen($res)) {
return [];
}
$res = explode(',', $res);
+
return response()->json($res);
}
- if( config('remote-auth.mastodon.domains.custom') &&
- !config('remote-auth.mastodon.domains.only_default') &&
+ if (config('remote-auth.mastodon.domains.custom') &&
+ ! config('remote-auth.mastodon.domains.only_default') &&
strlen(config('remote-auth.mastodon.domains.custom')) > 3 &&
strpos(config('remote-auth.mastodon.domains.custom'), '.') > -1
) {
$res = config('remote-auth.mastodon.domains.custom');
- if(!$res || !strlen($res)) {
+ if (! $res || ! strlen($res)) {
return [];
}
$res = explode(',', $res);
+
return response()->json($res);
}
@@ -93,57 +94,62 @@ class RemoteAuthController extends Controller
$domain = $request->input('domain');
- if(str_starts_with(strtolower($domain), 'http')) {
+ if (str_starts_with(strtolower($domain), 'http')) {
$res = [
'domain' => $domain,
'ready' => false,
- 'action' => 'incompatible_domain'
+ 'action' => 'incompatible_domain',
];
+
return response()->json($res);
}
- $validateInstance = Helpers::validateUrl('https://' . $domain . '/?block-check=' . time());
+ $validateInstance = Helpers::validateUrl('https://'.$domain.'/?block-check='.time());
- if(!$validateInstance) {
- $res = [
+ if (! $validateInstance) {
+ $res = [
'domain' => $domain,
'ready' => false,
- 'action' => 'blocked_domain'
+ 'action' => 'blocked_domain',
];
+
return response()->json($res);
}
$compatible = RemoteAuthService::isDomainCompatible($domain);
- if(!$compatible) {
+ if (! $compatible) {
$res = [
'domain' => $domain,
'ready' => false,
- 'action' => 'incompatible_domain'
+ 'action' => 'incompatible_domain',
];
+
return response()->json($res);
}
- if(config('remote-auth.mastodon.domains.only_default')) {
+ if (config('remote-auth.mastodon.domains.only_default')) {
$defaultDomains = explode(',', config('remote-auth.mastodon.domains.default'));
- if(!in_array($domain, $defaultDomains)) {
+ if (! in_array($domain, $defaultDomains)) {
$res = [
'domain' => $domain,
'ready' => false,
- 'action' => 'incompatible_domain'
+ 'action' => 'incompatible_domain',
];
+
return response()->json($res);
}
}
- if(config('remote-auth.mastodon.domains.only_custom') && config('remote-auth.mastodon.domains.custom')) {
+ if (config('remote-auth.mastodon.domains.only_custom') && config('remote-auth.mastodon.domains.custom')) {
$customDomains = explode(',', config('remote-auth.mastodon.domains.custom'));
- if(!in_array($domain, $customDomains)) {
+ if (! in_array($domain, $customDomains)) {
$res = [
'domain' => $domain,
'ready' => false,
- 'action' => 'incompatible_domain'
+ 'action' => 'incompatible_domain',
];
+
return response()->json($res);
}
}
@@ -163,13 +169,13 @@ class RemoteAuthController extends Controller
'state' => $state,
]);
- $request->session()->put('oauth_redirect_to', 'https://' . $domain . '/oauth/authorize?' . $query);
+ $request->session()->put('oauth_redirect_to', 'https://'.$domain.'/oauth/authorize?'.$query);
$dsh = Str::random(17);
$res = [
'domain' => $domain,
'ready' => true,
- 'dsh' => $dsh
+ 'dsh' => $dsh,
];
return response()->json($res);
@@ -185,7 +191,7 @@ class RemoteAuthController extends Controller
config('remote-auth.mastodon.enabled')
), 404);
- if(!$request->filled('d') || !$request->filled('dsh') || !$request->session()->exists('oauth_redirect_to')) {
+ if (! $request->filled('d') || ! $request->filled('dsh') || ! $request->session()->exists('oauth_redirect_to')) {
return redirect('/login');
}
@@ -204,7 +210,7 @@ class RemoteAuthController extends Controller
$domain = $request->session()->get('oauth_domain');
- if($request->filled('code')) {
+ if ($request->filled('code')) {
$code = $request->input('code');
$state = $request->session()->pull('state');
@@ -216,12 +222,14 @@ class RemoteAuthController extends Controller
$res = RemoteAuthService::getToken($domain, $code);
- if(!$res || !isset($res['access_token'])) {
+ if (! $res || ! isset($res['access_token'])) {
$request->session()->regenerate();
+
return redirect('/login');
}
$request->session()->put('oauth_remote_session_token', $res['access_token']);
+
return redirect('/auth/mastodon/getting-started');
}
@@ -237,9 +245,10 @@ class RemoteAuthController extends Controller
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
- if($request->user()) {
+ if ($request->user()) {
return redirect('/');
}
+
return view('auth.remote.onboarding');
}
@@ -261,36 +270,36 @@ class RemoteAuthController extends Controller
$res = RemoteAuthService::getVerifyCredentials($domain, $token);
- abort_if(!$res || !isset($res['acct']), 403, 'Invalid credentials');
+ abort_if(! $res || ! isset($res['acct']), 403, 'Invalid credentials');
- $webfinger = strtolower('@' . $res['acct'] . '@' . $domain);
+ $webfinger = strtolower('@'.$res['acct'].'@'.$domain);
$request->session()->put('oauth_masto_webfinger', $webfinger);
- if(config('remote-auth.mastodon.max_uses.enabled')) {
+ if (config('remote-auth.mastodon.max_uses.enabled')) {
$limit = config('remote-auth.mastodon.max_uses.limit');
$uses = RemoteAuthService::lookupWebfingerUses($webfinger);
- if($uses >= $limit) {
+ if ($uses >= $limit) {
return response()->json([
'code' => 200,
'msg' => 'Success!',
- 'action' => 'max_uses_reached'
+ 'action' => 'max_uses_reached',
]);
}
}
$exists = RemoteAuth::whereDomain($domain)->where('webfinger', $webfinger)->whereNotNull('user_id')->first();
- if($exists && $exists->user_id) {
+ if ($exists && $exists->user_id) {
return response()->json([
'code' => 200,
'msg' => 'Success!',
- 'action' => 'redirect_existing_user'
+ 'action' => 'redirect_existing_user',
]);
}
return response()->json([
'code' => 200,
'msg' => 'Success!',
- 'action' => 'onboard'
+ 'action' => 'onboard',
]);
}
@@ -311,7 +320,7 @@ class RemoteAuthController extends Controller
$token = $request->session()->get('oauth_remote_session_token');
$res = RemoteAuthService::getVerifyCredentials($domain, $token);
- $res['_webfinger'] = strtolower('@' . $res['acct'] . '@' . $domain);
+ $res['_webfinger'] = strtolower('@'.$res['acct'].'@'.$domain);
$res['_domain'] = strtolower($domain);
$request->session()->put('oauth_remasto_id', $res['id']);
@@ -324,7 +333,7 @@ class RemoteAuthController extends Controller
'bearer_token' => $token,
'verify_credentials' => $res,
'last_verify_credentials_at' => now(),
- 'last_successful_login_at' => now()
+ 'last_successful_login_at' => now(),
]);
$request->session()->put('oauth_masto_raid', $ra->id);
@@ -355,24 +364,24 @@ class RemoteAuthController extends Controller
$underscore = substr_count($value, '_');
$period = substr_count($value, '.');
- if(ends_with($value, ['.php', '.js', '.css'])) {
+ if (ends_with($value, ['.php', '.js', '.css'])) {
return $fail('Username is invalid.');
}
- if(($dash + $underscore + $period) > 1) {
+ if (($dash + $underscore + $period) > 1) {
return $fail('Username is invalid. Can only contain one dash (-), period (.) or underscore (_).');
}
- if (!ctype_alnum($value[0])) {
+ if (! ctype_alnum($value[0])) {
return $fail('Username is invalid. Must start with a letter or number.');
}
- if (!ctype_alnum($value[strlen($value) - 1])) {
+ if (! ctype_alnum($value[strlen($value) - 1])) {
return $fail('Username is invalid. Must end with a letter or number.');
}
$val = str_replace(['_', '.', '-'], '', $value);
- if(!ctype_alnum($val)) {
+ if (! ctype_alnum($val)) {
return $fail('Username is invalid. Username must be alpha-numeric and may contain dashes (-), periods (.) and underscores (_).');
}
@@ -380,8 +389,8 @@ class RemoteAuthController extends Controller
if (in_array(strtolower($value), array_map('strtolower', $restricted))) {
return $fail('Username cannot be used.');
}
- }
- ]
+ },
+ ],
]);
$username = strtolower($request->input('username'));
@@ -390,7 +399,7 @@ class RemoteAuthController extends Controller
return response()->json([
'code' => 200,
'username' => $username,
- 'exists' => $exists
+ 'exists' => $exists,
]);
}
@@ -411,7 +420,7 @@ class RemoteAuthController extends Controller
'email' => [
'required',
'email:strict,filter_unicode,dns,spoof',
- ]
+ ],
]);
$email = $request->input('email');
@@ -422,7 +431,7 @@ class RemoteAuthController extends Controller
'code' => 200,
'email' => $email,
'exists' => $exists,
- 'banned' => $banned
+ 'banned' => $banned,
]);
}
@@ -445,18 +454,18 @@ class RemoteAuthController extends Controller
$res = RemoteAuthService::getFollowing($domain, $token, $id);
- if(!$res) {
+ if (! $res) {
return response()->json([
'code' => 200,
- 'following' => []
+ 'following' => [],
]);
}
- $res = collect($res)->filter(fn($acct) => Helpers::validateUrl($acct['url']))->values()->toArray();
+ $res = collect($res)->filter(fn ($acct) => Helpers::validateUrl($acct['url']))->values()->toArray();
return response()->json([
'code' => 200,
- 'following' => $res
+ 'following' => $res,
]);
}
@@ -487,24 +496,24 @@ class RemoteAuthController extends Controller
$underscore = substr_count($value, '_');
$period = substr_count($value, '.');
- if(ends_with($value, ['.php', '.js', '.css'])) {
+ if (ends_with($value, ['.php', '.js', '.css'])) {
return $fail('Username is invalid.');
}
- if(($dash + $underscore + $period) > 1) {
+ if (($dash + $underscore + $period) > 1) {
return $fail('Username is invalid. Can only contain one dash (-), period (.) or underscore (_).');
}
- if (!ctype_alnum($value[0])) {
+ if (! ctype_alnum($value[0])) {
return $fail('Username is invalid. Must start with a letter or number.');
}
- if (!ctype_alnum($value[strlen($value) - 1])) {
+ if (! ctype_alnum($value[strlen($value) - 1])) {
return $fail('Username is invalid. Must end with a letter or number.');
}
$val = str_replace(['_', '.', '-'], '', $value);
- if(!ctype_alnum($val)) {
+ if (! ctype_alnum($val)) {
return $fail('Username is invalid. Username must be alpha-numeric and may contain dashes (-), periods (.) and underscores (_).');
}
@@ -512,10 +521,10 @@ class RemoteAuthController extends Controller
if (in_array(strtolower($value), array_map('strtolower', $restricted))) {
return $fail('Username cannot be used.');
}
- }
+ },
],
'password' => 'required|string|min:8|confirmed',
- 'name' => 'nullable|max:30'
+ 'name' => 'nullable|max:30',
]);
$email = $request->input('email');
@@ -527,7 +536,7 @@ class RemoteAuthController extends Controller
'name' => $name,
'username' => $username,
'password' => $password,
- 'email' => $email
+ 'email' => $email,
]);
$raid = $request->session()->pull('oauth_masto_raid');
@@ -541,7 +550,7 @@ class RemoteAuthController extends Controller
return [
'code' => 200,
'msg' => 'Success',
- 'token' => $token
+ 'token' => $token,
];
}
@@ -585,7 +594,7 @@ class RemoteAuthController extends Controller
abort_unless($request->session()->exists('oauth_remasto_id'), 403);
$this->validate($request, [
- 'account' => 'required|url'
+ 'account' => 'required|url',
]);
$account = $request->input('account');
@@ -594,10 +603,10 @@ class RemoteAuthController extends Controller
$host = strtolower(config('pixelfed.domain.app'));
$domain = strtolower(parse_url($account, PHP_URL_HOST));
- if($domain == $host) {
+ if ($domain == $host) {
$username = Str::of($account)->explode('/')->last();
$user = User::where('username', $username)->first();
- if($user) {
+ if ($user) {
return ['id' => (string) $user->profile_id];
} else {
return [];
@@ -605,7 +614,7 @@ class RemoteAuthController extends Controller
} else {
try {
$profile = Helpers::profileFetch($account);
- if($profile) {
+ if ($profile) {
return ['id' => (string) $profile->id];
} else {
return [];
@@ -635,13 +644,13 @@ class RemoteAuthController extends Controller
$user = $request->user();
$profile = $user->profile;
- abort_if(!$profile->avatar, 404, 'Missing avatar');
+ abort_if(! $profile->avatar, 404, 'Missing avatar');
$avatar = $profile->avatar;
$avatar->remote_url = $request->input('avatar_url');
$avatar->save();
- MediaStorageService::avatar($avatar, config_cache('pixelfed.cloud_storage') == false);
+ MediaStorageService::avatar($avatar, (bool) config_cache('pixelfed.cloud_storage') == false);
return [200];
}
@@ -657,7 +666,7 @@ class RemoteAuthController extends Controller
), 404);
abort_unless($request->user(), 404);
- $currentWebfinger = '@' . $request->user()->username . '@' . config('pixelfed.domain.app');
+ $currentWebfinger = '@'.$request->user()->username.'@'.config('pixelfed.domain.app');
$ra = RemoteAuth::where('user_id', $request->user()->id)->firstOrFail();
RemoteAuthService::submitToBeagle(
$ra->webfinger,
@@ -691,19 +700,20 @@ class RemoteAuthController extends Controller
$user = User::findOrFail($ra->user_id);
abort_if($user->is_admin || $user->status != null, 422, 'Invalid auth action');
Auth::loginUsingId($ra->user_id);
+
return [200];
}
protected function createUser($data)
{
event(new Registered($user = User::create([
- 'name' => Purify::clean($data['name']),
+ 'name' => Purify::clean($data['name']),
'username' => $data['username'],
- 'email' => $data['email'],
+ 'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_verified_at' => config('remote-auth.mastodon.contraints.skip_email_verification') ? now() : null,
'app_register_ip' => request()->ip(),
- 'register_source' => 'mastodon'
+ 'register_source' => 'mastodon',
])));
$this->guarder()->login($user);
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index cbf21518b..9388d3abd 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -2,368 +2,367 @@
namespace App\Http\Controllers;
-use Auth;
use App\Hashtag;
use App\Place;
use App\Profile;
+use App\Services\WebfingerService;
use App\Status;
-use Illuminate\Http\Request;
use App\Util\ActivityPub\Helpers;
+use Auth;
+use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
-use App\Transformer\Api\{
- AccountTransformer,
- HashtagTransformer,
- StatusTransformer,
-};
-use App\Services\WebfingerService;
class SearchController extends Controller
{
- public $tokens = [];
- public $term = '';
- public $hash = '';
- public $cacheKey = 'api:search:tag:';
+ public $tokens = [];
- public function __construct()
- {
- $this->middleware('auth');
- }
+ public $term = '';
- public function searchAPI(Request $request)
- {
- $this->validate($request, [
- 'q' => 'required|string|min:3|max:120',
- 'src' => 'required|string|in:metro',
- 'v' => 'required|integer|in:2',
- 'scope' => 'required|in:all,hashtag,profile,remote,webfinger'
- ]);
+ public $hash = '';
- $scope = $request->input('scope') ?? 'all';
- $this->term = e(urldecode($request->input('q')));
- $this->hash = hash('sha256', $this->term);
+ public $cacheKey = 'api:search:tag:';
- switch ($scope) {
- case 'all':
- $this->getHashtags();
- $this->getPosts();
- $this->getProfiles();
- // $this->getPlaces();
- break;
+ public function __construct()
+ {
+ $this->middleware('auth');
+ }
- case 'hashtag':
- $this->getHashtags();
- break;
+ public function searchAPI(Request $request)
+ {
+ $this->validate($request, [
+ 'q' => 'required|string|min:3|max:120',
+ 'src' => 'required|string|in:metro',
+ 'v' => 'required|integer|in:2',
+ 'scope' => 'required|in:all,hashtag,profile,remote,webfinger',
+ ]);
- case 'profile':
- $this->getProfiles();
- break;
+ $scope = $request->input('scope') ?? 'all';
+ $this->term = e(urldecode($request->input('q')));
+ $this->hash = hash('sha256', $this->term);
- case 'webfinger':
- $this->webfingerSearch();
- break;
+ switch ($scope) {
+ case 'all':
+ $this->getHashtags();
+ $this->getPosts();
+ $this->getProfiles();
+ // $this->getPlaces();
+ break;
- case 'remote':
- $this->remoteLookupSearch();
- break;
+ case 'hashtag':
+ $this->getHashtags();
+ break;
- case 'place':
- $this->getPlaces();
- break;
+ case 'profile':
+ $this->getProfiles();
+ break;
- default:
- break;
- }
+ case 'webfinger':
+ $this->webfingerSearch();
+ break;
- return response()->json($this->tokens, 200, [], JSON_PRETTY_PRINT);
- }
+ case 'remote':
+ $this->remoteLookupSearch();
+ break;
- protected function getPosts()
- {
- $tag = $this->term;
- $hash = hash('sha256', $tag);
- if( Helpers::validateUrl($tag) != false &&
- Helpers::validateLocalUrl($tag) != true &&
- config_cache('federation.activitypub.enabled') == true &&
- config('federation.activitypub.remoteFollow') == true
- ) {
- $remote = Helpers::fetchFromUrl($tag);
- if( isset($remote['type']) &&
- $remote['type'] == 'Note') {
- $item = Helpers::statusFetch($tag);
- $this->tokens['posts'] = [[
- 'count' => 0,
- 'url' => $item->url(),
- 'type' => 'status',
- 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)} ",
- 'tokens' => [$item->caption],
- 'name' => $item->caption,
- 'thumb' => $item->thumb(),
- ]];
- }
- } else {
- $posts = Status::select('id', 'profile_id', 'caption', 'created_at')
- ->whereHas('media')
- ->whereNull('in_reply_to_id')
- ->whereNull('reblog_of_id')
- ->whereProfileId(Auth::user()->profile_id)
- ->where('caption', 'like', '%'.$tag.'%')
- ->latest()
- ->limit(10)
- ->get();
+ case 'place':
+ $this->getPlaces();
+ break;
- if($posts->count() > 0) {
- $posts = $posts->map(function($item, $key) {
- return [
- 'count' => 0,
- 'url' => $item->url(),
- 'type' => 'status',
- 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)} ",
- 'tokens' => [$item->caption],
- 'name' => $item->caption,
- 'thumb' => $item->thumb(),
- 'filter' => $item->firstMedia()->filter_class
- ];
- });
- $this->tokens['posts'] = $posts;
- }
- }
- }
+ default:
+ break;
+ }
- protected function getHashtags()
- {
- $tag = $this->term;
- $key = $this->cacheKey . 'hashtags:' . $this->hash;
- $ttl = now()->addMinutes(1);
- $tokens = Cache::remember($key, $ttl, function() use($tag) {
- $htag = Str::startsWith($tag, '#') == true ? mb_substr($tag, 1) : $tag;
- $hashtags = Hashtag::select('id', 'name', 'slug')
- ->where('slug', 'like', '%'.$htag.'%')
- ->whereHas('posts')
- ->limit(20)
- ->get();
- if($hashtags->count() > 0) {
- $tags = $hashtags->map(function ($item, $key) {
- return [
- 'count' => $item->posts()->count(),
- 'url' => $item->url(),
- 'type' => 'hashtag',
- 'value' => $item->name,
- 'tokens' => '',
- 'name' => null,
- ];
- });
- return $tags;
- }
- });
- $this->tokens['hashtags'] = $tokens;
- }
+ return response()->json($this->tokens, 200, [], JSON_PRETTY_PRINT);
+ }
- protected function getPlaces()
- {
- $tag = $this->term;
- // $key = $this->cacheKey . 'places:' . $this->hash;
- // $ttl = now()->addHours(12);
- // $tokens = Cache::remember($key, $ttl, function() use($tag) {
- $htag = Str::contains($tag, ',') == true ? explode(',', $tag) : [$tag];
- $hashtags = Place::select('id', 'name', 'slug', 'country')
- ->where('name', 'like', '%'.$htag[0].'%')
- ->paginate(20);
- $tags = [];
- if($hashtags->count() > 0) {
- $tags = $hashtags->map(function ($item, $key) {
- return [
- 'count' => null,
- 'url' => $item->url(),
- 'type' => 'place',
- 'value' => $item->name . ', ' . $item->country,
- 'tokens' => '',
- 'name' => null,
- 'city' => $item->name,
- 'country' => $item->country
- ];
- });
- // return $tags;
- }
- // });
- $this->tokens['places'] = $tags;
- $this->tokens['placesPagination'] = [
- 'total' => $hashtags->total(),
- 'current_page' => $hashtags->currentPage(),
- 'last_page' => $hashtags->lastPage()
- ];
- }
+ protected function getPosts()
+ {
+ $tag = $this->term;
+ $hash = hash('sha256', $tag);
+ if (Helpers::validateUrl($tag) != false &&
+ Helpers::validateLocalUrl($tag) != true &&
+ (bool) config_cache('federation.activitypub.enabled') == true &&
+ config('federation.activitypub.remoteFollow') == true
+ ) {
+ $remote = Helpers::fetchFromUrl($tag);
+ if (isset($remote['type']) &&
+ in_array($remote['type'], ['Note', 'Question'])
+ ) {
+ $item = Helpers::statusFetch($tag);
+ $this->tokens['posts'] = [[
+ 'count' => 0,
+ 'url' => $item->url(),
+ 'type' => 'status',
+ 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)} ",
+ 'tokens' => [$item->caption],
+ 'name' => $item->caption,
+ 'thumb' => $item->thumb(),
+ ]];
+ }
+ } else {
+ $posts = Status::select('id', 'profile_id', 'caption', 'created_at')
+ ->whereHas('media')
+ ->whereNull('in_reply_to_id')
+ ->whereNull('reblog_of_id')
+ ->whereProfileId(Auth::user()->profile_id)
+ ->where('caption', 'like', '%'.$tag.'%')
+ ->latest()
+ ->limit(10)
+ ->get();
- protected function getProfiles()
- {
- $tag = $this->term;
- $remoteKey = $this->cacheKey . 'profiles:remote:' . $this->hash;
- $key = $this->cacheKey . 'profiles:' . $this->hash;
- $remoteTtl = now()->addMinutes(15);
- $ttl = now()->addHours(2);
- if( Helpers::validateUrl($tag) != false &&
- Helpers::validateLocalUrl($tag) != true &&
- config_cache('federation.activitypub.enabled') == true &&
- config('federation.activitypub.remoteFollow') == true
- ) {
- $remote = Helpers::fetchFromUrl($tag);
- if( isset($remote['type']) &&
- $remote['type'] == 'Person'
- ) {
- $this->tokens['profiles'] = Cache::remember($remoteKey, $remoteTtl, function() use($tag) {
- $item = Helpers::profileFirstOrNew($tag);
- $tokens = [[
- 'count' => 1,
- 'url' => $item->url(),
- 'type' => 'profile',
- 'value' => $item->username,
- 'tokens' => [$item->username],
- 'name' => $item->name,
- 'entity' => [
- 'id' => (string) $item->id,
- 'following' => $item->followedBy(Auth::user()->profile),
- 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id),
- 'thumb' => $item->avatarUrl(),
- 'local' => (bool) !$item->domain,
- 'post_count' => $item->statuses()->count()
- ]
- ]];
- return $tokens;
- });
- }
- }
+ if ($posts->count() > 0) {
+ $posts = $posts->map(function ($item, $key) {
+ return [
+ 'count' => 0,
+ 'url' => $item->url(),
+ 'type' => 'status',
+ 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)} ",
+ 'tokens' => [$item->caption],
+ 'name' => $item->caption,
+ 'thumb' => $item->thumb(),
+ 'filter' => $item->firstMedia()->filter_class,
+ ];
+ });
+ $this->tokens['posts'] = $posts;
+ }
+ }
+ }
- else {
- $this->tokens['profiles'] = Cache::remember($key, $ttl, function() use($tag) {
- if(Str::startsWith($tag, '@')) {
- $tag = substr($tag, 1);
- }
- $users = Profile::select('status', 'domain', 'username', 'name', 'id')
- ->whereNull('status')
- ->where('username', 'like', '%'.$tag.'%')
- ->limit(20)
- ->orderBy('domain')
- ->get();
+ protected function getHashtags()
+ {
+ $tag = $this->term;
+ $key = $this->cacheKey.'hashtags:'.$this->hash;
+ $ttl = now()->addMinutes(1);
+ $tokens = Cache::remember($key, $ttl, function () use ($tag) {
+ $htag = Str::startsWith($tag, '#') == true ? mb_substr($tag, 1) : $tag;
+ $hashtags = Hashtag::select('id', 'name', 'slug')
+ ->where('slug', 'like', '%'.$htag.'%')
+ ->whereHas('posts')
+ ->limit(20)
+ ->get();
+ if ($hashtags->count() > 0) {
+ $tags = $hashtags->map(function ($item, $key) {
+ return [
+ 'count' => $item->posts()->count(),
+ 'url' => $item->url(),
+ 'type' => 'hashtag',
+ 'value' => $item->name,
+ 'tokens' => '',
+ 'name' => null,
+ ];
+ });
- if($users->count() > 0) {
- return $users->map(function ($item, $key) {
- return [
- 'count' => 0,
- 'url' => $item->url(),
- 'type' => 'profile',
- 'value' => $item->username,
- 'tokens' => [$item->username],
- 'name' => $item->name,
- 'avatar' => $item->avatarUrl(),
- 'id' => (string) $item->id,
- 'entity' => [
- 'id' => (string) $item->id,
- 'following' => $item->followedBy(Auth::user()->profile),
- 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id),
- 'thumb' => $item->avatarUrl(),
- 'local' => (bool) !$item->domain,
- 'post_count' => $item->statuses()->count()
- ]
- ];
- });
- }
- });
- }
- }
+ return $tags;
+ }
+ });
+ $this->tokens['hashtags'] = $tokens;
+ }
- public function results(Request $request)
- {
- $this->validate($request, [
- 'q' => 'required|string|min:1',
- ]);
+ protected function getPlaces()
+ {
+ $tag = $this->term;
+ // $key = $this->cacheKey . 'places:' . $this->hash;
+ // $ttl = now()->addHours(12);
+ // $tokens = Cache::remember($key, $ttl, function() use($tag) {
+ $htag = Str::contains($tag, ',') == true ? explode(',', $tag) : [$tag];
+ $hashtags = Place::select('id', 'name', 'slug', 'country')
+ ->where('name', 'like', '%'.$htag[0].'%')
+ ->paginate(20);
+ $tags = [];
+ if ($hashtags->count() > 0) {
+ $tags = $hashtags->map(function ($item, $key) {
+ return [
+ 'count' => null,
+ 'url' => $item->url(),
+ 'type' => 'place',
+ 'value' => $item->name.', '.$item->country,
+ 'tokens' => '',
+ 'name' => null,
+ 'city' => $item->name,
+ 'country' => $item->country,
+ ];
+ });
+ // return $tags;
+ }
+ // });
+ $this->tokens['places'] = $tags;
+ $this->tokens['placesPagination'] = [
+ 'total' => $hashtags->total(),
+ 'current_page' => $hashtags->currentPage(),
+ 'last_page' => $hashtags->lastPage(),
+ ];
+ }
- return view('search.results');
- }
+ protected function getProfiles()
+ {
+ $tag = $this->term;
+ $remoteKey = $this->cacheKey.'profiles:remote:'.$this->hash;
+ $key = $this->cacheKey.'profiles:'.$this->hash;
+ $remoteTtl = now()->addMinutes(15);
+ $ttl = now()->addHours(2);
+ if (Helpers::validateUrl($tag) != false &&
+ Helpers::validateLocalUrl($tag) != true &&
+ (bool) config_cache('federation.activitypub.enabled') == true &&
+ config('federation.activitypub.remoteFollow') == true
+ ) {
+ $remote = Helpers::fetchFromUrl($tag);
+ if (isset($remote['type']) &&
+ $remote['type'] == 'Person'
+ ) {
+ $this->tokens['profiles'] = Cache::remember($remoteKey, $remoteTtl, function () use ($tag) {
+ $item = Helpers::profileFirstOrNew($tag);
+ $tokens = [[
+ 'count' => 1,
+ 'url' => $item->url(),
+ 'type' => 'profile',
+ 'value' => $item->username,
+ 'tokens' => [$item->username],
+ 'name' => $item->name,
+ 'entity' => [
+ 'id' => (string) $item->id,
+ 'following' => $item->followedBy(Auth::user()->profile),
+ 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id),
+ 'thumb' => $item->avatarUrl(),
+ 'local' => (bool) ! $item->domain,
+ 'post_count' => $item->statuses()->count(),
+ ],
+ ]];
- protected function webfingerSearch()
- {
- $wfs = WebfingerService::lookup($this->term);
+ return $tokens;
+ });
+ }
+ } else {
+ $this->tokens['profiles'] = Cache::remember($key, $ttl, function () use ($tag) {
+ if (Str::startsWith($tag, '@')) {
+ $tag = substr($tag, 1);
+ }
+ $users = Profile::select('status', 'domain', 'username', 'name', 'id')
+ ->whereNull('status')
+ ->where('username', 'like', '%'.$tag.'%')
+ ->limit(20)
+ ->orderBy('domain')
+ ->get();
- if(empty($wfs)) {
- return;
- }
+ if ($users->count() > 0) {
+ return $users->map(function ($item, $key) {
+ return [
+ 'count' => 0,
+ 'url' => $item->url(),
+ 'type' => 'profile',
+ 'value' => $item->username,
+ 'tokens' => [$item->username],
+ 'name' => $item->name,
+ 'avatar' => $item->avatarUrl(),
+ 'id' => (string) $item->id,
+ 'entity' => [
+ 'id' => (string) $item->id,
+ 'following' => $item->followedBy(Auth::user()->profile),
+ 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id),
+ 'thumb' => $item->avatarUrl(),
+ 'local' => (bool) ! $item->domain,
+ 'post_count' => $item->statuses()->count(),
+ ],
+ ];
+ });
+ }
+ });
+ }
+ }
- $this->tokens['profiles'] = [
- [
- 'count' => 1,
- 'url' => $wfs['url'],
- 'type' => 'profile',
- 'value' => $wfs['username'],
- 'tokens' => [$wfs['username']],
- 'name' => $wfs['display_name'],
- 'entity' => [
- 'id' => (string) $wfs['id'],
- 'following' => null,
- 'follow_request' => null,
- 'thumb' => $wfs['avatar'],
- 'local' => (bool) $wfs['local']
- ]
- ]
- ];
- return;
- }
+ public function results(Request $request)
+ {
+ $this->validate($request, [
+ 'q' => 'required|string|min:1',
+ ]);
- protected function remotePostLookup()
- {
- $tag = $this->term;
- $hash = hash('sha256', $tag);
- $local = Helpers::validateLocalUrl($tag);
- $valid = Helpers::validateUrl($tag);
+ return view('search.results');
+ }
- if($valid == false || $local == true) {
- return;
- }
+ protected function webfingerSearch()
+ {
+ $wfs = WebfingerService::lookup($this->term);
- if(Status::whereUri($tag)->whereLocal(false)->exists()) {
- $item = Status::whereUri($tag)->first();
- $media = $item->firstMedia();
- $url = null;
- if($media) {
- $url = $media->remote_url;
- }
- $this->tokens['posts'] = [[
- 'count' => 0,
- 'url' => "/i/web/post/_/$item->profile_id/$item->id",
- 'type' => 'status',
- 'username' => $item->profile->username,
- 'caption' => $item->rendered ?? $item->caption,
- 'thumb' => $url,
- 'timestamp' => $item->created_at->diffForHumans()
- ]];
- }
+ if (empty($wfs)) {
+ return;
+ }
- $remote = Helpers::fetchFromUrl($tag);
+ $this->tokens['profiles'] = [
+ [
+ 'count' => 1,
+ 'url' => $wfs['url'],
+ 'type' => 'profile',
+ 'value' => $wfs['username'],
+ 'tokens' => [$wfs['username']],
+ 'name' => $wfs['display_name'],
+ 'entity' => [
+ 'id' => (string) $wfs['id'],
+ 'following' => null,
+ 'follow_request' => null,
+ 'thumb' => $wfs['avatar'],
+ 'local' => (bool) $wfs['local'],
+ ],
+ ],
+ ];
- if(isset($remote['type']) && $remote['type'] == 'Note') {
- $item = Helpers::statusFetch($tag);
- $media = $item->firstMedia();
- $url = null;
- if($media) {
- $url = $media->remote_url;
- }
- $this->tokens['posts'] = [[
- 'count' => 0,
- 'url' => "/i/web/post/_/$item->profile_id/$item->id",
- 'type' => 'status',
- 'username' => $item->profile->username,
- 'caption' => $item->rendered ?? $item->caption,
- 'thumb' => $url,
- 'timestamp' => $item->created_at->diffForHumans()
- ]];
- }
- }
+ }
- protected function remoteLookupSearch()
- {
- if(!Helpers::validateUrl($this->term)) {
- return;
- }
- $this->getProfiles();
- $this->remotePostLookup();
- }
+ protected function remotePostLookup()
+ {
+ $tag = $this->term;
+ $hash = hash('sha256', $tag);
+ $local = Helpers::validateLocalUrl($tag);
+ $valid = Helpers::validateUrl($tag);
+
+ if ($valid == false || $local == true) {
+ return;
+ }
+
+ if (Status::whereUri($tag)->whereLocal(false)->exists()) {
+ $item = Status::whereUri($tag)->first();
+ $media = $item->firstMedia();
+ $url = null;
+ if ($media) {
+ $url = $media->remote_url;
+ }
+ $this->tokens['posts'] = [[
+ 'count' => 0,
+ 'url' => "/i/web/post/_/$item->profile_id/$item->id",
+ 'type' => 'status',
+ 'username' => $item->profile->username,
+ 'caption' => $item->rendered ?? $item->caption,
+ 'thumb' => $url,
+ 'timestamp' => $item->created_at->diffForHumans(),
+ ]];
+ }
+
+ $remote = Helpers::fetchFromUrl($tag);
+
+ if (isset($remote['type']) && $remote['type'] == 'Note') {
+ $item = Helpers::statusFetch($tag);
+ $media = $item->firstMedia();
+ $url = null;
+ if ($media) {
+ $url = $media->remote_url;
+ }
+ $this->tokens['posts'] = [[
+ 'count' => 0,
+ 'url' => "/i/web/post/_/$item->profile_id/$item->id",
+ 'type' => 'status',
+ 'username' => $item->profile->username,
+ 'caption' => $item->rendered ?? $item->caption,
+ 'thumb' => $url,
+ 'timestamp' => $item->created_at->diffForHumans(),
+ ]];
+ }
+ }
+
+ protected function remoteLookupSearch()
+ {
+ if (! Helpers::validateUrl($this->term)) {
+ return;
+ }
+ $this->getProfiles();
+ $this->remotePostLookup();
+ }
}
diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php
index 4a3b3552d..7f77f9a81 100644
--- a/app/Http/Controllers/StatusController.php
+++ b/app/Http/Controllers/StatusController.php
@@ -78,7 +78,7 @@ class StatusController extends Controller
]);
}
- if ($request->wantsJson() && config_cache('federation.activitypub.enabled')) {
+ if ($request->wantsJson() && (bool) config_cache('federation.activitypub.enabled')) {
return $this->showActivityPub($request, $status);
}
diff --git a/app/Http/Controllers/Stories/StoryApiV1Controller.php b/app/Http/Controllers/Stories/StoryApiV1Controller.php
index ca6a24791..5d0a15160 100644
--- a/app/Http/Controllers/Stories/StoryApiV1Controller.php
+++ b/app/Http/Controllers/Stories/StoryApiV1Controller.php
@@ -2,54 +2,56 @@
namespace App\Http\Controllers\Stories;
-use App\Http\Controllers\Controller;
-use Illuminate\Http\Request;
-use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\Storage;
-use App\Models\Conversation;
use App\DirectMessage;
-use App\Notification;
-use App\Story;
-use App\Status;
-use App\StoryView;
+use App\Http\Controllers\Controller;
+use App\Http\Resources\StoryView as StoryViewResource;
use App\Jobs\StoryPipeline\StoryDelete;
use App\Jobs\StoryPipeline\StoryFanout;
use App\Jobs\StoryPipeline\StoryReplyDeliver;
use App\Jobs\StoryPipeline\StoryViewDeliver;
+use App\Models\Conversation;
+use App\Notification;
use App\Services\AccountService;
use App\Services\MediaPathService;
use App\Services\StoryService;
-use App\Http\Resources\StoryView as StoryViewResource;
+use App\Status;
+use App\Story;
+use App\StoryView;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Storage;
+use Illuminate\Support\Str;
class StoryApiV1Controller extends Controller
{
const RECENT_KEY = 'pf:stories:recent-by-id:';
+
const RECENT_TTL = 300;
public function carousel(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$pid = $request->user()->profile_id;
- if(config('database.default') == 'pgsql') {
- $s = Cache::remember(self::RECENT_KEY . $pid, self::RECENT_TTL, function() use($pid) {
+ if (config('database.default') == 'pgsql') {
+ $s = Cache::remember(self::RECENT_KEY.$pid, self::RECENT_TTL, function () use ($pid) {
return Story::select('stories.*', 'followers.following_id')
->leftJoin('followers', 'followers.following_id', 'stories.profile_id')
->where('followers.profile_id', $pid)
->where('stories.active', true)
- ->map(function($s) {
- $r = new \StdClass;
+ ->map(function ($s) {
+ $r = new \StdClass;
$r->id = $s->id;
$r->profile_id = $s->profile_id;
$r->type = $s->type;
$r->path = $s->path;
+
return $r;
})
->unique('profile_id');
});
} else {
- $s = Cache::remember(self::RECENT_KEY . $pid, self::RECENT_TTL, function() use($pid) {
+ $s = Cache::remember(self::RECENT_KEY.$pid, self::RECENT_TTL, function () use ($pid) {
return Story::select('stories.*', 'followers.following_id')
->leftJoin('followers', 'followers.following_id', 'stories.profile_id')
->where('followers.profile_id', $pid)
@@ -59,9 +61,9 @@ class StoryApiV1Controller extends Controller
});
}
- $nodes = $s->map(function($s) use($pid) {
+ $nodes = $s->map(function ($s) use ($pid) {
$profile = AccountService::get($s->profile_id, true);
- if(!$profile || !isset($profile['id'])) {
+ if (! $profile || ! isset($profile['id'])) {
return false;
}
@@ -72,50 +74,51 @@ class StoryApiV1Controller extends Controller
'src' => url(Storage::url($s->path)),
'duration' => $s->duration ?? 3,
'seen' => StoryService::hasSeen($pid, $s->id),
- 'created_at' => $s->created_at->format('c')
+ 'created_at' => $s->created_at->format('c'),
];
})
- ->filter()
- ->groupBy('pid')
- ->map(function($item) use($pid) {
- $profile = AccountService::get($item[0]['pid'], true);
- $url = $profile['local'] ? url("/stories/{$profile['username']}") :
- url("/i/rs/{$profile['id']}");
- return [
- 'id' => 'pfs:' . $profile['id'],
- 'user' => [
- 'id' => (string) $profile['id'],
- 'username' => $profile['username'],
- 'username_acct' => $profile['acct'],
- 'avatar' => $profile['avatar'],
- 'local' => $profile['local'],
- 'is_author' => $profile['id'] == $pid
- ],
- 'nodes' => $item,
- 'url' => $url,
- 'seen' => StoryService::hasSeen($pid, StoryService::latest($profile['id'])),
- ];
- })
- ->sortBy('seen')
- ->values();
+ ->filter()
+ ->groupBy('pid')
+ ->map(function ($item) use ($pid) {
+ $profile = AccountService::get($item[0]['pid'], true);
+ $url = $profile['local'] ? url("/stories/{$profile['username']}") :
+ url("/i/rs/{$profile['id']}");
+
+ return [
+ 'id' => 'pfs:'.$profile['id'],
+ 'user' => [
+ 'id' => (string) $profile['id'],
+ 'username' => $profile['username'],
+ 'username_acct' => $profile['acct'],
+ 'avatar' => $profile['avatar'],
+ 'local' => $profile['local'],
+ 'is_author' => $profile['id'] == $pid,
+ ],
+ 'nodes' => $item,
+ 'url' => $url,
+ 'seen' => StoryService::hasSeen($pid, StoryService::latest($profile['id'])),
+ ];
+ })
+ ->sortBy('seen')
+ ->values();
$res = [
'self' => [],
'nodes' => $nodes,
];
- if(Story::whereProfileId($pid)->whereActive(true)->exists()) {
+ if (Story::whereProfileId($pid)->whereActive(true)->exists()) {
$selfStories = Story::whereProfileId($pid)
->whereActive(true)
->get()
- ->map(function($s) use($pid) {
+ ->map(function ($s) {
return [
'id' => (string) $s->id,
'type' => $s->type,
'src' => url(Storage::url($s->path)),
'duration' => $s->duration,
'seen' => true,
- 'created_at' => $s->created_at->format('c')
+ 'created_at' => $s->created_at->format('c'),
];
})
->sortBy('id')
@@ -127,38 +130,40 @@ class StoryApiV1Controller extends Controller
'username' => $selfProfile['acct'],
'avatar' => $selfProfile['avatar'],
'local' => $selfProfile['local'],
- 'is_author' => true
+ 'is_author' => true,
],
'nodes' => $selfStories,
];
}
- return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
+
+ return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
public function selfCarousel(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$pid = $request->user()->profile_id;
- if(config('database.default') == 'pgsql') {
- $s = Cache::remember(self::RECENT_KEY . $pid, self::RECENT_TTL, function() use($pid) {
+ if (config('database.default') == 'pgsql') {
+ $s = Cache::remember(self::RECENT_KEY.$pid, self::RECENT_TTL, function () use ($pid) {
return Story::select('stories.*', 'followers.following_id')
->leftJoin('followers', 'followers.following_id', 'stories.profile_id')
->where('followers.profile_id', $pid)
->where('stories.active', true)
- ->map(function($s) {
- $r = new \StdClass;
+ ->map(function ($s) {
+ $r = new \StdClass;
$r->id = $s->id;
$r->profile_id = $s->profile_id;
$r->type = $s->type;
$r->path = $s->path;
+
return $r;
})
->unique('profile_id');
});
} else {
- $s = Cache::remember(self::RECENT_KEY . $pid, self::RECENT_TTL, function() use($pid) {
+ $s = Cache::remember(self::RECENT_KEY.$pid, self::RECENT_TTL, function () use ($pid) {
return Story::select('stories.*', 'followers.following_id')
->leftJoin('followers', 'followers.following_id', 'stories.profile_id')
->where('followers.profile_id', $pid)
@@ -168,9 +173,9 @@ class StoryApiV1Controller extends Controller
});
}
- $nodes = $s->map(function($s) use($pid) {
+ $nodes = $s->map(function ($s) use ($pid) {
$profile = AccountService::get($s->profile_id, true);
- if(!$profile || !isset($profile['id'])) {
+ if (! $profile || ! isset($profile['id'])) {
return false;
}
@@ -181,32 +186,33 @@ class StoryApiV1Controller extends Controller
'src' => url(Storage::url($s->path)),
'duration' => $s->duration ?? 3,
'seen' => StoryService::hasSeen($pid, $s->id),
- 'created_at' => $s->created_at->format('c')
+ 'created_at' => $s->created_at->format('c'),
];
})
- ->filter()
- ->groupBy('pid')
- ->map(function($item) use($pid) {
- $profile = AccountService::get($item[0]['pid'], true);
- $url = $profile['local'] ? url("/stories/{$profile['username']}") :
- url("/i/rs/{$profile['id']}");
- return [
- 'id' => 'pfs:' . $profile['id'],
- 'user' => [
- 'id' => (string) $profile['id'],
- 'username' => $profile['username'],
- 'username_acct' => $profile['acct'],
- 'avatar' => $profile['avatar'],
- 'local' => $profile['local'],
- 'is_author' => $profile['id'] == $pid
- ],
- 'nodes' => $item,
- 'url' => $url,
- 'seen' => StoryService::hasSeen($pid, StoryService::latest($profile['id'])),
- ];
- })
- ->sortBy('seen')
- ->values();
+ ->filter()
+ ->groupBy('pid')
+ ->map(function ($item) use ($pid) {
+ $profile = AccountService::get($item[0]['pid'], true);
+ $url = $profile['local'] ? url("/stories/{$profile['username']}") :
+ url("/i/rs/{$profile['id']}");
+
+ return [
+ 'id' => 'pfs:'.$profile['id'],
+ 'user' => [
+ 'id' => (string) $profile['id'],
+ 'username' => $profile['username'],
+ 'username_acct' => $profile['acct'],
+ 'avatar' => $profile['avatar'],
+ 'local' => $profile['local'],
+ 'is_author' => $profile['id'] == $pid,
+ ],
+ 'nodes' => $item,
+ 'url' => $url,
+ 'seen' => StoryService::hasSeen($pid, StoryService::latest($profile['id'])),
+ ];
+ })
+ ->sortBy('seen')
+ ->values();
$selfProfile = AccountService::get($pid, true);
$res = [
@@ -216,7 +222,7 @@ class StoryApiV1Controller extends Controller
'username' => $selfProfile['acct'],
'avatar' => $selfProfile['avatar'],
'local' => $selfProfile['local'],
- 'is_author' => true
+ 'is_author' => true,
],
'nodes' => [],
@@ -224,40 +230,41 @@ class StoryApiV1Controller extends Controller
'nodes' => $nodes,
];
- if(Story::whereProfileId($pid)->whereActive(true)->exists()) {
+ if (Story::whereProfileId($pid)->whereActive(true)->exists()) {
$selfStories = Story::whereProfileId($pid)
->whereActive(true)
->get()
- ->map(function($s) use($pid) {
+ ->map(function ($s) {
return [
'id' => (string) $s->id,
'type' => $s->type,
'src' => url(Storage::url($s->path)),
'duration' => $s->duration,
'seen' => true,
- 'created_at' => $s->created_at->format('c')
+ 'created_at' => $s->created_at->format('c'),
];
})
->sortBy('id')
->values();
$res['self']['nodes'] = $selfStories;
}
- return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
+
+ return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
public function add(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
- 'file' => function() {
+ 'file' => function () {
return [
'required',
'mimetypes:image/jpeg,image/png,video/mp4',
- 'max:' . config_cache('pixelfed.max_photo_size'),
+ 'max:'.config_cache('pixelfed.max_photo_size'),
];
},
- 'duration' => 'sometimes|integer|min:0|max:30'
+ 'duration' => 'sometimes|integer|min:0|max:30',
]);
$user = $request->user();
@@ -267,7 +274,7 @@ class StoryApiV1Controller extends Controller
->where('expires_at', '>', now())
->count();
- if($count >= Story::MAX_PER_DAY) {
+ if ($count >= Story::MAX_PER_DAY) {
abort(418, 'You have reached your limit for new Stories today.');
}
@@ -277,7 +284,7 @@ class StoryApiV1Controller extends Controller
$story = new Story();
$story->duration = $request->input('duration', 3);
$story->profile_id = $user->profile_id;
- $story->type = Str::endsWith($photo->getMimeType(), 'mp4') ? 'video' :'photo';
+ $story->type = Str::endsWith($photo->getMimeType(), 'mp4') ? 'video' : 'photo';
$story->mime = $photo->getMimeType();
$story->path = $path;
$story->local = true;
@@ -290,10 +297,10 @@ class StoryApiV1Controller extends Controller
$res = [
'code' => 200,
- 'msg' => 'Successfully added',
+ 'msg' => 'Successfully added',
'media_id' => (string) $story->id,
- 'media_url' => url(Storage::url($url)) . '?v=' . time(),
- 'media_type' => $story->type
+ 'media_url' => url(Storage::url($url)).'?v='.time(),
+ 'media_type' => $story->type,
];
return $res;
@@ -301,13 +308,13 @@ class StoryApiV1Controller extends Controller
public function publish(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'media_id' => 'required',
'duration' => 'required|integer|min:0|max:30',
'can_reply' => 'required|boolean',
- 'can_react' => 'required|boolean'
+ 'can_react' => 'required|boolean',
]);
$id = $request->input('media_id');
@@ -327,13 +334,13 @@ class StoryApiV1Controller extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully published',
+ 'msg' => 'Successfully published',
];
}
public function delete(Request $request, $id)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$user = $request->user();
@@ -346,16 +353,16 @@ class StoryApiV1Controller extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully deleted'
+ 'msg' => 'Successfully deleted',
];
}
public function viewed(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
- 'id' => 'required|min:1',
+ 'id' => 'required|min:1',
]);
$id = $request->input('id');
@@ -367,44 +374,45 @@ class StoryApiV1Controller extends Controller
$profile = $story->profile;
- if($story->profile_id == $authed->id) {
+ if ($story->profile_id == $authed->id) {
return [];
}
$publicOnly = (bool) $profile->followedBy($authed);
- abort_if(!$publicOnly, 403);
+ abort_if(! $publicOnly, 403);
$v = StoryView::firstOrCreate([
'story_id' => $id,
- 'profile_id' => $authed->id
+ 'profile_id' => $authed->id,
]);
- if($v->wasRecentlyCreated) {
+ if ($v->wasRecentlyCreated) {
Story::findOrFail($story->id)->increment('view_count');
- if($story->local == false) {
+ if ($story->local == false) {
StoryViewDeliver::dispatch($story, $authed)->onQueue('story');
}
}
- Cache::forget('stories:recent:by_id:' . $authed->id);
+ Cache::forget('stories:recent:by_id:'.$authed->id);
StoryService::addSeen($authed->id, $story->id);
+
return ['code' => 200];
}
public function comment(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'sid' => 'required',
- 'caption' => 'required|string'
+ 'caption' => 'required|string',
]);
$pid = $request->user()->profile_id;
$text = $request->input('caption');
$story = Story::findOrFail($request->input('sid'));
- abort_if(!$story->can_reply, 422);
+ abort_if(! $story->can_reply, 422);
$status = new Status;
$status->type = 'story:reply';
@@ -415,7 +423,7 @@ class StoryApiV1Controller extends Controller
$status->visibility = 'direct';
$status->in_reply_to_profile_id = $story->profile_id;
$status->entities = json_encode([
- 'story_id' => $story->id
+ 'story_id' => $story->id,
]);
$status->save();
@@ -429,24 +437,24 @@ class StoryApiV1Controller extends Controller
'story_actor_username' => $request->user()->username,
'story_id' => $story->id,
'story_media_url' => url(Storage::url($story->path)),
- 'caption' => $text
+ 'caption' => $text,
]);
$dm->save();
Conversation::updateOrInsert(
[
'to_id' => $story->profile_id,
- 'from_id' => $pid
+ 'from_id' => $pid,
],
[
'type' => 'story:comment',
'status_id' => $status->id,
'dm_id' => $dm->id,
- 'is_hidden' => false
+ 'is_hidden' => false,
]
);
- if($story->local) {
+ if ($story->local) {
$n = new Notification;
$n->profile_id = $dm->to_id;
$n->actor_id = $dm->from_id;
@@ -460,33 +468,35 @@ class StoryApiV1Controller extends Controller
return [
'code' => 200,
- 'msg' => 'Sent!'
+ 'msg' => 'Sent!',
];
}
protected function storeMedia($photo, $user)
{
$mimes = explode(',', config_cache('pixelfed.media_types'));
- if(in_array($photo->getMimeType(), [
+ if (in_array($photo->getMimeType(), [
'image/jpeg',
'image/png',
- 'video/mp4'
+ 'video/mp4',
]) == false) {
abort(400, 'Invalid media type');
+
return;
}
$storagePath = MediaPathService::story($user->profile);
- $path = $photo->storePubliclyAs($storagePath, Str::random(random_int(2, 12)) . '_' . Str::random(random_int(32, 35)) . '_' . Str::random(random_int(1, 14)) . '.' . $photo->extension());
+ $path = $photo->storePubliclyAs($storagePath, Str::random(random_int(2, 12)).'_'.Str::random(random_int(32, 35)).'_'.Str::random(random_int(1, 14)).'.'.$photo->extension());
+
return $path;
}
public function viewers(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
- 'sid' => 'required|string|min:1|max:50'
+ 'sid' => 'required|string|min:1|max:50',
]);
$pid = $request->user()->profile_id;
diff --git a/app/Http/Controllers/StoryComposeController.php b/app/Http/Controllers/StoryComposeController.php
index eb2d859c0..c8b0599a6 100644
--- a/app/Http/Controllers/StoryComposeController.php
+++ b/app/Http/Controllers/StoryComposeController.php
@@ -2,59 +2,52 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
-use Illuminate\Support\Str;
-use App\Media;
-use App\Profile;
-use App\Report;
use App\DirectMessage;
-use App\Notification;
-use App\Status;
-use App\Story;
-use App\StoryView;
-use App\Models\Poll;
-use App\Models\PollVote;
-use App\Services\ProfileService;
-use App\Services\StoryService;
-use Cache, Storage;
-use Image as Intervention;
-use App\Services\FollowerService;
-use App\Services\MediaPathService;
-use FFMpeg;
-use FFMpeg\Coordinate\Dimension;
-use FFMpeg\Format\Video\X264;
+use App\Jobs\StoryPipeline\StoryDelete;
+use App\Jobs\StoryPipeline\StoryFanout;
use App\Jobs\StoryPipeline\StoryReactionDeliver;
use App\Jobs\StoryPipeline\StoryReplyDeliver;
-use App\Jobs\StoryPipeline\StoryFanout;
-use App\Jobs\StoryPipeline\StoryDelete;
-use ImageOptimizer;
use App\Models\Conversation;
+use App\Models\Poll;
+use App\Models\PollVote;
+use App\Notification;
+use App\Report;
+use App\Services\FollowerService;
+use App\Services\MediaPathService;
+use App\Services\StoryService;
use App\Services\UserRoleService;
+use App\Status;
+use App\Story;
+use FFMpeg;
+use Illuminate\Http\Request;
+use Illuminate\Support\Str;
+use Image as Intervention;
+use Storage;
class StoryComposeController extends Controller
{
public function apiV1Add(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
- 'file' => function() {
+ 'file' => function () {
return [
'required',
'mimetypes:image/jpeg,image/png,video/mp4',
- 'max:' . config_cache('pixelfed.max_photo_size'),
+ 'max:'.config_cache('pixelfed.max_photo_size'),
];
},
]);
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$count = Story::whereProfileId($user->profile_id)
->whereActive(true)
->where('expires_at', '>', now())
->count();
- if($count >= Story::MAX_PER_DAY) {
+ if ($count >= Story::MAX_PER_DAY) {
abort(418, 'You have reached your limit for new Stories today.');
}
@@ -64,7 +57,7 @@ class StoryComposeController extends Controller
$story = new Story();
$story->duration = 3;
$story->profile_id = $user->profile_id;
- $story->type = Str::endsWith($photo->getMimeType(), 'mp4') ? 'video' :'photo';
+ $story->type = Str::endsWith($photo->getMimeType(), 'mp4') ? 'video' : 'photo';
$story->mime = $photo->getMimeType();
$story->path = $path;
$story->local = true;
@@ -77,21 +70,22 @@ class StoryComposeController extends Controller
$res = [
'code' => 200,
- 'msg' => 'Successfully added',
+ 'msg' => 'Successfully added',
'media_id' => (string) $story->id,
- 'media_url' => url(Storage::url($url)) . '?v=' . time(),
- 'media_type' => $story->type
+ 'media_url' => url(Storage::url($url)).'?v='.time(),
+ 'media_type' => $story->type,
];
- if($story->type === 'video') {
+ if ($story->type === 'video') {
$video = FFMpeg::open($path);
$duration = $video->getDurationInSeconds();
$res['media_duration'] = $duration;
- if($duration > 500) {
+ if ($duration > 500) {
Storage::delete($story->path);
$story->delete();
+
return response()->json([
- 'message' => 'Video duration cannot exceed 60 seconds'
+ 'message' => 'Video duration cannot exceed 60 seconds',
], 422);
}
}
@@ -102,37 +96,39 @@ class StoryComposeController extends Controller
protected function storePhoto($photo, $user)
{
$mimes = explode(',', config_cache('pixelfed.media_types'));
- if(in_array($photo->getMimeType(), [
+ if (in_array($photo->getMimeType(), [
'image/jpeg',
'image/png',
- 'video/mp4'
+ 'video/mp4',
]) == false) {
abort(400, 'Invalid media type');
+
return;
}
$storagePath = MediaPathService::story($user->profile);
- $path = $photo->storePubliclyAs($storagePath, Str::random(random_int(2, 12)) . '_' . Str::random(random_int(32, 35)) . '_' . Str::random(random_int(1, 14)) . '.' . $photo->extension());
- if(in_array($photo->getMimeType(), ['image/jpeg','image/png'])) {
- $fpath = storage_path('app/' . $path);
+ $path = $photo->storePubliclyAs($storagePath, Str::random(random_int(2, 12)).'_'.Str::random(random_int(32, 35)).'_'.Str::random(random_int(1, 14)).'.'.$photo->extension());
+ if (in_array($photo->getMimeType(), ['image/jpeg', 'image/png'])) {
+ $fpath = storage_path('app/'.$path);
$img = Intervention::make($fpath);
$img->orientate();
$img->save($fpath, config_cache('pixelfed.image_quality'));
$img->destroy();
}
+
return $path;
}
public function cropPhoto(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'media_id' => 'required|integer|min:1',
'width' => 'required',
'height' => 'required',
'x' => 'required',
- 'y' => 'required'
+ 'y' => 'required',
]);
$user = $request->user();
@@ -144,13 +140,13 @@ class StoryComposeController extends Controller
$story = Story::whereProfileId($user->profile_id)->findOrFail($id);
- $path = storage_path('app/' . $story->path);
+ $path = storage_path('app/'.$story->path);
- if(!is_file($path)) {
+ if (! is_file($path)) {
abort(400, 'Invalid or missing media.');
}
- if($story->type === 'photo') {
+ if ($story->type === 'photo') {
$img = Intervention::make($path);
$img->crop($width, $height, $x, $y);
$img->resize(1080, 1920, function ($constraint) {
@@ -161,24 +157,24 @@ class StoryComposeController extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully cropped',
+ 'msg' => 'Successfully cropped',
];
}
public function publishStory(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'media_id' => 'required',
'duration' => 'required|integer|min:3|max:120',
'can_reply' => 'required|boolean',
- 'can_react' => 'required|boolean'
+ 'can_react' => 'required|boolean',
]);
$id = $request->input('media_id');
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$story = Story::whereProfileId($user->profile_id)
->findOrFail($id);
@@ -194,13 +190,13 @@ class StoryComposeController extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully published',
+ 'msg' => 'Successfully published',
];
}
public function apiV1Delete(Request $request, $id)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$user = $request->user();
@@ -213,40 +209,40 @@ class StoryComposeController extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully deleted'
+ 'msg' => 'Successfully deleted',
];
}
public function compose(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
return view('stories.compose');
}
public function createPoll(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
- abort_if(!config_cache('instance.polls.enabled'), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
+ abort_if(! config_cache('instance.polls.enabled'), 404);
return $request->all();
}
public function publishStoryPoll(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'question' => 'required|string|min:6|max:140',
'options' => 'required|array|min:2|max:4',
'can_reply' => 'required|boolean',
- 'can_react' => 'required|boolean'
+ 'can_react' => 'required|boolean',
]);
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$pid = $request->user()->profile_id;
$count = Story::whereProfileId($pid)
@@ -254,7 +250,7 @@ class StoryComposeController extends Controller
->where('expires_at', '>', now())
->count();
- if($count >= Story::MAX_PER_DAY) {
+ if ($count >= Story::MAX_PER_DAY) {
abort(418, 'You have reached your limit for new Stories today.');
}
@@ -262,7 +258,7 @@ class StoryComposeController extends Controller
$story->type = 'poll';
$story->story = json_encode([
'question' => $request->input('question'),
- 'options' => $request->input('options')
+ 'options' => $request->input('options'),
]);
$story->public = false;
$story->local = true;
@@ -278,7 +274,7 @@ class StoryComposeController extends Controller
$poll->profile_id = $pid;
$poll->poll_options = $request->input('options');
$poll->expires_at = $story->expires_at;
- $poll->cached_tallies = collect($poll->poll_options)->map(function($o) {
+ $poll->cached_tallies = collect($poll->poll_options)->map(function ($o) {
return 0;
})->toArray();
$poll->save();
@@ -290,23 +286,23 @@ class StoryComposeController extends Controller
return [
'code' => 200,
- 'msg' => 'Successfully published',
+ 'msg' => 'Successfully published',
];
}
public function storyPollVote(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'sid' => 'required',
- 'ci' => 'required|integer|min:0|max:3'
+ 'ci' => 'required|integer|min:0|max:3',
]);
$pid = $request->user()->profile_id;
$ci = $request->input('ci');
$story = Story::findOrFail($request->input('sid'));
- abort_if(!FollowerService::follows($pid, $story->profile_id), 403);
+ abort_if(! FollowerService::follows($pid, $story->profile_id), 403);
$poll = Poll::whereStoryId($story->id)->firstOrFail();
$vote = new PollVote;
@@ -318,7 +314,7 @@ class StoryComposeController extends Controller
$vote->save();
$poll->votes_count = $poll->votes_count + 1;
- $poll->cached_tallies = collect($poll->getTallies())->map(function($tally, $key) use($ci) {
+ $poll->cached_tallies = collect($poll->getTallies())->map(function ($tally, $key) use ($ci) {
return $ci == $key ? $tally + 1 : $tally;
})->toArray();
$poll->save();
@@ -328,15 +324,15 @@ class StoryComposeController extends Controller
public function storeReport(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
- 'type' => 'required|alpha_dash',
- 'id' => 'required|integer|min:1',
+ 'type' => 'required|alpha_dash',
+ 'id' => 'required|integer|min:1',
]);
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$pid = $request->user()->profile_id;
$sid = $request->input('id');
@@ -353,24 +349,24 @@ class StoryComposeController extends Controller
'copyright',
'impersonation',
'scam',
- 'terrorism'
+ 'terrorism',
];
- abort_if(!in_array($type, $types), 422, 'Invalid story report type');
+ abort_if(! in_array($type, $types), 422, 'Invalid story report type');
$story = Story::findOrFail($sid);
abort_if($story->profile_id == $pid, 422, 'Cannot report your own story');
- abort_if(!FollowerService::follows($pid, $story->profile_id), 422, 'Cannot report a story from an account you do not follow');
+ abort_if(! FollowerService::follows($pid, $story->profile_id), 422, 'Cannot report a story from an account you do not follow');
- if( Report::whereProfileId($pid)
+ if (Report::whereProfileId($pid)
->whereObjectType('App\Story')
->whereObjectId($story->id)
->exists()
) {
return response()->json(['error' => [
'code' => 409,
- 'message' => 'Cannot report the same story again'
+ 'message' => 'Cannot report the same story again',
]], 409);
}
@@ -389,18 +385,18 @@ class StoryComposeController extends Controller
public function react(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'sid' => 'required',
- 'reaction' => 'required|string'
+ 'reaction' => 'required|string',
]);
$pid = $request->user()->profile_id;
$text = $request->input('reaction');
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$story = Story::findOrFail($request->input('sid'));
- abort_if(!$story->can_react, 422);
+ abort_if(! $story->can_react, 422);
abort_if(StoryService::reactCounter($story->id, $pid) >= 5, 422, 'You have already reacted to this story');
$status = new Status;
@@ -413,7 +409,7 @@ class StoryComposeController extends Controller
$status->in_reply_to_profile_id = $story->profile_id;
$status->entities = json_encode([
'story_id' => $story->id,
- 'reaction' => $text
+ 'reaction' => $text,
]);
$status->save();
@@ -427,24 +423,24 @@ class StoryComposeController extends Controller
'story_actor_username' => $request->user()->username,
'story_id' => $story->id,
'story_media_url' => url(Storage::url($story->path)),
- 'reaction' => $text
+ 'reaction' => $text,
]);
$dm->save();
Conversation::updateOrInsert(
[
'to_id' => $story->profile_id,
- 'from_id' => $pid
+ 'from_id' => $pid,
],
[
'type' => 'story:react',
'status_id' => $status->id,
'dm_id' => $dm->id,
- 'is_hidden' => false
+ 'is_hidden' => false,
]
);
- if($story->local) {
+ if ($story->local) {
// generate notification
$n = new Notification;
$n->profile_id = $dm->to_id;
@@ -464,18 +460,18 @@ class StoryComposeController extends Controller
public function comment(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
$this->validate($request, [
'sid' => 'required',
- 'caption' => 'required|string'
+ 'caption' => 'required|string',
]);
$pid = $request->user()->profile_id;
$text = $request->input('caption');
$user = $request->user();
- abort_if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
+ abort_if($user->has_roles && ! UserRoleService::can('can-use-stories', $user->id), 403, 'Invalid permissions for this action');
$story = Story::findOrFail($request->input('sid'));
- abort_if(!$story->can_reply, 422);
+ abort_if(! $story->can_reply, 422);
$status = new Status;
$status->type = 'story:reply';
@@ -486,7 +482,7 @@ class StoryComposeController extends Controller
$status->visibility = 'direct';
$status->in_reply_to_profile_id = $story->profile_id;
$status->entities = json_encode([
- 'story_id' => $story->id
+ 'story_id' => $story->id,
]);
$status->save();
@@ -500,24 +496,24 @@ class StoryComposeController extends Controller
'story_actor_username' => $request->user()->username,
'story_id' => $story->id,
'story_media_url' => url(Storage::url($story->path)),
- 'caption' => $text
+ 'caption' => $text,
]);
$dm->save();
Conversation::updateOrInsert(
[
'to_id' => $story->profile_id,
- 'from_id' => $pid
+ 'from_id' => $pid,
],
[
'type' => 'story:comment',
'status_id' => $status->id,
'dm_id' => $dm->id,
- 'is_hidden' => false
+ 'is_hidden' => false,
]
);
- if($story->local) {
+ if ($story->local) {
// generate notification
$n = new Notification;
$n->profile_id = $dm->to_id;
diff --git a/app/Http/Controllers/StoryController.php b/app/Http/Controllers/StoryController.php
index 692e27961..fede7c6d9 100644
--- a/app/Http/Controllers/StoryController.php
+++ b/app/Http/Controllers/StoryController.php
@@ -34,7 +34,7 @@ class StoryController extends StoryComposeController
{
public function recent(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$user = $request->user();
if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id)) {
return [];
@@ -117,7 +117,7 @@ class StoryController extends StoryComposeController
public function profile(Request $request, $id)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$user = $request->user();
if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id)) {
@@ -176,7 +176,7 @@ class StoryController extends StoryComposeController
public function viewed(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$this->validate($request, [
'id' => 'required|min:1',
@@ -221,7 +221,7 @@ class StoryController extends StoryComposeController
public function exists(Request $request, $id)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$user = $request->user();
if($user->has_roles && !UserRoleService::can('can-use-stories', $user->id)) {
return response()->json(false);
@@ -233,7 +233,7 @@ class StoryController extends StoryComposeController
public function iRedirect(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$user = $request->user();
abort_if(!$user, 404);
@@ -243,7 +243,7 @@ class StoryController extends StoryComposeController
public function viewers(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$this->validate($request, [
'sid' => 'required|string'
@@ -274,7 +274,7 @@ class StoryController extends StoryComposeController
public function remoteStory(Request $request, $id)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$profile = Profile::findOrFail($id);
if($profile->user_id != null || $profile->domain == null) {
@@ -286,7 +286,7 @@ class StoryController extends StoryComposeController
public function pollResults(Request $request)
{
- abort_if(!config_cache('instance.stories.enabled') || !$request->user(), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled') || !$request->user(), 404);
$this->validate($request, [
'sid' => 'required|string'
@@ -304,7 +304,7 @@ class StoryController extends StoryComposeController
public function getActivityObject(Request $request, $username, $id)
{
- abort_if(!config_cache('instance.stories.enabled'), 404);
+ abort_if(!(bool) config_cache('instance.stories.enabled'), 404);
if(!$request->wantsJson()) {
return redirect('/stories/' . $username);
diff --git a/app/Http/Controllers/UserEmailForgotController.php b/app/Http/Controllers/UserEmailForgotController.php
index 33378c4d0..3889b9802 100644
--- a/app/Http/Controllers/UserEmailForgotController.php
+++ b/app/Http/Controllers/UserEmailForgotController.php
@@ -34,7 +34,7 @@ class UserEmailForgotController extends Controller
'username.exists' => 'This username is no longer active or does not exist!'
];
- if(config('captcha.enabled') || config('captcha.active.login') || config('captcha.active.register')) {
+ if((bool) config_cache('captcha.enabled')) {
$rules['h-captcha-response'] = 'required|captcha';
$messages['h-captcha-response.required'] = 'You need to complete the captcha!';
}
diff --git a/app/Http/Requests/Status/StoreStatusEditRequest.php b/app/Http/Requests/Status/StoreStatusEditRequest.php
index aa9364ca6..e8e2d22f5 100644
--- a/app/Http/Requests/Status/StoreStatusEditRequest.php
+++ b/app/Http/Requests/Status/StoreStatusEditRequest.php
@@ -2,10 +2,10 @@
namespace App\Http\Requests\Status;
-use Illuminate\Foundation\Http\FormRequest;
use App\Media;
use App\Status;
use Closure;
+use Illuminate\Foundation\Http\FormRequest;
class StoreStatusEditRequest extends FormRequest
{
@@ -14,24 +14,25 @@ class StoreStatusEditRequest extends FormRequest
*/
public function authorize(): bool
{
- $profile = $this->user()->profile;
- if($profile->status != null) {
- return false;
- }
- if($profile->unlisted == true && $profile->cw == true) {
- return false;
- }
- $types = [
- "photo",
- "photo:album",
- "photo:video:album",
- "reply",
- "text",
- "video",
- "video:album"
- ];
- $scopes = ['public', 'unlisted', 'private'];
- $status = Status::whereNull('reblog_of_id')->whereIn('type', $types)->whereIn('scope', $scopes)->find($this->route('id'));
+ $profile = $this->user()->profile;
+ if ($profile->status != null) {
+ return false;
+ }
+ if ($profile->unlisted == true && $profile->cw == true) {
+ return false;
+ }
+ $types = [
+ 'photo',
+ 'photo:album',
+ 'photo:video:album',
+ 'reply',
+ 'text',
+ 'video',
+ 'video:album',
+ ];
+ $scopes = ['public', 'unlisted', 'private'];
+ $status = Status::whereNull('reblog_of_id')->whereIn('type', $types)->whereIn('scope', $scopes)->find($this->route('id'));
+
return $status && $this->user()->profile_id === $status->profile_id;
}
@@ -47,18 +48,18 @@ class StoreStatusEditRequest extends FormRequest
'spoiler_text' => 'nullable|string|max:140',
'sensitive' => 'sometimes|boolean',
'media_ids' => [
- 'nullable',
- 'required_without:status',
- 'array',
- 'max:' . config('pixelfed.max_album_length'),
- function (string $attribute, mixed $value, Closure $fail) {
- Media::whereProfileId($this->user()->profile_id)
- ->where(function($query) {
- return $query->whereNull('status_id')
- ->orWhere('status_id', '=', $this->route('id'));
- })
- ->findOrFail($value);
- },
+ 'nullable',
+ 'required_without:status',
+ 'array',
+ 'max:'.(int) config_cache('pixelfed.max_album_length'),
+ function (string $attribute, mixed $value, Closure $fail) {
+ Media::whereProfileId($this->user()->profile_id)
+ ->where(function ($query) {
+ return $query->whereNull('status_id')
+ ->orWhere('status_id', '=', $this->route('id'));
+ })
+ ->findOrFail($value);
+ },
],
'location' => 'sometimes|nullable',
'location.id' => 'sometimes|integer|min:1|max:128769',
diff --git a/app/Jobs/AvatarPipeline/AvatarOptimize.php b/app/Jobs/AvatarPipeline/AvatarOptimize.php
index 4464dff4e..8b50d8330 100644
--- a/app/Jobs/AvatarPipeline/AvatarOptimize.php
+++ b/app/Jobs/AvatarPipeline/AvatarOptimize.php
@@ -2,9 +2,9 @@
namespace App\Jobs\AvatarPipeline;
-use Cache;
use App\Avatar;
use App\Profile;
+use Cache;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -17,88 +17,88 @@ use Storage;
class AvatarOptimize implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $profile;
- protected $current;
+ protected $profile;
- /**
- * Delete the job if its models no longer exist.
- *
- * @var bool
- */
- public $deleteWhenMissingModels = true;
+ protected $current;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Profile $profile, $current)
- {
- $this->profile = $profile;
- $this->current = $current;
- }
+ /**
+ * Delete the job if its models no longer exist.
+ *
+ * @var bool
+ */
+ public $deleteWhenMissingModels = true;
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $avatar = $this->profile->avatar;
- $file = storage_path("app/$avatar->media_path");
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Profile $profile, $current)
+ {
+ $this->profile = $profile;
+ $this->current = $current;
+ }
- try {
- $img = Intervention::make($file)->orientate();
- $img->fit(200, 200, function ($constraint) {
- $constraint->upsize();
- });
- $quality = config_cache('pixelfed.image_quality');
- $img->save($file, $quality);
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $avatar = $this->profile->avatar;
+ $file = storage_path("app/$avatar->media_path");
- $avatar = Avatar::whereProfileId($this->profile->id)->firstOrFail();
- $avatar->change_count = ++$avatar->change_count;
- $avatar->last_processed_at = Carbon::now();
- $avatar->save();
- Cache::forget('avatar:' . $avatar->profile_id);
- $this->deleteOldAvatar($avatar->media_path, $this->current);
+ try {
+ $img = Intervention::make($file)->orientate();
+ $img->fit(200, 200, function ($constraint) {
+ $constraint->upsize();
+ });
+ $quality = config_cache('pixelfed.image_quality');
+ $img->save($file, $quality);
- if(config_cache('pixelfed.cloud_storage') && config('instance.avatar.local_to_cloud')) {
- $this->uploadToCloud($avatar);
- } else {
- $avatar->cdn_url = null;
- $avatar->save();
- }
- } catch (Exception $e) {
- }
- }
+ $avatar = Avatar::whereProfileId($this->profile->id)->firstOrFail();
+ $avatar->change_count = ++$avatar->change_count;
+ $avatar->last_processed_at = Carbon::now();
+ $avatar->save();
+ Cache::forget('avatar:'.$avatar->profile_id);
+ $this->deleteOldAvatar($avatar->media_path, $this->current);
- protected function deleteOldAvatar($new, $current)
- {
- if ( storage_path('app/'.$new) == $current ||
- Str::endsWith($current, 'avatars/default.png') ||
- Str::endsWith($current, 'avatars/default.jpg'))
- {
- return;
- }
- if (is_file($current)) {
- @unlink($current);
- }
- }
+ if ((bool) config_cache('pixelfed.cloud_storage') && (bool) config_cache('instance.avatar.local_to_cloud')) {
+ $this->uploadToCloud($avatar);
+ } else {
+ $avatar->cdn_url = null;
+ $avatar->save();
+ }
+ } catch (Exception $e) {
+ }
+ }
- protected function uploadToCloud($avatar)
- {
- $base = 'cache/avatars/' . $avatar->profile_id;
- $disk = Storage::disk(config('filesystems.cloud'));
- $disk->deleteDirectory($base);
- $path = $base . '/' . 'avatar_' . strtolower(Str::random(random_int(3,6))) . $avatar->change_count . '.' . pathinfo($avatar->media_path, PATHINFO_EXTENSION);
- $url = $disk->put($path, Storage::get($avatar->media_path));
- $avatar->media_path = $path;
- $avatar->cdn_url = $disk->url($path);
- $avatar->save();
- Storage::delete($avatar->media_path);
- Cache::forget('avatar:' . $avatar->profile_id);
- }
+ protected function deleteOldAvatar($new, $current)
+ {
+ if (storage_path('app/'.$new) == $current ||
+ Str::endsWith($current, 'avatars/default.png') ||
+ Str::endsWith($current, 'avatars/default.jpg')) {
+ return;
+ }
+ if (is_file($current)) {
+ @unlink($current);
+ }
+ }
+
+ protected function uploadToCloud($avatar)
+ {
+ $base = 'cache/avatars/'.$avatar->profile_id;
+ $disk = Storage::disk(config('filesystems.cloud'));
+ $disk->deleteDirectory($base);
+ $path = $base.'/'.'avatar_'.strtolower(Str::random(random_int(3, 6))).$avatar->change_count.'.'.pathinfo($avatar->media_path, PATHINFO_EXTENSION);
+ $url = $disk->put($path, Storage::get($avatar->media_path));
+ $avatar->media_path = $path;
+ $avatar->cdn_url = $disk->url($path);
+ $avatar->save();
+ Storage::delete($avatar->media_path);
+ Cache::forget('avatar:'.$avatar->profile_id);
+ }
}
diff --git a/app/Jobs/AvatarPipeline/RemoteAvatarFetch.php b/app/Jobs/AvatarPipeline/RemoteAvatarFetch.php
index 4e4a1b2ec..c2a2b2a16 100644
--- a/app/Jobs/AvatarPipeline/RemoteAvatarFetch.php
+++ b/app/Jobs/AvatarPipeline/RemoteAvatarFetch.php
@@ -4,112 +4,107 @@ namespace App\Jobs\AvatarPipeline;
use App\Avatar;
use App\Profile;
+use App\Services\MediaStorageService;
+use App\Util\ActivityPub\Helpers;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use App\Util\ActivityPub\Helpers;
-use Illuminate\Support\Str;
-use Zttp\Zttp;
-use App\Http\Controllers\AvatarController;
-use Storage;
-use Log;
-use Illuminate\Http\File;
-use App\Services\MediaStorageService;
-use App\Services\ActivityPubFetchService;
class RemoteAvatarFetch implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $profile;
+ protected $profile;
- /**
- * Delete the job if its models no longer exist.
- *
- * @var bool
- */
- public $deleteWhenMissingModels = true;
+ /**
+ * Delete the job if its models no longer exist.
+ *
+ * @var bool
+ */
+ public $deleteWhenMissingModels = true;
- /**
- * The number of times the job may be attempted.
- *
- * @var int
- */
- public $tries = 1;
- public $timeout = 300;
- public $maxExceptions = 1;
+ /**
+ * The number of times the job may be attempted.
+ *
+ * @var int
+ */
+ public $tries = 1;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Profile $profile)
- {
- $this->profile = $profile;
- }
+ public $timeout = 300;
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $profile = $this->profile;
+ public $maxExceptions = 1;
- if(boolval(config_cache('pixelfed.cloud_storage')) == false && boolval(config_cache('federation.avatars.store_local')) == false) {
- return 1;
- }
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Profile $profile)
+ {
+ $this->profile = $profile;
+ }
- if($profile->domain == null || $profile->private_key) {
- return 1;
- }
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $profile = $this->profile;
- $avatar = Avatar::whereProfileId($profile->id)->first();
+ if ((bool) config_cache('pixelfed.cloud_storage') == false && (bool) config_cache('federation.avatars.store_local') == false) {
+ return 1;
+ }
- if(!$avatar) {
- $avatar = new Avatar;
- $avatar->profile_id = $profile->id;
- $avatar->save();
- }
+ if ($profile->domain == null || $profile->private_key) {
+ return 1;
+ }
- if($avatar->media_path == null && $avatar->remote_url == null) {
- $avatar->media_path = 'public/avatars/default.jpg';
- $avatar->is_remote = true;
- $avatar->save();
- }
+ $avatar = Avatar::whereProfileId($profile->id)->first();
- $person = Helpers::fetchFromUrl($profile->remote_url);
+ if (! $avatar) {
+ $avatar = new Avatar;
+ $avatar->profile_id = $profile->id;
+ $avatar->save();
+ }
- if(!$person || !isset($person['@context'])) {
- return 1;
- }
+ if ($avatar->media_path == null && $avatar->remote_url == null) {
+ $avatar->media_path = 'public/avatars/default.jpg';
+ $avatar->is_remote = true;
+ $avatar->save();
+ }
- if( !isset($person['icon']) ||
- !isset($person['icon']['type']) ||
- !isset($person['icon']['url'])
- ) {
- return 1;
- }
+ $person = Helpers::fetchFromUrl($profile->remote_url);
- if($person['icon']['type'] !== 'Image') {
- return 1;
- }
+ if (! $person || ! isset($person['@context'])) {
+ return 1;
+ }
- if(!Helpers::validateUrl($person['icon']['url'])) {
- return 1;
- }
+ if (! isset($person['icon']) ||
+ ! isset($person['icon']['type']) ||
+ ! isset($person['icon']['url'])
+ ) {
+ return 1;
+ }
- $icon = $person['icon'];
+ if ($person['icon']['type'] !== 'Image') {
+ return 1;
+ }
- $avatar->remote_url = $icon['url'];
- $avatar->save();
+ if (! Helpers::validateUrl($person['icon']['url'])) {
+ return 1;
+ }
- MediaStorageService::avatar($avatar, boolval(config_cache('pixelfed.cloud_storage')) == false, true);
+ $icon = $person['icon'];
- return 1;
- }
+ $avatar->remote_url = $icon['url'];
+ $avatar->save();
+
+ MediaStorageService::avatar($avatar, (bool) config_cache('pixelfed.cloud_storage') == false, true);
+
+ return 1;
+ }
}
diff --git a/app/Jobs/AvatarPipeline/RemoteAvatarFetchFromUrl.php b/app/Jobs/AvatarPipeline/RemoteAvatarFetchFromUrl.php
index c8c6820e4..f8a63c5bd 100644
--- a/app/Jobs/AvatarPipeline/RemoteAvatarFetchFromUrl.php
+++ b/app/Jobs/AvatarPipeline/RemoteAvatarFetchFromUrl.php
@@ -4,93 +4,88 @@ namespace App\Jobs\AvatarPipeline;
use App\Avatar;
use App\Profile;
+use App\Services\AccountService;
+use App\Services\MediaStorageService;
+use Cache;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use App\Util\ActivityPub\Helpers;
-use Illuminate\Support\Str;
-use Zttp\Zttp;
-use App\Http\Controllers\AvatarController;
-use Cache;
-use Storage;
-use Log;
-use Illuminate\Http\File;
-use App\Services\AccountService;
-use App\Services\MediaStorageService;
-use App\Services\ActivityPubFetchService;
class RemoteAvatarFetchFromUrl implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $profile;
- protected $url;
+ protected $profile;
- /**
- * Delete the job if its models no longer exist.
- *
- * @var bool
- */
- public $deleteWhenMissingModels = true;
+ protected $url;
- /**
- * The number of times the job may be attempted.
- *
- * @var int
- */
- public $tries = 1;
- public $timeout = 300;
- public $maxExceptions = 1;
+ /**
+ * Delete the job if its models no longer exist.
+ *
+ * @var bool
+ */
+ public $deleteWhenMissingModels = true;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Profile $profile, $url)
- {
- $this->profile = $profile;
- $this->url = $url;
- }
+ /**
+ * The number of times the job may be attempted.
+ *
+ * @var int
+ */
+ public $tries = 1;
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $profile = $this->profile;
+ public $timeout = 300;
- Cache::forget('avatar:' . $profile->id);
- AccountService::del($profile->id);
+ public $maxExceptions = 1;
- if(boolval(config_cache('pixelfed.cloud_storage')) == false && boolval(config_cache('federation.avatars.store_local')) == false) {
- return 1;
- }
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Profile $profile, $url)
+ {
+ $this->profile = $profile;
+ $this->url = $url;
+ }
- if($profile->domain == null || $profile->private_key) {
- return 1;
- }
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $profile = $this->profile;
- $avatar = Avatar::whereProfileId($profile->id)->first();
+ Cache::forget('avatar:'.$profile->id);
+ AccountService::del($profile->id);
- if(!$avatar) {
- $avatar = new Avatar;
- $avatar->profile_id = $profile->id;
- $avatar->is_remote = true;
- $avatar->remote_url = $this->url;
- $avatar->save();
- } else {
- $avatar->remote_url = $this->url;
- $avatar->is_remote = true;
- $avatar->save();
- }
+ if ((bool) config_cache('pixelfed.cloud_storage') == false && (bool) config_cache('federation.avatars.store_local') == false) {
+ return 1;
+ }
- MediaStorageService::avatar($avatar, boolval(config_cache('pixelfed.cloud_storage')) == false, true);
+ if ($profile->domain == null || $profile->private_key) {
+ return 1;
+ }
- return 1;
- }
+ $avatar = Avatar::whereProfileId($profile->id)->first();
+
+ if (! $avatar) {
+ $avatar = new Avatar;
+ $avatar->profile_id = $profile->id;
+ $avatar->is_remote = true;
+ $avatar->remote_url = $this->url;
+ $avatar->save();
+ } else {
+ $avatar->remote_url = $this->url;
+ $avatar->is_remote = true;
+ $avatar->save();
+ }
+
+ MediaStorageService::avatar($avatar, (bool) config_cache('pixelfed.cloud_storage') == false, true);
+
+ return 1;
+ }
}
diff --git a/app/Jobs/ImageOptimizePipeline/ImageOptimize.php b/app/Jobs/ImageOptimizePipeline/ImageOptimize.php
index 0448ade6a..e2d558143 100644
--- a/app/Jobs/ImageOptimizePipeline/ImageOptimize.php
+++ b/app/Jobs/ImageOptimizePipeline/ImageOptimize.php
@@ -45,7 +45,7 @@ class ImageOptimize implements ShouldQueue
return;
}
- if(config('pixelfed.optimize_image') == false) {
+ if((bool) config_cache('pixelfed.optimize_image') == false) {
ImageThumbnail::dispatch($media)->onQueue('mmo');
return;
} else {
diff --git a/app/Jobs/ImageOptimizePipeline/ImageResize.php b/app/Jobs/ImageOptimizePipeline/ImageResize.php
index c1b4ea7f0..2aa51a532 100644
--- a/app/Jobs/ImageOptimizePipeline/ImageResize.php
+++ b/app/Jobs/ImageOptimizePipeline/ImageResize.php
@@ -51,7 +51,7 @@ class ImageResize implements ShouldQueue
return;
}
- if(!config('pixelfed.optimize_image')) {
+ if((bool) config_cache('pixelfed.optimize_image') === false) {
ImageThumbnail::dispatch($media)->onQueue('mmo');
return;
}
diff --git a/app/Jobs/ImageOptimizePipeline/ImageUpdate.php b/app/Jobs/ImageOptimizePipeline/ImageUpdate.php
index 550448699..9012529f2 100644
--- a/app/Jobs/ImageOptimizePipeline/ImageUpdate.php
+++ b/app/Jobs/ImageOptimizePipeline/ImageUpdate.php
@@ -61,7 +61,7 @@ class ImageUpdate implements ShouldQueue
return;
}
- if(config('pixelfed.optimize_image')) {
+ if((bool) config_cache('pixelfed.optimize_image')) {
if (in_array($media->mime, $this->protectedMimes) == true) {
ImageOptimizer::optimize($thumb);
if(!$media->skip_optimize) {
diff --git a/app/Jobs/MediaPipeline/MediaDeletePipeline.php b/app/Jobs/MediaPipeline/MediaDeletePipeline.php
index 55df84948..df16a42d5 100644
--- a/app/Jobs/MediaPipeline/MediaDeletePipeline.php
+++ b/app/Jobs/MediaPipeline/MediaDeletePipeline.php
@@ -3,27 +3,30 @@
namespace App\Jobs\MediaPipeline;
use App\Media;
+use App\Services\Media\MediaHlsService;
use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Redis;
-use Illuminate\Support\Facades\Storage;
-use App\Services\Media\MediaHlsService;
use Illuminate\Queue\Middleware\WithoutOverlapping;
-use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Storage;
-class MediaDeletePipeline implements ShouldQueue, ShouldBeUniqueUntilProcessing
+class MediaDeletePipeline implements ShouldBeUniqueUntilProcessing, ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $media;
+ protected $media;
public $timeout = 300;
+
public $tries = 3;
+
public $maxExceptions = 1;
+
public $failOnTimeout = true;
+
public $deleteWhenMissingModels = true;
/**
@@ -38,7 +41,7 @@ class MediaDeletePipeline implements ShouldQueue, ShouldBeUniqueUntilProcessing
*/
public function uniqueId(): string
{
- return 'media:purge-job:id-' . $this->media->id;
+ return 'media:purge-job:id-'.$this->media->id;
}
/**
@@ -51,58 +54,58 @@ class MediaDeletePipeline implements ShouldQueue, ShouldBeUniqueUntilProcessing
return [(new WithoutOverlapping("media:purge-job:id-{$this->media->id}"))->shared()->dontRelease()];
}
- public function __construct(Media $media)
- {
- $this->media = $media;
- }
+ public function __construct(Media $media)
+ {
+ $this->media = $media;
+ }
- public function handle()
- {
- $media = $this->media;
- $path = $media->media_path;
- $thumb = $media->thumbnail_path;
+ public function handle()
+ {
+ $media = $this->media;
+ $path = $media->media_path;
+ $thumb = $media->thumbnail_path;
- if(!$path) {
- return 1;
- }
+ if (! $path) {
+ return 1;
+ }
- $e = explode('/', $path);
- array_pop($e);
- $i = implode('/', $e);
+ $e = explode('/', $path);
+ array_pop($e);
+ $i = implode('/', $e);
- if(config_cache('pixelfed.cloud_storage') == true) {
- $disk = Storage::disk(config('filesystems.cloud'));
+ if ((bool) config_cache('pixelfed.cloud_storage') == true) {
+ $disk = Storage::disk(config('filesystems.cloud'));
- if($path && $disk->exists($path)) {
- $disk->delete($path);
- }
+ if ($path && $disk->exists($path)) {
+ $disk->delete($path);
+ }
- if($thumb && $disk->exists($thumb)) {
- $disk->delete($thumb);
- }
- }
+ if ($thumb && $disk->exists($thumb)) {
+ $disk->delete($thumb);
+ }
+ }
- $disk = Storage::disk(config('filesystems.local'));
+ $disk = Storage::disk(config('filesystems.local'));
- if($path && $disk->exists($path)) {
- $disk->delete($path);
- }
+ if ($path && $disk->exists($path)) {
+ $disk->delete($path);
+ }
- if($thumb && $disk->exists($thumb)) {
- $disk->delete($thumb);
- }
+ if ($thumb && $disk->exists($thumb)) {
+ $disk->delete($thumb);
+ }
- if($media->hls_path != null) {
+ if ($media->hls_path != null) {
$files = MediaHlsService::allFiles($media);
- if($files && count($files)) {
- foreach($files as $file) {
+ if ($files && count($files)) {
+ foreach ($files as $file) {
$disk->delete($file);
}
}
- }
+ }
- $media->delete();
+ $media->delete();
- return 1;
- }
+ return 1;
+ }
}
diff --git a/app/Jobs/MediaPipeline/MediaFixLocalFilesystemCleanupPipeline.php b/app/Jobs/MediaPipeline/MediaFixLocalFilesystemCleanupPipeline.php
index bbd3851b9..a972f1f86 100644
--- a/app/Jobs/MediaPipeline/MediaFixLocalFilesystemCleanupPipeline.php
+++ b/app/Jobs/MediaPipeline/MediaFixLocalFilesystemCleanupPipeline.php
@@ -8,68 +8,69 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
class MediaFixLocalFilesystemCleanupPipeline implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- public $timeout = 1800;
- public $tries = 5;
- public $maxExceptions = 1;
+ public $timeout = 1800;
- public function handle()
- {
- if(config_cache('pixelfed.cloud_storage') == false) {
- // Only run if cloud storage is enabled
- return;
- }
+ public $tries = 5;
- $disk = Storage::disk('local');
- $cloud = Storage::disk(config('filesystems.cloud'));
+ public $maxExceptions = 1;
- Media::whereNotNull(['status_id', 'cdn_url', 'replicated_at'])
- ->chunk(20, function ($medias) use($disk, $cloud) {
- foreach($medias as $media) {
- if(!str_starts_with($media->media_path, 'public')) {
- continue;
- }
+ public function handle()
+ {
+ if ((bool) config_cache('pixelfed.cloud_storage') == false) {
+ // Only run if cloud storage is enabled
+ return;
+ }
- if($disk->exists($media->media_path) && $cloud->exists($media->media_path)) {
- $disk->delete($media->media_path);
- }
+ $disk = Storage::disk('local');
+ $cloud = Storage::disk(config('filesystems.cloud'));
- if($media->thumbnail_path) {
- if($disk->exists($media->thumbnail_path)) {
- $disk->delete($media->thumbnail_path);
- }
- }
+ Media::whereNotNull(['status_id', 'cdn_url', 'replicated_at'])
+ ->chunk(20, function ($medias) use ($disk, $cloud) {
+ foreach ($medias as $media) {
+ if (! str_starts_with($media->media_path, 'public')) {
+ continue;
+ }
- $paths = explode('/', $media->media_path);
- if(count($paths) === 7) {
- array_pop($paths);
- $baseDir = implode('/', $paths);
+ if ($disk->exists($media->media_path) && $cloud->exists($media->media_path)) {
+ $disk->delete($media->media_path);
+ }
- if(count($disk->allFiles($baseDir)) === 0) {
- $disk->deleteDirectory($baseDir);
+ if ($media->thumbnail_path) {
+ if ($disk->exists($media->thumbnail_path)) {
+ $disk->delete($media->thumbnail_path);
+ }
+ }
- array_pop($paths);
- $baseDir = implode('/', $paths);
+ $paths = explode('/', $media->media_path);
+ if (count($paths) === 7) {
+ array_pop($paths);
+ $baseDir = implode('/', $paths);
- if(count($disk->allFiles($baseDir)) === 0) {
- $disk->deleteDirectory($baseDir);
+ if (count($disk->allFiles($baseDir)) === 0) {
+ $disk->deleteDirectory($baseDir);
- array_pop($paths);
- $baseDir = implode('/', $paths);
+ array_pop($paths);
+ $baseDir = implode('/', $paths);
- if(count($disk->allFiles($baseDir)) === 0) {
- $disk->deleteDirectory($baseDir);
- }
- }
- }
- }
- }
- });
- }
+ if (count($disk->allFiles($baseDir)) === 0) {
+ $disk->deleteDirectory($baseDir);
+
+ array_pop($paths);
+ $baseDir = implode('/', $paths);
+
+ if (count($disk->allFiles($baseDir)) === 0) {
+ $disk->deleteDirectory($baseDir);
+ }
+ }
+ }
+ }
+ }
+ });
+ }
}
diff --git a/app/Jobs/RemoteFollowPipeline/RemoteFollowImportRecent.php b/app/Jobs/RemoteFollowPipeline/RemoteFollowImportRecent.php
index 5b413ecc1..394c2cfb8 100644
--- a/app/Jobs/RemoteFollowPipeline/RemoteFollowImportRecent.php
+++ b/app/Jobs/RemoteFollowPipeline/RemoteFollowImportRecent.php
@@ -17,6 +17,7 @@ use Log;
use Storage;
use Zttp\Zttp;
use App\Util\ActivityPub\Helpers;
+use App\Services\MediaPathService;
class RemoteFollowImportRecent implements ShouldQueue
{
@@ -45,7 +46,6 @@ class RemoteFollowImportRecent implements ShouldQueue
'image/jpg',
'image/jpeg',
'image/png',
- 'image/gif',
];
}
@@ -208,9 +208,7 @@ class RemoteFollowImportRecent implements ShouldQueue
public function importMedia($url, $mime, $status)
{
$user = $this->profile;
- $monthHash = hash('sha1', date('Y').date('m'));
- $userHash = hash('sha1', $user->id.(string) $user->created_at);
- $storagePath = "public/m/{$monthHash}/{$userHash}";
+ $storagePath = MediaPathService::get($user, 2);
try {
$info = pathinfo($url);
diff --git a/app/Jobs/SharePipeline/SharePipeline.php b/app/Jobs/SharePipeline/SharePipeline.php
index 4eca4e1ab..734c44231 100644
--- a/app/Jobs/SharePipeline/SharePipeline.php
+++ b/app/Jobs/SharePipeline/SharePipeline.php
@@ -2,9 +2,15 @@
namespace App\Jobs\SharePipeline;
-use Cache, Log;
-use Illuminate\Support\Facades\Redis;
-use App\{Status, Notification};
+use App\Jobs\HomeFeedPipeline\FeedInsertPipeline;
+use App\Notification;
+use App\Services\ReblogService;
+use App\Services\StatusService;
+use App\Status;
+use App\Transformer\ActivityPub\Verb\Announce;
+use App\Util\ActivityPub\HttpSignature;
+use GuzzleHttp\Client;
+use GuzzleHttp\Pool;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -12,141 +18,136 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
-use App\Transformer\ActivityPub\Verb\Announce;
-use GuzzleHttp\{Pool, Client, Promise};
-use App\Util\ActivityPub\HttpSignature;
-use App\Services\ReblogService;
-use App\Services\StatusService;
-use App\Jobs\HomeFeedPipeline\FeedInsertPipeline;
class SharePipeline implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $status;
+ protected $status;
- /**
- * Delete the job if its models no longer exist.
- *
- * @var bool
- */
- public $deleteWhenMissingModels = true;
+ /**
+ * Delete the job if its models no longer exist.
+ *
+ * @var bool
+ */
+ public $deleteWhenMissingModels = true;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Status $status)
- {
- $this->status = $status;
- }
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Status $status)
+ {
+ $this->status = $status;
+ }
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $status = $this->status;
- $parent = Status::find($this->status->reblog_of_id);
- if(!$parent) {
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $status = $this->status;
+ $parent = Status::find($this->status->reblog_of_id);
+ if (! $parent) {
return;
}
- $actor = $status->profile;
- $target = $parent->profile;
+ $actor = $status->profile;
+ $target = $parent->profile;
- if ($status->uri !== null) {
- // Ignore notifications to remote statuses
- return;
- }
+ if ($status->uri !== null) {
+ // Ignore notifications to remote statuses
+ return;
+ }
- if($target->id === $status->profile_id) {
- $this->remoteAnnounceDeliver();
- return true;
- }
+ if ($target->id === $status->profile_id) {
+ $this->remoteAnnounceDeliver();
- ReblogService::addPostReblog($parent->profile_id, $status->id);
+ return true;
+ }
- $parent->reblogs_count = $parent->reblogs_count + 1;
- $parent->save();
- StatusService::del($parent->id);
+ ReblogService::addPostReblog($parent->profile_id, $status->id);
- Notification::firstOrCreate(
- [
- 'profile_id' => $target->id,
- 'actor_id' => $actor->id,
- 'action' => 'share',
- 'item_type' => 'App\Status',
- 'item_id' => $status->reblog_of_id ?? $status->id,
- ]
- );
+ $parent->reblogs_count = $parent->reblogs_count + 1;
+ $parent->save();
+ StatusService::del($parent->id);
- FeedInsertPipeline::dispatch($status->id, $status->profile_id)->onQueue('feed');
+ Notification::firstOrCreate(
+ [
+ 'profile_id' => $target->id,
+ 'actor_id' => $actor->id,
+ 'action' => 'share',
+ 'item_type' => 'App\Status',
+ 'item_id' => $status->reblog_of_id ?? $status->id,
+ ]
+ );
- return $this->remoteAnnounceDeliver();
- }
+ FeedInsertPipeline::dispatch($status->id, $status->profile_id)->onQueue('feed');
- public function remoteAnnounceDeliver()
- {
- if(config('app.env') !== 'production' || config_cache('federation.activitypub.enabled') == false) {
- return true;
- }
- $status = $this->status;
- $profile = $status->profile;
+ return $this->remoteAnnounceDeliver();
+ }
- $fractal = new Fractal\Manager();
- $fractal->setSerializer(new ArraySerializer());
- $resource = new Fractal\Resource\Item($status, new Announce());
- $activity = $fractal->createData($resource)->toArray();
+ public function remoteAnnounceDeliver()
+ {
+ if (config('app.env') !== 'production' || (bool) config_cache('federation.activitypub.enabled') == false) {
+ return true;
+ }
+ $status = $this->status;
+ $profile = $status->profile;
- $audience = $status->profile->getAudienceInbox();
+ $fractal = new Fractal\Manager();
+ $fractal->setSerializer(new ArraySerializer());
+ $resource = new Fractal\Resource\Item($status, new Announce());
+ $activity = $fractal->createData($resource)->toArray();
- if(empty($audience) || $status->scope != 'public') {
- // Return on profiles with no remote followers
- return;
- }
+ $audience = $status->profile->getAudienceInbox();
- $payload = json_encode($activity);
+ if (empty($audience) || $status->scope != 'public') {
+ // Return on profiles with no remote followers
+ return;
+ }
- $client = new Client([
- 'timeout' => config('federation.activitypub.delivery.timeout')
- ]);
+ $payload = json_encode($activity);
- $version = config('pixelfed.version');
- $appUrl = config('app.url');
- $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
+ $client = new Client([
+ 'timeout' => config('federation.activitypub.delivery.timeout'),
+ ]);
- $requests = function($audience) use ($client, $activity, $profile, $payload, $userAgent) {
- foreach($audience as $url) {
- $headers = HttpSignature::sign($profile, $url, $activity, [
- 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
- 'User-Agent' => $userAgent,
- ]);
- yield function() use ($client, $url, $headers, $payload) {
- return $client->postAsync($url, [
- 'curl' => [
- CURLOPT_HTTPHEADER => $headers,
- CURLOPT_POSTFIELDS => $payload,
- CURLOPT_HEADER => true
- ]
- ]);
- };
- }
- };
+ $version = config('pixelfed.version');
+ $appUrl = config('app.url');
+ $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
- $pool = new Pool($client, $requests($audience), [
- 'concurrency' => config('federation.activitypub.delivery.concurrency'),
- 'fulfilled' => function ($response, $index) {
- },
- 'rejected' => function ($reason, $index) {
- }
- ]);
+ $requests = function ($audience) use ($client, $activity, $profile, $payload, $userAgent) {
+ foreach ($audience as $url) {
+ $headers = HttpSignature::sign($profile, $url, $activity, [
+ 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+ 'User-Agent' => $userAgent,
+ ]);
+ yield function () use ($client, $url, $headers, $payload) {
+ return $client->postAsync($url, [
+ 'curl' => [
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POSTFIELDS => $payload,
+ CURLOPT_HEADER => true,
+ ],
+ ]);
+ };
+ }
+ };
- $promise = $pool->promise();
+ $pool = new Pool($client, $requests($audience), [
+ 'concurrency' => config('federation.activitypub.delivery.concurrency'),
+ 'fulfilled' => function ($response, $index) {
+ },
+ 'rejected' => function ($reason, $index) {
+ },
+ ]);
- $promise->wait();
+ $promise = $pool->promise();
- }
+ $promise->wait();
+
+ }
}
diff --git a/app/Jobs/SharePipeline/UndoSharePipeline.php b/app/Jobs/SharePipeline/UndoSharePipeline.php
index 1435688d9..af3239953 100644
--- a/app/Jobs/SharePipeline/UndoSharePipeline.php
+++ b/app/Jobs/SharePipeline/UndoSharePipeline.php
@@ -2,9 +2,15 @@
namespace App\Jobs\SharePipeline;
-use Cache, Log;
-use Illuminate\Support\Facades\Redis;
-use App\{Status, Notification};
+use App\Jobs\HomeFeedPipeline\FeedRemovePipeline;
+use App\Notification;
+use App\Services\ReblogService;
+use App\Services\StatusService;
+use App\Status;
+use App\Transformer\ActivityPub\Verb\UndoAnnounce;
+use App\Util\ActivityPub\HttpSignature;
+use GuzzleHttp\Client;
+use GuzzleHttp\Pool;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -12,128 +18,125 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
-use App\Transformer\ActivityPub\Verb\UndoAnnounce;
-use GuzzleHttp\{Pool, Client, Promise};
-use App\Util\ActivityPub\HttpSignature;
-use App\Services\ReblogService;
-use App\Services\StatusService;
-use App\Jobs\HomeFeedPipeline\FeedRemovePipeline;
class UndoSharePipeline implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $status;
- public $deleteWhenMissingModels = true;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- public function __construct(Status $status)
- {
- $this->status = $status;
- }
+ protected $status;
- public function handle()
- {
- $status = $this->status;
- $actor = $status->profile;
- $parent = Status::find($status->reblog_of_id);
+ public $deleteWhenMissingModels = true;
- FeedRemovePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed');
+ public function __construct(Status $status)
+ {
+ $this->status = $status;
+ }
- if($parent) {
- $target = $parent->profile_id;
- ReblogService::removePostReblog($parent->profile_id, $status->id);
+ public function handle()
+ {
+ $status = $this->status;
+ $actor = $status->profile;
+ $parent = Status::find($status->reblog_of_id);
- if($parent->reblogs_count > 0) {
- $parent->reblogs_count = $parent->reblogs_count - 1;
- $parent->save();
- StatusService::del($parent->id);
- }
+ FeedRemovePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed');
- $notification = Notification::whereProfileId($target)
- ->whereActorId($status->profile_id)
- ->whereAction('share')
- ->whereItemId($status->reblog_of_id)
- ->whereItemType('App\Status')
- ->first();
+ if ($parent) {
+ $target = $parent->profile_id;
+ ReblogService::removePostReblog($parent->profile_id, $status->id);
- if($notification) {
- $notification->forceDelete();
- }
- }
+ if ($parent->reblogs_count > 0) {
+ $parent->reblogs_count = $parent->reblogs_count - 1;
+ $parent->save();
+ StatusService::del($parent->id);
+ }
- if ($status->uri != null) {
- return;
- }
+ $notification = Notification::whereProfileId($target)
+ ->whereActorId($status->profile_id)
+ ->whereAction('share')
+ ->whereItemId($status->reblog_of_id)
+ ->whereItemType('App\Status')
+ ->first();
- if(config('app.env') !== 'production' || config_cache('federation.activitypub.enabled') == false) {
- return $status->delete();
- } else {
- return $this->remoteAnnounceDeliver();
- }
- }
+ if ($notification) {
+ $notification->forceDelete();
+ }
+ }
- public function remoteAnnounceDeliver()
- {
- if(config('app.env') !== 'production' || config_cache('federation.activitypub.enabled') == false) {
+ if ($status->uri != null) {
+ return;
+ }
+
+ if (config('app.env') !== 'production' || (bool) config_cache('federation.activitypub.enabled') == false) {
+ return $status->delete();
+ } else {
+ return $this->remoteAnnounceDeliver();
+ }
+ }
+
+ public function remoteAnnounceDeliver()
+ {
+ if (config('app.env') !== 'production' || (bool) config_cache('federation.activitypub.enabled') == false) {
$status->delete();
- return 1;
- }
- $status = $this->status;
- $profile = $status->profile;
+ return 1;
+ }
- $fractal = new Fractal\Manager();
- $fractal->setSerializer(new ArraySerializer());
- $resource = new Fractal\Resource\Item($status, new UndoAnnounce());
- $activity = $fractal->createData($resource)->toArray();
+ $status = $this->status;
+ $profile = $status->profile;
- $audience = $status->profile->getAudienceInbox();
+ $fractal = new Fractal\Manager();
+ $fractal->setSerializer(new ArraySerializer());
+ $resource = new Fractal\Resource\Item($status, new UndoAnnounce());
+ $activity = $fractal->createData($resource)->toArray();
- if(empty($audience) || $status->scope != 'public') {
- return 1;
- }
+ $audience = $status->profile->getAudienceInbox();
- $payload = json_encode($activity);
+ if (empty($audience) || $status->scope != 'public') {
+ return 1;
+ }
- $client = new Client([
- 'timeout' => config('federation.activitypub.delivery.timeout')
- ]);
+ $payload = json_encode($activity);
- $version = config('pixelfed.version');
- $appUrl = config('app.url');
- $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
+ $client = new Client([
+ 'timeout' => config('federation.activitypub.delivery.timeout'),
+ ]);
- $requests = function($audience) use ($client, $activity, $profile, $payload, $userAgent) {
- foreach($audience as $url) {
- $headers = HttpSignature::sign($profile, $url, $activity, [
- 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
- 'User-Agent' => $userAgent,
- ]);
- yield function() use ($client, $url, $headers, $payload) {
- return $client->postAsync($url, [
- 'curl' => [
- CURLOPT_HTTPHEADER => $headers,
- CURLOPT_POSTFIELDS => $payload,
- CURLOPT_HEADER => true
- ]
- ]);
- };
- }
- };
+ $version = config('pixelfed.version');
+ $appUrl = config('app.url');
+ $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
- $pool = new Pool($client, $requests($audience), [
- 'concurrency' => config('federation.activitypub.delivery.concurrency'),
- 'fulfilled' => function ($response, $index) {
- },
- 'rejected' => function ($reason, $index) {
- }
- ]);
+ $requests = function ($audience) use ($client, $activity, $profile, $payload, $userAgent) {
+ foreach ($audience as $url) {
+ $headers = HttpSignature::sign($profile, $url, $activity, [
+ 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+ 'User-Agent' => $userAgent,
+ ]);
+ yield function () use ($client, $url, $headers, $payload) {
+ return $client->postAsync($url, [
+ 'curl' => [
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POSTFIELDS => $payload,
+ CURLOPT_HEADER => true,
+ ],
+ ]);
+ };
+ }
+ };
- $promise = $pool->promise();
+ $pool = new Pool($client, $requests($audience), [
+ 'concurrency' => config('federation.activitypub.delivery.concurrency'),
+ 'fulfilled' => function ($response, $index) {
+ },
+ 'rejected' => function ($reason, $index) {
+ },
+ ]);
- $promise->wait();
+ $promise = $pool->promise();
- $status->delete();
+ $promise->wait();
- return 1;
- }
+ $status->delete();
+
+ return 1;
+ }
}
diff --git a/app/Jobs/StatusPipeline/StatusDelete.php b/app/Jobs/StatusPipeline/StatusDelete.php
index dbbfad5ac..d85ebdc4a 100644
--- a/app/Jobs/StatusPipeline/StatusDelete.php
+++ b/app/Jobs/StatusPipeline/StatusDelete.php
@@ -2,126 +2,122 @@
namespace App\Jobs\StatusPipeline;
-use DB, Cache, Storage;
-use App\{
- AccountInterstitial,
- Bookmark,
- CollectionItem,
- DirectMessage,
- Like,
- Media,
- MediaTag,
- Mention,
- Notification,
- Report,
- Status,
- StatusArchived,
- StatusHashtag,
- StatusView
-};
+use App\AccountInterstitial;
+use App\Bookmark;
+use App\CollectionItem;
+use App\DirectMessage;
+use App\Jobs\MediaPipeline\MediaDeletePipeline;
+use App\Like;
+use App\Media;
+use App\MediaTag;
+use App\Mention;
+use App\Notification;
+use App\Report;
+use App\Services\CollectionService;
+use App\Services\NotificationService;
+use App\Services\StatusService;
+use App\Status;
+use App\StatusArchived;
+use App\StatusHashtag;
+use App\StatusView;
+use App\Transformer\ActivityPub\Verb\DeleteNote;
+use App\Util\ActivityPub\HttpSignature;
+use Cache;
+use GuzzleHttp\Client;
+use GuzzleHttp\Pool;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use League\Fractal;
-use Illuminate\Support\Str;
use League\Fractal\Serializer\ArraySerializer;
-use App\Transformer\ActivityPub\Verb\DeleteNote;
-use App\Util\ActivityPub\Helpers;
-use GuzzleHttp\Pool;
-use GuzzleHttp\Client;
-use GuzzleHttp\Promise;
-use App\Util\ActivityPub\HttpSignature;
-use App\Services\CollectionService;
-use App\Services\StatusService;
-use App\Services\NotificationService;
-use App\Jobs\MediaPipeline\MediaDeletePipeline;
class StatusDelete implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $status;
+ protected $status;
- /**
- * Delete the job if its models no longer exist.
- *
- * @var bool
- */
- public $deleteWhenMissingModels = true;
+ /**
+ * Delete the job if its models no longer exist.
+ *
+ * @var bool
+ */
+ public $deleteWhenMissingModels = true;
public $timeout = 900;
+
public $tries = 2;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Status $status)
- {
- $this->status = $status;
- }
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Status $status)
+ {
+ $this->status = $status;
+ }
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $status = $this->status;
- $profile = $this->status->profile;
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $status = $this->status;
+ $profile = $this->status->profile;
- StatusService::del($status->id, true);
- if($profile) {
- if(in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])) {
- $profile->status_count = $profile->status_count - 1;
- $profile->save();
- }
- }
+ StatusService::del($status->id, true);
+ if ($profile) {
+ if (in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])) {
+ $profile->status_count = $profile->status_count - 1;
+ $profile->save();
+ }
+ }
- Cache::forget('pf:atom:user-feed:by-id:' . $status->profile_id);
+ Cache::forget('pf:atom:user-feed:by-id:'.$status->profile_id);
- if(config_cache('federation.activitypub.enabled') == true) {
- return $this->fanoutDelete($status);
- } else {
- return $this->unlinkRemoveMedia($status);
- }
- }
+ if ((bool) config_cache('federation.activitypub.enabled') == true) {
+ return $this->fanoutDelete($status);
+ } else {
+ return $this->unlinkRemoveMedia($status);
+ }
+ }
- public function unlinkRemoveMedia($status)
- {
+ public function unlinkRemoveMedia($status)
+ {
Media::whereStatusId($status->id)
- ->get()
- ->each(function($media) {
- MediaDeletePipeline::dispatch($media);
- });
+ ->get()
+ ->each(function ($media) {
+ MediaDeletePipeline::dispatch($media);
+ });
- if($status->in_reply_to_id) {
- $parent = Status::findOrFail($status->in_reply_to_id);
- --$parent->reply_count;
- $parent->save();
- StatusService::del($parent->id);
- }
+ if ($status->in_reply_to_id) {
+ $parent = Status::findOrFail($status->in_reply_to_id);
+ $parent->reply_count--;
+ $parent->save();
+ StatusService::del($parent->id);
+ }
Bookmark::whereStatusId($status->id)->delete();
CollectionItem::whereObjectType('App\Status')
->whereObjectId($status->id)
->get()
- ->each(function($col) {
+ ->each(function ($col) {
CollectionService::removeItem($col->collection_id, $col->object_id);
$col->delete();
- });
+ });
$dms = DirectMessage::whereStatusId($status->id)->get();
- foreach($dms as $dm) {
+ foreach ($dms as $dm) {
$not = Notification::whereItemType('App\DirectMessage')
->whereItemId($dm->id)
->first();
- if($not) {
+ if ($not) {
NotificationService::del($not->profile_id, $not->id);
$not->forceDeleteQuietly();
}
@@ -130,11 +126,11 @@ class StatusDelete implements ShouldQueue
Like::whereStatusId($status->id)->delete();
$mediaTags = MediaTag::where('status_id', $status->id)->get();
- foreach($mediaTags as $mtag) {
+ foreach ($mediaTags as $mtag) {
$not = Notification::whereItemType('App\MediaTag')
->whereItemId($mtag->id)
->first();
- if($not) {
+ if ($not) {
NotificationService::del($not->profile_id, $not->id);
$not->forceDeleteQuietly();
}
@@ -142,85 +138,85 @@ class StatusDelete implements ShouldQueue
}
Mention::whereStatusId($status->id)->forceDelete();
- Notification::whereItemType('App\Status')
- ->whereItemId($status->id)
- ->forceDelete();
+ Notification::whereItemType('App\Status')
+ ->whereItemId($status->id)
+ ->forceDelete();
- Report::whereObjectType('App\Status')
- ->whereObjectId($status->id)
- ->delete();
+ Report::whereObjectType('App\Status')
+ ->whereObjectId($status->id)
+ ->delete();
StatusArchived::whereStatusId($status->id)->delete();
StatusHashtag::whereStatusId($status->id)->delete();
StatusView::whereStatusId($status->id)->delete();
- Status::whereInReplyToId($status->id)->update(['in_reply_to_id' => null]);
+ Status::whereInReplyToId($status->id)->update(['in_reply_to_id' => null]);
- AccountInterstitial::where('item_type', 'App\Status')
- ->where('item_id', $status->id)
- ->delete();
+ AccountInterstitial::where('item_type', 'App\Status')
+ ->where('item_id', $status->id)
+ ->delete();
- $status->delete();
-
- return 1;
- }
-
- public function fanoutDelete($status)
- {
- $profile = $status->profile;
-
- if(!$profile) {
- return;
- }
-
- $audience = $status->profile->getAudienceInbox();
-
- $fractal = new Fractal\Manager();
- $fractal->setSerializer(new ArraySerializer());
- $resource = new Fractal\Resource\Item($status, new DeleteNote());
- $activity = $fractal->createData($resource)->toArray();
-
- $this->unlinkRemoveMedia($status);
-
- $payload = json_encode($activity);
-
- $client = new Client([
- 'timeout' => config('federation.activitypub.delivery.timeout')
- ]);
-
- $version = config('pixelfed.version');
- $appUrl = config('app.url');
- $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
-
- $requests = function($audience) use ($client, $activity, $profile, $payload, $userAgent) {
- foreach($audience as $url) {
- $headers = HttpSignature::sign($profile, $url, $activity, [
- 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
- 'User-Agent' => $userAgent,
- ]);
- yield function() use ($client, $url, $headers, $payload) {
- return $client->postAsync($url, [
- 'curl' => [
- CURLOPT_HTTPHEADER => $headers,
- CURLOPT_POSTFIELDS => $payload,
- CURLOPT_HEADER => true
- ]
- ]);
- };
- }
- };
-
- $pool = new Pool($client, $requests($audience), [
- 'concurrency' => config('federation.activitypub.delivery.concurrency'),
- 'fulfilled' => function ($response, $index) {
- },
- 'rejected' => function ($reason, $index) {
- }
- ]);
-
- $promise = $pool->promise();
-
- $promise->wait();
+ $status->delete();
return 1;
- }
+ }
+
+ public function fanoutDelete($status)
+ {
+ $profile = $status->profile;
+
+ if (! $profile) {
+ return;
+ }
+
+ $audience = $status->profile->getAudienceInbox();
+
+ $fractal = new Fractal\Manager();
+ $fractal->setSerializer(new ArraySerializer());
+ $resource = new Fractal\Resource\Item($status, new DeleteNote());
+ $activity = $fractal->createData($resource)->toArray();
+
+ $this->unlinkRemoveMedia($status);
+
+ $payload = json_encode($activity);
+
+ $client = new Client([
+ 'timeout' => config('federation.activitypub.delivery.timeout'),
+ ]);
+
+ $version = config('pixelfed.version');
+ $appUrl = config('app.url');
+ $userAgent = "(Pixelfed/{$version}; +{$appUrl})";
+
+ $requests = function ($audience) use ($client, $activity, $profile, $payload, $userAgent) {
+ foreach ($audience as $url) {
+ $headers = HttpSignature::sign($profile, $url, $activity, [
+ 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+ 'User-Agent' => $userAgent,
+ ]);
+ yield function () use ($client, $url, $headers, $payload) {
+ return $client->postAsync($url, [
+ 'curl' => [
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POSTFIELDS => $payload,
+ CURLOPT_HEADER => true,
+ ],
+ ]);
+ };
+ }
+ };
+
+ $pool = new Pool($client, $requests($audience), [
+ 'concurrency' => config('federation.activitypub.delivery.concurrency'),
+ 'fulfilled' => function ($response, $index) {
+ },
+ 'rejected' => function ($reason, $index) {
+ },
+ ]);
+
+ $promise = $pool->promise();
+
+ $promise->wait();
+
+ return 1;
+ }
}
diff --git a/app/Jobs/StatusPipeline/StatusEntityLexer.php b/app/Jobs/StatusPipeline/StatusEntityLexer.php
index 872594a96..4d19c7d8a 100644
--- a/app/Jobs/StatusPipeline/StatusEntityLexer.php
+++ b/app/Jobs/StatusPipeline/StatusEntityLexer.php
@@ -3,12 +3,16 @@
namespace App\Jobs\StatusPipeline;
use App\Hashtag;
+use App\Jobs\HomeFeedPipeline\FeedInsertPipeline;
use App\Jobs\MentionPipeline\MentionPipeline;
use App\Mention;
use App\Profile;
+use App\Services\AdminShadowFilterService;
+use App\Services\PublicTimelineService;
+use App\Services\StatusService;
+use App\Services\UserFilterService;
use App\Status;
use App\StatusHashtag;
-use App\Services\PublicTimelineService;
use App\Util\Lexer\Autolink;
use App\Util\Lexer\Extractor;
use App\Util\Sentiment\Bouncer;
@@ -19,18 +23,15 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use App\Services\StatusService;
-use App\Services\UserFilterService;
-use App\Services\AdminShadowFilterService;
-use App\Jobs\HomeFeedPipeline\FeedInsertPipeline;
-use App\Jobs\HomeFeedPipeline\HashtagInsertFanoutPipeline;
class StatusEntityLexer implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $status;
+
protected $entities;
+
protected $autolink;
/**
@@ -60,12 +61,12 @@ class StatusEntityLexer implements ShouldQueue
$profile = $this->status->profile;
$status = $this->status;
- if(in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])) {
+ if (in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])) {
$profile->status_count = $profile->status_count + 1;
$profile->save();
}
- if($profile->no_autolink == false) {
+ if ($profile->no_autolink == false) {
$this->parseEntities();
}
}
@@ -103,16 +104,16 @@ class StatusEntityLexer implements ShouldQueue
$status = $this->status;
foreach ($tags as $tag) {
- if(mb_strlen($tag) > 124) {
+ if (mb_strlen($tag) > 124) {
continue;
}
DB::transaction(function () use ($status, $tag) {
$slug = str_slug($tag, '-', false);
$hashtag = Hashtag::firstOrCreate([
- 'slug' => $slug
+ 'slug' => $slug,
], [
- 'name' => $tag
+ 'name' => $tag,
]);
StatusHashtag::firstOrCreate(
@@ -136,11 +137,11 @@ class StatusEntityLexer implements ShouldQueue
foreach ($mentions as $mention) {
$mentioned = Profile::whereUsername($mention)->first();
- if (empty($mentioned) || !isset($mentioned->id)) {
+ if (empty($mentioned) || ! isset($mentioned->id)) {
continue;
}
$blocks = UserFilterService::blocks($mentioned->id);
- if($blocks && in_array($status->profile_id, $blocks)) {
+ if ($blocks && in_array($status->profile_id, $blocks)) {
continue;
}
@@ -161,8 +162,8 @@ class StatusEntityLexer implements ShouldQueue
$status = $this->status;
StatusService::refresh($status->id);
- if(config('exp.cached_home_timeline')) {
- if( $status->in_reply_to_id === null &&
+ if (config('exp.cached_home_timeline')) {
+ if ($status->in_reply_to_id === null &&
in_array($status->scope, ['public', 'unlisted', 'private'])
) {
FeedInsertPipeline::dispatch($status->id, $status->profile_id)->onQueue('feed');
@@ -179,28 +180,28 @@ class StatusEntityLexer implements ShouldQueue
'photo:album',
'video',
'video:album',
- 'photo:video:album'
+ 'photo:video:album',
];
- if(config_cache('pixelfed.bouncer.enabled')) {
+ if ((bool) config_cache('pixelfed.bouncer.enabled')) {
Bouncer::get($status);
}
- Cache::forget('pf:atom:user-feed:by-id:' . $status->profile_id);
+ Cache::forget('pf:atom:user-feed:by-id:'.$status->profile_id);
$hideNsfw = config('instance.hide_nsfw_on_public_feeds');
- if( $status->uri == null &&
+ if ($status->uri == null &&
$status->scope == 'public' &&
in_array($status->type, $types) &&
$status->in_reply_to_id === null &&
$status->reblog_of_id === null &&
($hideNsfw ? $status->is_nsfw == false : true)
) {
- if(AdminShadowFilterService::canAddToPublicFeedByProfileId($status->profile_id)) {
+ if (AdminShadowFilterService::canAddToPublicFeedByProfileId($status->profile_id)) {
PublicTimelineService::add($status->id);
}
}
- if(config_cache('federation.activitypub.enabled') == true && config('app.env') == 'production') {
+ if ((bool) config_cache('federation.activitypub.enabled') == true && config('app.env') == 'production') {
StatusActivityPubDeliver::dispatch($status);
}
}
diff --git a/app/Jobs/StatusPipeline/StatusRemoteUpdatePipeline.php b/app/Jobs/StatusPipeline/StatusRemoteUpdatePipeline.php
index 23b8716c1..7ef7a3366 100644
--- a/app/Jobs/StatusPipeline/StatusRemoteUpdatePipeline.php
+++ b/app/Jobs/StatusPipeline/StatusRemoteUpdatePipeline.php
@@ -2,172 +2,171 @@
namespace App\Jobs\StatusPipeline;
+use App\Media;
+use App\Models\StatusEdit;
+use App\ModLog;
+use App\Profile;
+use App\Services\StatusService;
+use App\Status;
use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use App\Media;
-use App\ModLog;
-use App\Profile;
-use App\Status;
-use App\Models\StatusEdit;
-use App\Services\StatusService;
-use Purify;
use Illuminate\Support\Facades\Http;
+use Purify;
class StatusRemoteUpdatePipeline implements ShouldQueue
{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- public $activity;
+ public $activity;
- /**
- * Create a new job instance.
- */
- public function __construct($activity)
- {
- $this->activity = $activity;
- }
+ /**
+ * Create a new job instance.
+ */
+ public function __construct($activity)
+ {
+ $this->activity = $activity;
+ }
- /**
- * Execute the job.
- */
- public function handle(): void
- {
- $activity = $this->activity;
- $status = Status::with('media')->whereObjectUrl($activity['id'])->first();
- if(!$status) {
- return;
- }
- $this->createPreviousEdit($status);
- $this->updateMedia($status, $activity);
- $this->updateImmediateAttributes($status, $activity);
- $this->createEdit($status, $activity);
- }
+ /**
+ * Execute the job.
+ */
+ public function handle(): void
+ {
+ $activity = $this->activity;
+ $status = Status::with('media')->whereObjectUrl($activity['id'])->first();
+ if (! $status) {
+ return;
+ }
+ $this->createPreviousEdit($status);
+ $this->updateMedia($status, $activity);
+ $this->updateImmediateAttributes($status, $activity);
+ $this->createEdit($status, $activity);
+ }
- protected function createPreviousEdit($status)
- {
- if(!$status->edits()->count()) {
- StatusEdit::create([
- 'status_id' => $status->id,
- 'profile_id' => $status->profile_id,
- 'caption' => $status->caption,
- 'spoiler_text' => $status->cw_summary,
- 'is_nsfw' => $status->is_nsfw,
- 'ordered_media_attachment_ids' => $status->media()->orderBy('order')->pluck('id')->toArray(),
- 'created_at' => $status->created_at
- ]);
- }
- }
+ protected function createPreviousEdit($status)
+ {
+ if (! $status->edits()->count()) {
+ StatusEdit::create([
+ 'status_id' => $status->id,
+ 'profile_id' => $status->profile_id,
+ 'caption' => $status->caption,
+ 'spoiler_text' => $status->cw_summary,
+ 'is_nsfw' => $status->is_nsfw,
+ 'ordered_media_attachment_ids' => $status->media()->orderBy('order')->pluck('id')->toArray(),
+ 'created_at' => $status->created_at,
+ ]);
+ }
+ }
- protected function updateMedia($status, $activity)
- {
- if(!isset($activity['attachment'])) {
- return;
- }
- $ogm = $status->media->count() ? $status->media()->orderBy('order')->get() : collect([]);
- $nm = collect($activity['attachment'])->filter(function($nm) {
- return isset(
- $nm['type'],
- $nm['mediaType'],
- $nm['url']
- ) &&
- in_array($nm['type'], ['Document', 'Image', 'Video']) &&
- in_array($nm['mediaType'], explode(',', config('pixelfed.media_types')));
- });
+ protected function updateMedia($status, $activity)
+ {
+ if (! isset($activity['attachment'])) {
+ return;
+ }
+ $ogm = $status->media->count() ? $status->media()->orderBy('order')->get() : collect([]);
+ $nm = collect($activity['attachment'])->filter(function ($nm) {
+ return isset(
+ $nm['type'],
+ $nm['mediaType'],
+ $nm['url']
+ ) &&
+ in_array($nm['type'], ['Document', 'Image', 'Video']) &&
+ in_array($nm['mediaType'], explode(',', config_cache('pixelfed.media_types')));
+ });
- // Skip when no media
- if(!$ogm->count() && !$nm->count()) {
- return;
- }
+ // Skip when no media
+ if (! $ogm->count() && ! $nm->count()) {
+ return;
+ }
- Media::whereProfileId($status->profile_id)
- ->whereStatusId($status->id)
- ->update([
- 'status_id' => null
- ]);
+ Media::whereProfileId($status->profile_id)
+ ->whereStatusId($status->id)
+ ->update([
+ 'status_id' => null,
+ ]);
- $nm->each(function($n, $key) use($status) {
- $res = Http::withOptions(['allow_redirects' => false])->retry(3, 100, throw: false)->head($n['url']);
+ $nm->each(function ($n, $key) use ($status) {
+ $res = Http::withOptions(['allow_redirects' => false])->retry(3, 100, throw: false)->head($n['url']);
- if(!$res->successful()) {
- return;
- }
+ if (! $res->successful()) {
+ return;
+ }
- if(!in_array($res->header('content-type'), explode(',',config('pixelfed.media_types')))) {
- return;
- }
+ if (! in_array($res->header('content-type'), explode(',', config_cache('pixelfed.media_types')))) {
+ return;
+ }
- $m = new Media;
- $m->status_id = $status->id;
- $m->profile_id = $status->profile_id;
- $m->remote_media = true;
- $m->media_path = $n['url'];
+ $m = new Media;
+ $m->status_id = $status->id;
+ $m->profile_id = $status->profile_id;
+ $m->remote_media = true;
+ $m->media_path = $n['url'];
$m->mime = $res->header('content-type');
$m->size = $res->hasHeader('content-length') ? $res->header('content-length') : null;
- $m->caption = isset($n['name']) && !empty($n['name']) ? Purify::clean($n['name']) : null;
- $m->remote_url = $n['url'];
+ $m->caption = isset($n['name']) && ! empty($n['name']) ? Purify::clean($n['name']) : null;
+ $m->remote_url = $n['url'];
$m->blurhash = isset($n['blurhash']) && (strlen($n['blurhash']) < 50) ? $n['blurhash'] : null;
- $m->width = isset($n['width']) && !empty($n['width']) ? $n['width'] : null;
- $m->height = isset($n['height']) && !empty($n['height']) ? $n['height'] : null;
- $m->skip_optimize = true;
- $m->order = $key + 1;
- $m->save();
- });
- }
+ $m->width = isset($n['width']) && ! empty($n['width']) ? $n['width'] : null;
+ $m->height = isset($n['height']) && ! empty($n['height']) ? $n['height'] : null;
+ $m->skip_optimize = true;
+ $m->order = $key + 1;
+ $m->save();
+ });
+ }
- protected function updateImmediateAttributes($status, $activity)
- {
- if(isset($activity['content'])) {
- $status->caption = strip_tags($activity['content']);
- $status->rendered = Purify::clean($activity['content']);
- }
+ protected function updateImmediateAttributes($status, $activity)
+ {
+ if (isset($activity['content'])) {
+ $status->caption = strip_tags($activity['content']);
+ $status->rendered = Purify::clean($activity['content']);
+ }
- if(isset($activity['sensitive'])) {
- if((bool) $activity['sensitive'] == false) {
- $status->is_nsfw = false;
- $exists = ModLog::whereObjectType('App\Status::class')
- ->whereObjectId($status->id)
- ->whereAction('admin.status.moderate')
- ->exists();
- if($exists == true) {
- $status->is_nsfw = true;
- }
- $profile = Profile::find($status->profile_id);
- if(!$profile || $profile->cw == true) {
- $status->is_nsfw = true;
- }
- } else {
- $status->is_nsfw = true;
- }
- }
+ if (isset($activity['sensitive'])) {
+ if ((bool) $activity['sensitive'] == false) {
+ $status->is_nsfw = false;
+ $exists = ModLog::whereObjectType('App\Status::class')
+ ->whereObjectId($status->id)
+ ->whereAction('admin.status.moderate')
+ ->exists();
+ if ($exists == true) {
+ $status->is_nsfw = true;
+ }
+ $profile = Profile::find($status->profile_id);
+ if (! $profile || $profile->cw == true) {
+ $status->is_nsfw = true;
+ }
+ } else {
+ $status->is_nsfw = true;
+ }
+ }
- if(isset($activity['summary'])) {
- $status->cw_summary = Purify::clean($activity['summary']);
- } else {
- $status->cw_summary = null;
- }
+ if (isset($activity['summary'])) {
+ $status->cw_summary = Purify::clean($activity['summary']);
+ } else {
+ $status->cw_summary = null;
+ }
- $status->edited_at = now();
- $status->save();
- StatusService::del($status->id);
- }
+ $status->edited_at = now();
+ $status->save();
+ StatusService::del($status->id);
+ }
- protected function createEdit($status, $activity)
- {
- $cleaned = isset($activity['content']) ? Purify::clean($activity['content']) : null;
- $spoiler_text = isset($activity['summary']) ? Purify::clean($activity['summary']) : null;
- $sensitive = isset($activity['sensitive']) ? $activity['sensitive'] : null;
- $mids = $status->media()->count() ? $status->media()->orderBy('order')->pluck('id')->toArray() : null;
- StatusEdit::create([
- 'status_id' => $status->id,
- 'profile_id' => $status->profile_id,
- 'caption' => $cleaned,
- 'spoiler_text' => $spoiler_text,
- 'is_nsfw' => $sensitive,
- 'ordered_media_attachment_ids' => $mids
- ]);
- }
+ protected function createEdit($status, $activity)
+ {
+ $cleaned = isset($activity['content']) ? Purify::clean($activity['content']) : null;
+ $spoiler_text = isset($activity['summary']) ? Purify::clean($activity['summary']) : null;
+ $sensitive = isset($activity['sensitive']) ? $activity['sensitive'] : null;
+ $mids = $status->media()->count() ? $status->media()->orderBy('order')->pluck('id')->toArray() : null;
+ StatusEdit::create([
+ 'status_id' => $status->id,
+ 'profile_id' => $status->profile_id,
+ 'caption' => $cleaned,
+ 'spoiler_text' => $spoiler_text,
+ 'is_nsfw' => $sensitive,
+ 'ordered_media_attachment_ids' => $mids,
+ ]);
+ }
}
diff --git a/app/Models/CustomEmoji.php b/app/Models/CustomEmoji.php
index 1ff026a19..47aa0d1a8 100644
--- a/app/Models/CustomEmoji.php
+++ b/app/Models/CustomEmoji.php
@@ -18,7 +18,7 @@ class CustomEmoji extends Model
public static function scan($text, $activitypub = false)
{
- if(config('federation.custom_emoji.enabled') == false) {
+ if((bool) config_cache('federation.custom_emoji.enabled') == false) {
return [];
}
diff --git a/app/Observers/AvatarObserver.php b/app/Observers/AvatarObserver.php
index b7854e66f..557773ce0 100644
--- a/app/Observers/AvatarObserver.php
+++ b/app/Observers/AvatarObserver.php
@@ -3,9 +3,9 @@
namespace App\Observers;
use App\Avatar;
+use App\Services\AccountService;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
-use App\Services\AccountService;
class AvatarObserver
{
@@ -19,7 +19,6 @@ class AvatarObserver
/**
* Handle the avatar "created" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function created(Avatar $avatar)
@@ -30,7 +29,6 @@ class AvatarObserver
/**
* Handle the avatar "updated" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function updated(Avatar $avatar)
@@ -41,7 +39,6 @@ class AvatarObserver
/**
* Handle the avatar "deleted" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function deleted(Avatar $avatar)
@@ -52,23 +49,22 @@ class AvatarObserver
/**
* Handle the avatar "deleting" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function deleting(Avatar $avatar)
{
$path = storage_path('app/'.$avatar->media_path);
- if( is_file($path) &&
+ if (is_file($path) &&
$avatar->media_path != 'public/avatars/default.png' &&
$avatar->media_path != 'public/avatars/default.jpg'
) {
@unlink($path);
}
- if(config_cache('pixelfed.cloud_storage')) {
+ if ((bool) config_cache('pixelfed.cloud_storage')) {
$disk = Storage::disk(config('filesystems.cloud'));
$base = Str::startsWith($avatar->media_path, 'cache/avatars/');
- if($base && $disk->exists($avatar->media_path)) {
+ if ($base && $disk->exists($avatar->media_path)) {
$disk->delete($avatar->media_path);
}
}
@@ -78,7 +74,6 @@ class AvatarObserver
/**
* Handle the avatar "restored" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function restored(Avatar $avatar)
@@ -89,7 +84,6 @@ class AvatarObserver
/**
* Handle the avatar "force deleted" event.
*
- * @param \App\Avatar $avatar
* @return void
*/
public function forceDeleted(Avatar $avatar)
diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php
index d587bd7e8..2b5d46116 100644
--- a/app/Observers/UserObserver.php
+++ b/app/Observers/UserObserver.php
@@ -107,7 +107,7 @@ class UserObserver
CreateAvatar::dispatch($profile);
});
- if(config_cache('account.autofollow') == true) {
+ if((bool) config_cache('account.autofollow') == true) {
$names = config_cache('account.autofollow_usernames');
$names = explode(',', $names);
diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php
index 52e992ce0..43d12b592 100644
--- a/app/Providers/AuthServiceProvider.php
+++ b/app/Providers/AuthServiceProvider.php
@@ -2,9 +2,9 @@
namespace App\Providers;
+use Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Passport;
-use Gate;
class AuthServiceProvider extends ServiceProvider
{
@@ -24,11 +24,11 @@ class AuthServiceProvider extends ServiceProvider
*/
public function boot()
{
- if(config('app.env') === 'production' && config('pixelfed.oauth_enabled') == true) {
+ if (config('app.env') === 'production' && (bool) config_cache('pixelfed.oauth_enabled') == true) {
Passport::tokensExpireIn(now()->addDays(config('instance.oauth.token_expiration', 356)));
Passport::refreshTokensExpireIn(now()->addDays(config('instance.oauth.refresh_expiration', 400)));
Passport::enableImplicitGrant();
- if(config('instance.oauth.pat.enabled')) {
+ if (config('instance.oauth.pat.enabled')) {
Passport::personalAccessClientId(config('instance.oauth.pat.id'));
}
@@ -38,7 +38,7 @@ class AuthServiceProvider extends ServiceProvider
'follow' => 'Ability to follow other profiles',
'admin:read' => 'Read all data on the server',
'admin:write' => 'Modify all data on the server',
- 'push' => 'Receive your push notifications'
+ 'push' => 'Receive your push notifications',
]);
Passport::setDefaultScope([
diff --git a/app/Services/AdminSettingsService.php b/app/Services/AdminSettingsService.php
new file mode 100644
index 000000000..57fb6e96f
--- /dev/null
+++ b/app/Services/AdminSettingsService.php
@@ -0,0 +1,166 @@
+ self::getFeatures(),
+ 'landing' => self::getLanding(),
+ 'branding' => self::getBranding(),
+ 'media' => self::getMedia(),
+ 'rules' => self::getRules(),
+ 'suggested_rules' => self::getSuggestedRules(),
+ 'users' => self::getUsers(),
+ 'posts' => self::getPosts(),
+ 'platform' => self::getPlatform(),
+ 'storage' => self::getStorage(),
+ ];
+ }
+
+ public static function getFeatures()
+ {
+ $cloud_storage = (bool) config_cache('pixelfed.cloud_storage');
+ $cloud_disk = config('filesystems.cloud');
+ $cloud_ready = ! empty(config('filesystems.disks.'.$cloud_disk.'.key')) && ! empty(config('filesystems.disks.'.$cloud_disk.'.secret'));
+ $openReg = (bool) config_cache('pixelfed.open_registration');
+ $curOnboarding = (bool) config_cache('instance.curated_registration.enabled');
+ $regState = $openReg ? 'open' : ($curOnboarding ? 'filtered' : 'closed');
+
+ return [
+ 'registration_status' => $regState,
+ 'cloud_storage' => $cloud_ready && $cloud_storage,
+ 'activitypub_enabled' => (bool) config_cache('federation.activitypub.enabled'),
+ 'account_migration' => (bool) config_cache('federation.migration'),
+ 'mobile_apis' => (bool) config_cache('pixelfed.oauth_enabled'),
+ 'stories' => (bool) config_cache('instance.stories.enabled'),
+ 'instagram_import' => (bool) config_cache('pixelfed.import.instagram.enabled'),
+ 'autospam_enabled' => (bool) config_cache('pixelfed.bouncer.enabled'),
+ ];
+ }
+
+ public static function getLanding()
+ {
+ $availableAdmins = User::whereIsAdmin(true)->get();
+ $currentAdmin = config_cache('instance.admin.pid');
+
+ return [
+ 'admins' => $availableAdmins,
+ 'current_admin' => $currentAdmin,
+ 'show_directory' => (bool) config_cache('instance.landing.show_directory'),
+ 'show_explore' => (bool) config_cache('instance.landing.show_explore'),
+ ];
+ }
+
+ public static function getBranding()
+ {
+ return [
+ 'name' => config_cache('app.name'),
+ 'short_description' => config_cache('app.short_description'),
+ 'long_description' => config_cache('app.description'),
+ ];
+ }
+
+ public static function getMedia()
+ {
+ return [
+ 'max_photo_size' => config_cache('pixelfed.max_photo_size'),
+ 'max_album_length' => config_cache('pixelfed.max_album_length'),
+ 'image_quality' => config_cache('pixelfed.image_quality'),
+ 'media_types' => config_cache('pixelfed.media_types'),
+ 'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
+ 'optimize_video' => (bool) config_cache('pixelfed.optimize_video'),
+ ];
+ }
+
+ public static function getRules()
+ {
+ return config_cache('app.rules') ? json_decode(config_cache('app.rules'), true) : [];
+ }
+
+ public static function getSuggestedRules()
+ {
+ return BeagleService::getDefaultRules();
+ }
+
+ public static function getUsers()
+ {
+ $autoFollow = config_cache('account.autofollow_usernames');
+ if (strlen($autoFollow) >= 2) {
+ $autoFollow = explode(',', $autoFollow);
+ } else {
+ $autoFollow = [];
+ }
+
+ return [
+ 'require_email_verification' => (bool) config_cache('pixelfed.enforce_email_verification'),
+ 'enforce_account_limit' => (bool) config_cache('pixelfed.enforce_account_limit'),
+ 'max_account_size' => config_cache('pixelfed.max_account_size'),
+ 'admin_autofollow' => (bool) config_cache('account.autofollow'),
+ 'admin_autofollow_accounts' => $autoFollow,
+ 'max_user_blocks' => (int) config_cache('instance.user_filters.max_user_blocks'),
+ 'max_user_mutes' => (int) config_cache('instance.user_filters.max_user_mutes'),
+ 'max_domain_blocks' => (int) config_cache('instance.user_filters.max_domain_blocks'),
+ ];
+ }
+
+ public static function getPosts()
+ {
+ return [
+ 'max_caption_length' => config_cache('pixelfed.max_caption_length'),
+ 'max_altext_length' => config_cache('pixelfed.max_altext_length'),
+ ];
+ }
+
+ public static function getPlatform()
+ {
+ return [
+ 'allow_app_registration' => (bool) config_cache('pixelfed.allow_app_registration'),
+ 'app_registration_rate_limit_attempts' => config_cache('pixelfed.app_registration_rate_limit_attempts'),
+ 'app_registration_rate_limit_decay' => config_cache('pixelfed.app_registration_rate_limit_decay'),
+ 'app_registration_confirm_rate_limit_attempts' => config_cache('pixelfed.app_registration_confirm_rate_limit_attempts'),
+ 'app_registration_confirm_rate_limit_decay' => config_cache('pixelfed.app_registration_confirm_rate_limit_decay'),
+ 'allow_post_embeds' => (bool) config_cache('instance.embed.post'),
+ 'allow_profile_embeds' => (bool) config_cache('instance.embed.profile'),
+ 'captcha_enabled' => (bool) config_cache('captcha.enabled'),
+ 'captcha_on_login' => (bool) config_cache('captcha.active.login'),
+ 'captcha_on_register' => (bool) config_cache('captcha.active.register'),
+ 'captcha_secret' => Str::of(config_cache('captcha.secret'))->mask('*', 4, -4),
+ 'captcha_sitekey' => Str::of(config_cache('captcha.sitekey'))->mask('*', 4, -4),
+ 'custom_emoji_enabled' => (bool) config_cache('federation.custom_emoji.enabled'),
+ ];
+ }
+
+ public static function getStorage()
+ {
+ $cloud_storage = (bool) config_cache('pixelfed.cloud_storage');
+ $cloud_disk = config('filesystems.cloud');
+ $cloud_ready = ! empty(config('filesystems.disks.'.$cloud_disk.'.key')) && ! empty(config('filesystems.disks.'.$cloud_disk.'.secret'));
+ $primaryDisk = (bool) $cloud_ready && $cloud_storage;
+ $pkey = 'filesystems.disks.'.$cloud_disk.'.';
+ $disk = [
+ 'driver' => $cloud_disk,
+ 'key' => Str::of(config_cache($pkey.'key'))->mask('*', 0, -2),
+ 'secret' => Str::of(config_cache($pkey.'secret'))->mask('*', 0, -2),
+ 'region' => config_cache($pkey.'region'),
+ 'bucket' => config_cache($pkey.'bucket'),
+ 'visibility' => config_cache($pkey.'visibility'),
+ 'endpoint' => config_cache($pkey.'endpoint'),
+ 'url' => config_cache($pkey.'url'),
+ 'use_path_style_endpoint' => config_cache($pkey.'use_path_style_endpoint'),
+ ];
+
+ return [
+ 'primary_disk' => $primaryDisk ? 'cloud' : 'local',
+ 'cloud_ready' => (bool) $cloud_ready,
+ 'cloud_disk' => $cloud_disk,
+ 'disk_config' => $disk,
+ ];
+ }
+}
diff --git a/app/Services/AutospamService.php b/app/Services/AutospamService.php
index 6986e81e4..3164d14d0 100644
--- a/app/Services/AutospamService.php
+++ b/app/Services/AutospamService.php
@@ -2,77 +2,82 @@
namespace App\Services;
+use App\Util\Lexer\Classifier;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
-use App\Util\Lexer\Classifier;
class AutospamService
{
- const CHCKD_CACHE_KEY = 'pf:services:autospam:nlp:checked';
- const MODEL_CACHE_KEY = 'pf:services:autospam:nlp:model-cache';
- const MODEL_FILE_PATH = 'nlp/active-training-data.json';
- const MODEL_SPAM_PATH = 'nlp/spam.json';
- const MODEL_HAM_PATH = 'nlp/ham.json';
+ const CHCKD_CACHE_KEY = 'pf:services:autospam:nlp:checked';
- public static function check($text)
- {
- if(!$text || strlen($text) == 0) {
- false;
- }
- if(!self::active()) {
- return null;
- }
- $model = self::getCachedModel();
- $classifier = new Classifier;
- $classifier->import($model['documents'], $model['words']);
- return $classifier->most($text) === 'spam';
- }
+ const MODEL_CACHE_KEY = 'pf:services:autospam:nlp:model-cache';
- public static function eligible()
- {
- return Cache::remember(self::CHCKD_CACHE_KEY, 86400, function() {
- if(!config_cache('pixelfed.bouncer.enabled') || !config('autospam.enabled')) {
- return false;
- }
+ const MODEL_FILE_PATH = 'nlp/active-training-data.json';
- if(!Storage::exists(self::MODEL_SPAM_PATH)) {
- return false;
- }
+ const MODEL_SPAM_PATH = 'nlp/spam.json';
- if(!Storage::exists(self::MODEL_HAM_PATH)) {
- return false;
- }
+ const MODEL_HAM_PATH = 'nlp/ham.json';
- if(!Storage::exists(self::MODEL_FILE_PATH)) {
- return false;
- } else {
- if(Storage::size(self::MODEL_FILE_PATH) < 1000) {
- return false;
- }
- }
+ public static function check($text)
+ {
+ if (! $text || strlen($text) == 0) {
- return true;
- });
- }
+ }
+ if (! self::active()) {
+ return null;
+ }
+ $model = self::getCachedModel();
+ $classifier = new Classifier;
+ $classifier->import($model['documents'], $model['words']);
- public static function active()
- {
- return config_cache('autospam.nlp.enabled') && self::eligible();
- }
+ return $classifier->most($text) === 'spam';
+ }
- public static function getCachedModel()
- {
- if(!self::active()) {
- return null;
- }
+ public static function eligible()
+ {
+ return Cache::remember(self::CHCKD_CACHE_KEY, 86400, function () {
+ if (! (bool) config_cache('pixelfed.bouncer.enabled') || ! (bool) config_cache('autospam.enabled')) {
+ return false;
+ }
- return Cache::remember(self::MODEL_CACHE_KEY, 86400, function() {
- $res = Storage::get(self::MODEL_FILE_PATH);
- if(!$res || empty($res)) {
- return null;
- }
+ if (! Storage::exists(self::MODEL_SPAM_PATH)) {
+ return false;
+ }
- return json_decode($res, true);
- });
- }
+ if (! Storage::exists(self::MODEL_HAM_PATH)) {
+ return false;
+ }
+
+ if (! Storage::exists(self::MODEL_FILE_PATH)) {
+ return false;
+ } else {
+ if (Storage::size(self::MODEL_FILE_PATH) < 1000) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ }
+
+ public static function active()
+ {
+ return config_cache('autospam.nlp.enabled') && self::eligible();
+ }
+
+ public static function getCachedModel()
+ {
+ if (! self::active()) {
+ return null;
+ }
+
+ return Cache::remember(self::MODEL_CACHE_KEY, 86400, function () {
+ $res = Storage::get(self::MODEL_FILE_PATH);
+ if (! $res || empty($res)) {
+ return null;
+ }
+
+ return json_decode($res, true);
+ });
+ }
}
diff --git a/app/Services/ConfigCacheService.php b/app/Services/ConfigCacheService.php
index 7537830fc..626982781 100644
--- a/app/Services/ConfigCacheService.php
+++ b/app/Services/ConfigCacheService.php
@@ -8,6 +8,14 @@ use Cache;
class ConfigCacheService
{
const CACHE_KEY = 'config_cache:_v0-key:';
+ const PROTECTED_KEYS = [
+ 'filesystems.disks.s3.key',
+ 'filesystems.disks.s3.secret',
+ 'filesystems.disks.spaces.key',
+ 'filesystems.disks.spaces.secret',
+ 'captcha.secret',
+ 'captcha.sitekey',
+ ];
public static function get($key)
{
@@ -89,6 +97,41 @@ class ConfigCacheService
'pixelfed.app_registration_confirm_rate_limit_decay',
'instance.embed.profile',
'instance.embed.post',
+
+ 'captcha.enabled',
+ 'captcha.secret',
+ 'captcha.sitekey',
+ 'captcha.active.login',
+ 'captcha.active.register',
+ 'captcha.triggers.login.enabled',
+ 'captcha.triggers.login.attempts',
+ 'federation.custom_emoji.enabled',
+
+ 'pixelfed.optimize_image',
+ 'pixelfed.optimize_video',
+ 'pixelfed.max_collection_length',
+ 'media.delete_local_after_cloud',
+ 'instance.user_filters.max_user_blocks',
+ 'instance.user_filters.max_user_mutes',
+ 'instance.user_filters.max_domain_blocks',
+
+ 'filesystems.disks.s3.key',
+ 'filesystems.disks.s3.secret',
+ 'filesystems.disks.s3.region',
+ 'filesystems.disks.s3.bucket',
+ 'filesystems.disks.s3.visibility',
+ 'filesystems.disks.s3.url',
+ 'filesystems.disks.s3.endpoint',
+ 'filesystems.disks.s3.use_path_style_endpoint',
+
+ 'filesystems.disks.spaces.key',
+ 'filesystems.disks.spaces.secret',
+ 'filesystems.disks.spaces.region',
+ 'filesystems.disks.spaces.bucket',
+ 'filesystems.disks.spaces.visibility',
+ 'filesystems.disks.spaces.url',
+ 'filesystems.disks.spaces.endpoint',
+ 'filesystems.disks.spaces.use_path_style_endpoint',
// 'system.user_mode'
];
@@ -100,20 +143,34 @@ class ConfigCacheService
return config($key);
}
+ $protect = false;
+ $protected = null;
+ if(in_array($key, self::PROTECTED_KEYS)) {
+ $protect = true;
+ }
+
$v = config($key);
$c = ConfigCacheModel::where('k', $key)->first();
if ($c) {
- return $c->v ?? config($key);
+ if($protect) {
+ return decrypt($c->v) ?? config($key);
+ } else {
+ return $c->v ?? config($key);
+ }
}
if (! $v) {
return;
}
+ if($protect && $v) {
+ $protected = encrypt($v);
+ }
+
$cc = new ConfigCacheModel;
$cc->k = $key;
- $cc->v = $v;
+ $cc->v = $protect ? $protected : $v;
$cc->save();
return $v;
@@ -124,8 +181,15 @@ class ConfigCacheService
{
$exists = ConfigCacheModel::whereK($key)->first();
+ $protect = false;
+ $protected = null;
+ if(in_array($key, self::PROTECTED_KEYS)) {
+ $protect = true;
+ $protected = encrypt($val);
+ }
+
if ($exists) {
- $exists->v = $val;
+ $exists->v = $protect ? $protected : $val;
$exists->save();
Cache::put(self::CACHE_KEY.$key, $val, now()->addHours(12));
@@ -134,7 +198,7 @@ class ConfigCacheService
$cc = new ConfigCacheModel;
$cc->k = $key;
- $cc->v = $val;
+ $cc->v = $protect ? $protected : $val;
$cc->save();
Cache::put(self::CACHE_KEY.$key, $val, now()->addHours(12));
diff --git a/app/Services/CustomEmojiService.php b/app/Services/CustomEmojiService.php
index a95c93a2a..468772b5f 100644
--- a/app/Services/CustomEmojiService.php
+++ b/app/Services/CustomEmojiService.php
@@ -13,7 +13,7 @@ class CustomEmojiService
{
public static function get($shortcode)
{
- if(config('federation.custom_emoji.enabled') == false) {
+ if((bool) config_cache('federation.custom_emoji.enabled') == false) {
return;
}
@@ -22,7 +22,7 @@ class CustomEmojiService
public static function import($url, $id = false)
{
- if(config('federation.custom_emoji.enabled') == false) {
+ if((bool) config_cache('federation.custom_emoji.enabled') == false) {
return;
}
diff --git a/app/Services/FilesystemService.php b/app/Services/FilesystemService.php
new file mode 100644
index 000000000..b52f002f4
--- /dev/null
+++ b/app/Services/FilesystemService.php
@@ -0,0 +1,82 @@
+ 'latest',
+ 'region' => $region,
+ 'endpoint' => $endpoint,
+ 'credentials' => [
+ 'key' => $key,
+ 'secret' => $secret,
+ ]
+ ]);
+
+ $adapter = new AwsS3V3Adapter(
+ $client,
+ $bucket,
+ );
+
+ $throw = false;
+ $filesystem = new Filesystem($adapter);
+
+ $writable = false;
+ try {
+ $filesystem->write(self::VERIFY_FILE_NAME, 'ok', []);
+ $writable = true;
+ } catch (FilesystemException | UnableToWriteFile $exception) {
+ $writable = false;
+ }
+
+ if(!$writable) {
+ return false;
+ }
+
+ try {
+ $response = $filesystem->read(self::VERIFY_FILE_NAME);
+ if($response === 'ok') {
+ $writable = true;
+ $res[] = self::VERIFY_FILE_NAME;
+ } else {
+ $writable = false;
+ }
+ } catch (FilesystemException | UnableToReadFile $exception) {
+ $writable = false;
+ }
+
+ if(in_array(self::VERIFY_FILE_NAME, $res)) {
+ try {
+ $filesystem->delete(self::VERIFY_FILE_NAME);
+ } catch (FilesystemException | UnableToDeleteFile $exception) {
+ $writable = false;
+ }
+ }
+
+ if(!$writable) {
+ return false;
+ }
+
+ if(in_array(self::VERIFY_FILE_NAME, $res)) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Services/Internal/BeagleService.php b/app/Services/Internal/BeagleService.php
new file mode 100644
index 000000000..60a4f78e4
--- /dev/null
+++ b/app/Services/Internal/BeagleService.php
@@ -0,0 +1,44 @@
+addDays(7), function() {
+ try {
+ $res = Http::withOptions(['allow_redirects' => false])
+ ->timeout(5)
+ ->connectTimeout(5)
+ ->retry(2, 500)
+ ->get('https://beagle.pixelfed.net/api/v1/common/suggestions/rules');
+ } catch (RequestException $e) {
+ return;
+ } catch (ConnectionException $e) {
+ return;
+ } catch (Exception $e) {
+ return;
+ }
+
+ if(!$res->ok()) {
+ return;
+ }
+
+ $json = $res->json();
+
+ if(!isset($json['rule_suggestions']) || !count($json['rule_suggestions'])) {
+ return [];
+ }
+ return $json['rule_suggestions'];
+ });
+ }
+
+}
diff --git a/app/Services/LandingService.php b/app/Services/LandingService.php
index 20759ecf4..f51822df2 100644
--- a/app/Services/LandingService.php
+++ b/app/Services/LandingService.php
@@ -53,8 +53,8 @@ class LandingService
'name' => config_cache('app.name'),
'url' => config_cache('app.url'),
'domain' => config('pixelfed.domain.app'),
- 'show_directory' => config_cache('instance.landing.show_directory'),
- 'show_explore_feed' => config_cache('instance.landing.show_explore'),
+ 'show_directory' => (bool) config_cache('instance.landing.show_directory'),
+ 'show_explore_feed' => (bool) config_cache('instance.landing.show_explore'),
'open_registration' => (bool) $openReg,
'curated_onboarding' => (bool) config_cache('instance.curated_registration.enabled'),
'version' => config('pixelfed.version'),
@@ -85,7 +85,7 @@ class LandingService
'media_types' => config_cache('pixelfed.media_types'),
],
'features' => [
- 'federation' => config_cache('federation.activitypub.enabled'),
+ 'federation' => (bool) config_cache('federation.activitypub.enabled'),
'timelines' => [
'local' => true,
'network' => (bool) config_cache('federation.network_timeline'),
diff --git a/app/Services/MediaStorageService.php b/app/Services/MediaStorageService.php
index 216e37497..87bb9a586 100644
--- a/app/Services/MediaStorageService.php
+++ b/app/Services/MediaStorageService.php
@@ -2,44 +2,38 @@
namespace App\Services;
+use App\Jobs\AvatarPipeline\AvatarStorageCleanup;
+use App\Jobs\MediaPipeline\MediaDeletePipeline;
+use App\Media;
use App\Util\ActivityPub\Helpers;
+use GuzzleHttp\Client;
+use GuzzleHttp\Exception\RequestException;
use Illuminate\Http\File;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
-use App\Media;
-use App\Profile;
-use App\User;
-use GuzzleHttp\Client;
-use App\Services\AccountService;
-use App\Http\Controllers\AvatarController;
-use GuzzleHttp\Exception\RequestException;
-use App\Jobs\MediaPipeline\MediaDeletePipeline;
-use Illuminate\Support\Arr;
-use App\Jobs\AvatarPipeline\AvatarStorageCleanup;
-
-class MediaStorageService {
+class MediaStorageService
+{
public static function store(Media $media)
{
- if(config_cache('pixelfed.cloud_storage') == true) {
+ if ((bool) config_cache('pixelfed.cloud_storage') == true) {
(new self())->cloudStore($media);
}
- return;
}
public static function move(Media $media)
{
- if($media->remote_media) {
+ if ($media->remote_media) {
return;
}
- if(config_cache('pixelfed.cloud_storage') == true) {
+ if ((bool) config_cache('pixelfed.cloud_storage') == true) {
return (new self())->cloudMove($media);
}
- return;
+
}
public static function avatar($avatar, $local = false, $skipRecentCheck = false)
@@ -56,31 +50,31 @@ class MediaStorageService {
return false;
}
- $h = Arr::mapWithKeys($r->getHeaders(), function($item, $key) {
+ $h = Arr::mapWithKeys($r->getHeaders(), function ($item, $key) {
return [strtolower($key) => last($item)];
});
- if(!isset($h['content-length'], $h['content-type'])) {
+ if (! isset($h['content-length'], $h['content-type'])) {
return false;
}
$len = (int) $h['content-length'];
$mime = $h['content-type'];
- if($len < 10 || $len > ((config_cache('pixelfed.max_photo_size') * 1000))) {
+ if ($len < 10 || $len > ((config_cache('pixelfed.max_photo_size') * 1000))) {
return false;
}
return [
'length' => $len,
- 'mime' => $mime
+ 'mime' => $mime,
];
}
protected function cloudStore($media)
{
- if($media->remote_media == true) {
- if(config('media.storage.remote.cloud')) {
+ if ($media->remote_media == true) {
+ if (config('media.storage.remote.cloud')) {
(new self())->remoteToCloud($media);
}
} else {
@@ -100,7 +94,7 @@ class MediaStorageService {
$storagePath = implode('/', $p);
$url = ResilientMediaStorageService::store($storagePath, $path, $name);
- if($thumb) {
+ if ($thumb) {
$thumbUrl = ResilientMediaStorageService::store($storagePath, $thumb, $thumbname);
$media->thumbnail_url = $thumbUrl;
}
@@ -108,8 +102,8 @@ class MediaStorageService {
$media->optimized_url = $url;
$media->replicated_at = now();
$media->save();
- if($media->status_id) {
- Cache::forget('status:transformer:media:attachments:' . $media->status_id);
+ if ($media->status_id) {
+ Cache::forget('status:transformer:media:attachments:'.$media->status_id);
MediaService::del($media->status_id);
StatusService::del($media->status_id, false);
}
@@ -119,20 +113,20 @@ class MediaStorageService {
{
$url = $media->remote_url;
- if(!Helpers::validateUrl($url)) {
+ if (! Helpers::validateUrl($url)) {
return;
}
$head = $this->head($media->remote_url);
- if(!$head) {
+ if (! $head) {
return;
}
$mimes = [
'image/jpeg',
'image/png',
- 'video/mp4'
+ 'video/mp4',
];
$mime = $head['mime'];
@@ -141,11 +135,11 @@ class MediaStorageService {
$media->remote_media = true;
$media->save();
- if(!in_array($mime, $mimes)) {
+ if (! in_array($mime, $mimes)) {
return;
}
- if($head['length'] >= $max_size) {
+ if ($head['length'] >= $max_size) {
return;
}
@@ -168,10 +162,10 @@ class MediaStorageService {
}
$base = MediaPathService::get($media->profile);
- $path = Str::random(40) . $ext;
+ $path = Str::random(40).$ext;
$tmpBase = storage_path('app/remcache/');
- $tmpPath = $media->profile_id . '-' . $path;
- $tmpName = $tmpBase . $tmpPath;
+ $tmpPath = $media->profile_id.'-'.$path;
+ $tmpName = $tmpBase.$tmpPath;
$data = file_get_contents($url, false, null, 0, $head['length']);
file_put_contents($tmpName, $data);
$hash = hash_file('sha256', $tmpName);
@@ -186,8 +180,8 @@ class MediaStorageService {
$media->replicated_at = now();
$media->save();
- if($media->status_id) {
- Cache::forget('status:transformer:media:attachments:' . $media->status_id);
+ if ($media->status_id) {
+ Cache::forget('status:transformer:media:attachments:'.$media->status_id);
}
unlink($tmpName);
@@ -199,13 +193,13 @@ class MediaStorageService {
$url = $avatar->remote_url;
$driver = $local ? 'local' : config('filesystems.cloud');
- if(empty($url) || Helpers::validateUrl($url) == false) {
+ if (empty($url) || Helpers::validateUrl($url) == false) {
return;
}
$head = $this->head($url);
- if($head == false) {
+ if ($head == false) {
return;
}
@@ -218,46 +212,47 @@ class MediaStorageService {
$mime = $head['mime'];
$max_size = (int) config('pixelfed.max_avatar_size') * 1000;
- if(!$skipRecentCheck) {
- if($avatar->last_fetched_at && $avatar->last_fetched_at->gt(now()->subMonths(3))) {
+ if (! $skipRecentCheck) {
+ if ($avatar->last_fetched_at && $avatar->last_fetched_at->gt(now()->subMonths(3))) {
return;
}
}
- Cache::forget('avatar:' . $avatar->profile_id);
+ Cache::forget('avatar:'.$avatar->profile_id);
AccountService::del($avatar->profile_id);
// handle pleroma edge case
- if(Str::endsWith($mime, '; charset=utf-8')) {
+ if (Str::endsWith($mime, '; charset=utf-8')) {
$mime = str_replace('; charset=utf-8', '', $mime);
}
- if(!in_array($mime, $mimes)) {
+ if (! in_array($mime, $mimes)) {
return;
}
- if($head['length'] >= $max_size) {
+ if ($head['length'] >= $max_size) {
return;
}
- $base = ($local ? 'public/cache/' : 'cache/') . 'avatars/' . $avatar->profile_id;
+ $base = ($local ? 'public/cache/' : 'cache/').'avatars/'.$avatar->profile_id;
$ext = $head['mime'] == 'image/jpeg' ? 'jpg' : 'png';
- $path = 'avatar_' . strtolower(Str::random(random_int(3,6))) . '.' . $ext;
+ $path = 'avatar_'.strtolower(Str::random(random_int(3, 6))).'.'.$ext;
$tmpBase = storage_path('app/remcache/');
- $tmpPath = 'avatar_' . $avatar->profile_id . '-' . $path;
- $tmpName = $tmpBase . $tmpPath;
+ $tmpPath = 'avatar_'.$avatar->profile_id.'-'.$path;
+ $tmpName = $tmpBase.$tmpPath;
$data = @file_get_contents($url, false, null, 0, $head['length']);
- if(!$data) {
+ if (! $data) {
return;
}
file_put_contents($tmpName, $data);
- $mimeCheck = Storage::mimeType('remcache/' . $tmpPath);
+ $mimeCheck = Storage::mimeType('remcache/'.$tmpPath);
- if(!$mimeCheck || !in_array($mimeCheck, ['image/png', 'image/jpeg'])) {
+ if (! $mimeCheck || ! in_array($mimeCheck, ['image/png', 'image/jpeg'])) {
$avatar->last_fetched_at = now();
$avatar->save();
unlink($tmpName);
+
return;
}
@@ -265,15 +260,15 @@ class MediaStorageService {
$file = $disk->putFileAs($base, new File($tmpName), $path, 'public');
$permalink = $disk->url($file);
- $avatar->media_path = $base . '/' . $path;
+ $avatar->media_path = $base.'/'.$path;
$avatar->is_remote = true;
- $avatar->cdn_url = $local ? config('app.url') . $permalink : $permalink;
+ $avatar->cdn_url = $local ? config('app.url').$permalink : $permalink;
$avatar->size = $head['length'];
$avatar->change_count = $avatar->change_count + 1;
$avatar->last_fetched_at = now();
$avatar->save();
- Cache::forget('avatar:' . $avatar->profile_id);
+ Cache::forget('avatar:'.$avatar->profile_id);
AccountService::del($avatar->profile_id);
AvatarStorageCleanup::dispatch($avatar)->onQueue($queue)->delay(now()->addMinutes(random_int(3, 15)));
@@ -282,7 +277,7 @@ class MediaStorageService {
public static function delete(Media $media, $confirm = false)
{
- if(!$confirm) {
+ if (! $confirm) {
return;
}
MediaDeletePipeline::dispatch($media)->onQueue('mmo');
@@ -290,13 +285,13 @@ class MediaStorageService {
protected function cloudMove($media)
{
- if(!Storage::exists($media->media_path)) {
+ if (! Storage::exists($media->media_path)) {
return 'invalid file';
}
$path = storage_path('app/'.$media->media_path);
$thumb = false;
- if($media->thumbnail_path) {
+ if ($media->thumbnail_path) {
$thumb = storage_path('app/'.$media->thumbnail_path);
$pt = explode('/', $media->thumbnail_path);
$thumbname = array_pop($pt);
@@ -307,7 +302,7 @@ class MediaStorageService {
$storagePath = implode('/', $p);
$url = ResilientMediaStorageService::store($storagePath, $path, $name);
- if($thumb) {
+ if ($thumb) {
$thumbUrl = ResilientMediaStorageService::store($storagePath, $thumb, $thumbname);
$media->thumbnail_url = $thumbUrl;
}
@@ -316,8 +311,8 @@ class MediaStorageService {
$media->replicated_at = now();
$media->save();
- if($media->status_id) {
- Cache::forget('status:transformer:media:attachments:' . $media->status_id);
+ if ($media->status_id) {
+ Cache::forget('status:transformer:media:attachments:'.$media->status_id);
MediaService::del($media->status_id);
StatusService::del($media->status_id, false);
}
diff --git a/app/Util/ActivityPub/Helpers.php b/app/Util/ActivityPub/Helpers.php
index bcf4f359c..2002a8967 100644
--- a/app/Util/ActivityPub/Helpers.php
+++ b/app/Util/ActivityPub/Helpers.php
@@ -2,49 +2,34 @@
namespace App\Util\ActivityPub;
-use DB, Cache, Purify, Storage, Request, Validator;
-use App\{
- Activity,
- Follower,
- Instance,
- Like,
- Media,
- Notification,
- Profile,
- Status
-};
-use Zttp\Zttp;
-use Carbon\Carbon;
-use GuzzleHttp\Client;
-use Illuminate\Http\File;
-use Illuminate\Validation\Rule;
-use App\Jobs\AvatarPipeline\CreateAvatar;
-use App\Jobs\RemoteFollowPipeline\RemoteFollowImportRecent;
-use App\Jobs\ImageOptimizePipeline\{ImageOptimize,ImageThumbnail};
-use App\Jobs\StatusPipeline\NewStatusPipeline;
-use App\Jobs\StatusPipeline\StatusReplyPipeline;
-use App\Jobs\StatusPipeline\StatusTagsPipeline;
-use App\Util\ActivityPub\HttpSignature;
-use Illuminate\Support\Str;
-use App\Services\ActivityPubFetchService;
-use App\Services\ActivityPubDeliveryService;
-use App\Services\CustomEmojiService;
-use App\Services\InstanceService;
-use App\Services\MediaPathService;
-use App\Services\MediaStorageService;
-use App\Services\NetworkTimelineService;
-use App\Jobs\MediaPipeline\MediaStoragePipeline;
+use App\Instance;
use App\Jobs\AvatarPipeline\RemoteAvatarFetch;
use App\Jobs\HomeFeedPipeline\FeedInsertRemotePipeline;
-use App\Util\Media\License;
+use App\Jobs\MediaPipeline\MediaStoragePipeline;
+use App\Jobs\StatusPipeline\StatusReplyPipeline;
+use App\Jobs\StatusPipeline\StatusTagsPipeline;
+use App\Media;
use App\Models\Poll;
-use Illuminate\Contracts\Cache\LockTimeoutException;
-use App\Services\DomainService;
-use App\Services\UserFilterService;
+use App\Profile;
use App\Services\Account\AccountStatService;
+use App\Services\ActivityPubDeliveryService;
+use App\Services\ActivityPubFetchService;
+use App\Services\DomainService;
+use App\Services\InstanceService;
+use App\Services\MediaPathService;
+use App\Services\NetworkTimelineService;
+use App\Services\UserFilterService;
+use App\Status;
+use App\Util\Media\License;
+use Cache;
+use Carbon\Carbon;
+use Illuminate\Support\Str;
+use Illuminate\Validation\Rule;
+use Purify;
+use Validator;
-class Helpers {
-
+class Helpers
+{
public static function validateObject($data)
{
$verbs = ['Create', 'Announce', 'Like', 'Follow', 'Delete', 'Accept', 'Reject', 'Undo', 'Tombstone'];
@@ -53,14 +38,14 @@ class Helpers {
'type' => [
'required',
'string',
- Rule::in($verbs)
+ Rule::in($verbs),
],
'id' => 'required|string',
'actor' => 'required|string|url',
'object' => 'required',
'object.type' => 'required_if:type,Create',
'object.attributedTo' => 'required_if:type,Create|url',
- 'published' => 'required_if:type,Create|date'
+ 'published' => 'required_if:type,Create|date',
])->passes();
return $valid;
@@ -68,8 +53,8 @@ class Helpers {
public static function verifyAttachments($data)
{
- if(!isset($data['object']) || empty($data['object'])) {
- $data = ['object'=>$data];
+ if (! isset($data['object']) || empty($data['object'])) {
+ $data = ['object' => $data];
}
$activity = $data['object'];
@@ -80,7 +65,7 @@ class Helpers {
// Peertube
// $mediaTypes = in_array('video/mp4', $mimeTypes) ? ['Document', 'Image', 'Video', 'Link'] : ['Document', 'Image'];
- if(!isset($activity['attachment']) || empty($activity['attachment'])) {
+ if (! isset($activity['attachment']) || empty($activity['attachment'])) {
return false;
}
@@ -100,13 +85,13 @@ class Helpers {
'*.type' => [
'required',
'string',
- Rule::in($mediaTypes)
+ Rule::in($mediaTypes),
],
'*.url' => 'required|url',
- '*.mediaType' => [
+ '*.mediaType' => [
'required',
'string',
- Rule::in($mimeTypes)
+ Rule::in($mimeTypes),
],
'*.name' => 'sometimes|nullable|string',
'*.blurhash' => 'sometimes|nullable|string|min:6|max:164',
@@ -119,7 +104,7 @@ class Helpers {
public static function normalizeAudience($data, $localOnly = true)
{
- if(!isset($data['to'])) {
+ if (! isset($data['to'])) {
return;
}
@@ -128,32 +113,35 @@ class Helpers {
$audience['cc'] = [];
$scope = 'private';
- if(is_array($data['to']) && !empty($data['to'])) {
+ if (is_array($data['to']) && ! empty($data['to'])) {
foreach ($data['to'] as $to) {
- if($to == 'https://www.w3.org/ns/activitystreams#Public') {
+ if ($to == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'public';
+
continue;
}
$url = $localOnly ? self::validateLocalUrl($to) : self::validateUrl($to);
- if($url != false) {
+ if ($url != false) {
array_push($audience['to'], $url);
}
}
}
- if(is_array($data['cc']) && !empty($data['cc'])) {
+ if (is_array($data['cc']) && ! empty($data['cc'])) {
foreach ($data['cc'] as $cc) {
- if($cc == 'https://www.w3.org/ns/activitystreams#Public') {
+ if ($cc == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'unlisted';
+
continue;
}
$url = $localOnly ? self::validateLocalUrl($cc) : self::validateUrl($cc);
- if($url != false) {
+ if ($url != false) {
array_push($audience['cc'], $url);
}
}
}
$audience['scope'] = $scope;
+
return $audience;
}
@@ -161,56 +149,57 @@ class Helpers {
{
$audience = self::normalizeAudience($data);
$url = $profile->permalink();
+
return in_array($url, $audience['to']) || in_array($url, $audience['cc']);
}
public static function validateUrl($url)
{
- if(is_array($url)) {
+ if (is_array($url)) {
$url = $url[0];
}
$hash = hash('sha256', $url);
$key = "helpers:url:valid:sha256-{$hash}";
- $valid = Cache::remember($key, 900, function() use($url) {
+ $valid = Cache::remember($key, 900, function () use ($url) {
$localhosts = [
- '127.0.0.1', 'localhost', '::1'
+ '127.0.0.1', 'localhost', '::1',
];
- if(strtolower(mb_substr($url, 0, 8)) !== 'https://') {
+ if (strtolower(mb_substr($url, 0, 8)) !== 'https://') {
return false;
}
- if(substr_count($url, '://') !== 1) {
+ if (substr_count($url, '://') !== 1) {
return false;
}
- if(mb_substr($url, 0, 8) !== 'https://') {
- $url = 'https://' . substr($url, 8);
+ if (mb_substr($url, 0, 8) !== 'https://') {
+ $url = 'https://'.substr($url, 8);
}
$valid = filter_var($url, FILTER_VALIDATE_URL);
- if(!$valid) {
+ if (! $valid) {
return false;
}
$host = parse_url($valid, PHP_URL_HOST);
- if(in_array($host, $localhosts)) {
+ if (in_array($host, $localhosts)) {
return false;
}
- if(config('security.url.verify_dns')) {
- if(DomainService::hasValidDns($host) === false) {
+ if (config('security.url.verify_dns')) {
+ if (DomainService::hasValidDns($host) === false) {
return false;
}
}
- if(app()->environment() === 'production') {
+ if (app()->environment() === 'production') {
$bannedInstances = InstanceService::getBannedDomains();
- if(in_array($host, $bannedInstances)) {
+ if (in_array($host, $bannedInstances)) {
return false;
}
}
@@ -224,12 +213,14 @@ class Helpers {
public static function validateLocalUrl($url)
{
$url = self::validateUrl($url);
- if($url == true) {
+ if ($url == true) {
$domain = config('pixelfed.domain.app');
$host = parse_url($url, PHP_URL_HOST);
$url = strtolower($domain) === strtolower($host) ? $url : false;
+
return $url;
}
+
return false;
}
@@ -237,15 +228,16 @@ class Helpers {
{
$version = config('pixelfed.version');
$url = config('app.url');
+
return [
- 'Accept' => 'application/activity+json',
+ 'Accept' => 'application/activity+json',
'User-Agent' => "(Pixelfed/{$version}; +{$url})",
];
}
public static function fetchFromUrl($url = false)
{
- if(self::validateUrl($url) == false) {
+ if (self::validateUrl($url) == false) {
return;
}
@@ -253,13 +245,13 @@ class Helpers {
$key = "helpers:url:fetcher:sha256-{$hash}";
$ttl = now()->addMinutes(15);
- return Cache::remember($key, $ttl, function() use($url) {
+ return Cache::remember($key, $ttl, function () use ($url) {
$res = ActivityPubFetchService::get($url);
- if(!$res || empty($res)) {
+ if (! $res || empty($res)) {
return false;
}
$res = json_decode($res, true, 8);
- if(json_last_error() == JSON_ERROR_NONE) {
+ if (json_last_error() == JSON_ERROR_NONE) {
return $res;
} else {
return false;
@@ -274,12 +266,12 @@ class Helpers {
public static function pluckval($val)
{
- if(is_string($val)) {
+ if (is_string($val)) {
return $val;
}
- if(is_array($val)) {
- return !empty($val) ? head($val) : null;
+ if (is_array($val)) {
+ return ! empty($val) ? head($val) : null;
}
return null;
@@ -288,51 +280,52 @@ class Helpers {
public static function statusFirstOrFetch($url, $replyTo = false)
{
$url = self::validateUrl($url);
- if($url == false) {
+ if ($url == false) {
return;
}
$host = parse_url($url, PHP_URL_HOST);
$local = config('pixelfed.domain.app') == $host ? true : false;
- if($local) {
+ if ($local) {
$id = (int) last(explode('/', $url));
- return Status::whereNotIn('scope', ['draft','archived'])->findOrFail($id);
+
+ return Status::whereNotIn('scope', ['draft', 'archived'])->findOrFail($id);
}
- $cached = Status::whereNotIn('scope', ['draft','archived'])
+ $cached = Status::whereNotIn('scope', ['draft', 'archived'])
->whereUri($url)
->orWhere('object_url', $url)
->first();
- if($cached) {
+ if ($cached) {
return $cached;
}
$res = self::fetchFromUrl($url);
- if(!$res || empty($res) || isset($res['error']) || !isset($res['@context']) || !isset($res['published']) ) {
+ if (! $res || empty($res) || isset($res['error']) || ! isset($res['@context']) || ! isset($res['published'])) {
return;
}
- if(config('autospam.live_filters.enabled')) {
+ if (config('autospam.live_filters.enabled')) {
$filters = config('autospam.live_filters.filters');
- if(!empty($filters) && isset($res['content']) && !empty($res['content']) && strlen($filters) > 3) {
+ if (! empty($filters) && isset($res['content']) && ! empty($res['content']) && strlen($filters) > 3) {
$filters = array_map('trim', explode(',', $filters));
$content = $res['content'];
- foreach($filters as $filter) {
+ foreach ($filters as $filter) {
$filter = trim(strtolower($filter));
- if(!$filter || !strlen($filter)) {
+ if (! $filter || ! strlen($filter)) {
continue;
}
- if(str_contains(strtolower($content), $filter)) {
+ if (str_contains(strtolower($content), $filter)) {
return;
}
}
}
}
- if(isset($res['object'])) {
+ if (isset($res['object'])) {
$activity = $res;
} else {
$activity = ['object' => $res];
@@ -342,37 +335,37 @@ class Helpers {
$cw = isset($res['sensitive']) ? (bool) $res['sensitive'] : false;
- if(isset($res['to']) == true) {
- if(is_array($res['to']) && in_array('https://www.w3.org/ns/activitystreams#Public', $res['to'])) {
+ if (isset($res['to']) == true) {
+ if (is_array($res['to']) && in_array('https://www.w3.org/ns/activitystreams#Public', $res['to'])) {
$scope = 'public';
}
- if(is_string($res['to']) && 'https://www.w3.org/ns/activitystreams#Public' == $res['to']) {
+ if (is_string($res['to']) && $res['to'] == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'public';
}
}
- if(isset($res['cc']) == true) {
- if(is_array($res['cc']) && in_array('https://www.w3.org/ns/activitystreams#Public', $res['cc'])) {
+ if (isset($res['cc']) == true) {
+ if (is_array($res['cc']) && in_array('https://www.w3.org/ns/activitystreams#Public', $res['cc'])) {
$scope = 'unlisted';
}
- if(is_string($res['cc']) && 'https://www.w3.org/ns/activitystreams#Public' == $res['cc']) {
+ if (is_string($res['cc']) && $res['cc'] == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'unlisted';
}
}
- if(config('costar.enabled') == true) {
+ if (config('costar.enabled') == true) {
$blockedKeywords = config('costar.keyword.block');
- if($blockedKeywords !== null) {
+ if ($blockedKeywords !== null) {
$keywords = config('costar.keyword.block');
- foreach($keywords as $kw) {
- if(Str::contains($res['content'], $kw) == true) {
+ foreach ($keywords as $kw) {
+ if (Str::contains($res['content'], $kw) == true) {
return;
}
}
}
$unlisted = config('costar.domain.unlisted');
- if(in_array(parse_url($url, PHP_URL_HOST), $unlisted) == true) {
+ if (in_array(parse_url($url, PHP_URL_HOST), $unlisted) == true) {
$unlisted = true;
$scope = 'unlisted';
} else {
@@ -380,7 +373,7 @@ class Helpers {
}
$cwDomains = config('costar.domain.cw');
- if(in_array(parse_url($url, PHP_URL_HOST), $cwDomains) == true) {
+ if (in_array(parse_url($url, PHP_URL_HOST), $cwDomains) == true) {
$cw = true;
}
}
@@ -389,15 +382,15 @@ class Helpers {
$idDomain = parse_url($id, PHP_URL_HOST);
$urlDomain = parse_url($url, PHP_URL_HOST);
- if($idDomain && $urlDomain && strtolower($idDomain) !== strtolower($urlDomain)) {
+ if ($idDomain && $urlDomain && strtolower($idDomain) !== strtolower($urlDomain)) {
return;
}
- if(!self::validateUrl($id)) {
+ if (! self::validateUrl($id)) {
return;
}
- if(!isset($activity['object']['attributedTo'])) {
+ if (! isset($activity['object']['attributedTo'])) {
return;
}
@@ -405,39 +398,38 @@ class Helpers {
$activity['object']['attributedTo'] :
(is_array($activity['object']['attributedTo']) ?
collect($activity['object']['attributedTo'])
- ->filter(function($o) {
+ ->filter(function ($o) {
return $o && isset($o['type']) && $o['type'] == 'Person';
})
->pluck('id')
->first() : null
);
- if($attributedTo) {
+ if ($attributedTo) {
$actorDomain = parse_url($attributedTo, PHP_URL_HOST);
- if(!self::validateUrl($attributedTo) ||
+ if (! self::validateUrl($attributedTo) ||
$idDomain !== $actorDomain ||
$actorDomain !== $urlDomain
- )
- {
+ ) {
return;
}
}
- if($idDomain !== $urlDomain) {
+ if ($idDomain !== $urlDomain) {
return;
}
$profile = self::profileFirstOrNew($attributedTo);
- if(!$profile) {
+ if (! $profile) {
return;
}
- if(isset($activity['object']['inReplyTo']) && !empty($activity['object']['inReplyTo']) || $replyTo == true) {
+ if (isset($activity['object']['inReplyTo']) && ! empty($activity['object']['inReplyTo']) || $replyTo == true) {
$reply_to = self::statusFirstOrFetch(self::pluckval($activity['object']['inReplyTo']), false);
- if($reply_to) {
+ if ($reply_to) {
$blocks = UserFilterService::blocks($reply_to->profile_id);
- if(in_array($profile->id, $blocks)) {
+ if (in_array($profile->id, $blocks)) {
return;
}
}
@@ -447,15 +439,15 @@ class Helpers {
}
$ts = self::pluckval($res['published']);
- if($scope == 'public' && in_array($urlDomain, InstanceService::getUnlistedDomains())) {
+ if ($scope == 'public' && in_array($urlDomain, InstanceService::getUnlistedDomains())) {
$scope = 'unlisted';
}
- if(in_array($urlDomain, InstanceService::getNsfwDomains())) {
+ if (in_array($urlDomain, InstanceService::getNsfwDomains())) {
$cw = true;
}
- if($res['type'] === 'Question') {
+ if ($res['type'] === 'Question') {
$status = self::storePoll(
$profile,
$res,
@@ -466,6 +458,7 @@ class Helpers {
$scope,
$id
);
+
return $status;
} else {
$status = self::storeStatus($url, $profile, $res);
@@ -482,12 +475,12 @@ class Helpers {
$idDomain = parse_url($id, PHP_URL_HOST);
$urlDomain = parse_url($url, PHP_URL_HOST);
$originalUrlDomain = parse_url($originalUrl, PHP_URL_HOST);
- if(!self::validateUrl($id) || !self::validateUrl($url)) {
+ if (! self::validateUrl($id) || ! self::validateUrl($url)) {
return;
}
- if( strtolower($originalUrlDomain) !== strtolower($idDomain) ||
- strtolower($originalUrlDomain) !== strtolower($urlDomain) ) {
+ if (strtolower($originalUrlDomain) !== strtolower($idDomain) ||
+ strtolower($originalUrlDomain) !== strtolower($urlDomain)) {
return;
}
@@ -498,21 +491,21 @@ class Helpers {
$cw = self::getSensitive($activity, $url);
$pid = is_object($profile) ? $profile->id : (is_array($profile) ? $profile['id'] : null);
$isUnlisted = is_object($profile) ? $profile->unlisted : (is_array($profile) ? $profile['unlisted'] : false);
- $commentsDisabled = isset($activity['commentsEnabled']) ? !boolval($activity['commentsEnabled']) : false;
+ $commentsDisabled = isset($activity['commentsEnabled']) ? ! boolval($activity['commentsEnabled']) : false;
- if(!$pid) {
+ if (! $pid) {
return;
}
- if($scope == 'public') {
- if($isUnlisted == true) {
+ if ($scope == 'public') {
+ if ($isUnlisted == true) {
$scope = 'unlisted';
}
}
$status = Status::updateOrCreate(
[
- 'uri' => $url
+ 'uri' => $url,
], [
'profile_id' => $pid,
'url' => $url,
@@ -527,24 +520,24 @@ class Helpers {
'visibility' => $scope,
'cw_summary' => ($cw == true && isset($activity['summary']) ?
Purify::clean(strip_tags($activity['summary'])) : null),
- 'comments_disabled' => $commentsDisabled
+ 'comments_disabled' => $commentsDisabled,
]
);
- if($reply_to == null) {
+ if ($reply_to == null) {
self::importNoteAttachment($activity, $status);
} else {
- if(isset($activity['attachment']) && !empty($activity['attachment'])) {
+ if (isset($activity['attachment']) && ! empty($activity['attachment'])) {
self::importNoteAttachment($activity, $status);
}
StatusReplyPipeline::dispatch($status);
}
- if(isset($activity['tag']) && is_array($activity['tag']) && !empty($activity['tag'])) {
+ if (isset($activity['tag']) && is_array($activity['tag']) && ! empty($activity['tag'])) {
StatusTagsPipeline::dispatch($activity, $status);
}
- if( config('instance.timeline.network.cached') &&
+ if (config('instance.timeline.network.cached') &&
$status->in_reply_to_id === null &&
$status->reblog_of_id === null &&
in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) &&
@@ -556,8 +549,8 @@ class Helpers {
->unique()
->values()
->toArray();
- if(!in_array($urlDomain, $filteredDomains)) {
- if(!$isUnlisted) {
+ if (! in_array($urlDomain, $filteredDomains)) {
+ if (! $isUnlisted) {
NetworkTimelineService::add($status->id);
}
}
@@ -565,7 +558,7 @@ class Helpers {
AccountStatService::incrementPostCount($pid);
- if( $status->in_reply_to_id === null &&
+ if ($status->in_reply_to_id === null &&
in_array($status->type, ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
) {
FeedInsertRemotePipeline::dispatch($status->id, $pid)->onQueue('feed');
@@ -576,14 +569,14 @@ class Helpers {
public static function getSensitive($activity, $url)
{
- if(!$url || !strlen($url)) {
+ if (! $url || ! strlen($url)) {
return true;
}
$urlDomain = parse_url($url, PHP_URL_HOST);
$cw = isset($activity['sensitive']) ? (bool) $activity['sensitive'] : false;
- if(in_array($urlDomain, InstanceService::getNsfwDomains())) {
+ if (in_array($urlDomain, InstanceService::getNsfwDomains())) {
$cw = true;
}
@@ -593,13 +586,13 @@ class Helpers {
public static function getReplyTo($activity)
{
$reply_to = null;
- $inReplyTo = isset($activity['inReplyTo']) && !empty($activity['inReplyTo']) ?
+ $inReplyTo = isset($activity['inReplyTo']) && ! empty($activity['inReplyTo']) ?
self::pluckval($activity['inReplyTo']) :
false;
- if($inReplyTo) {
+ if ($inReplyTo) {
$reply_to = self::statusFirstOrFetch($inReplyTo);
- if($reply_to) {
+ if ($reply_to) {
$reply_to = optional($reply_to)->id;
}
} else {
@@ -616,25 +609,25 @@ class Helpers {
$urlDomain = parse_url(self::pluckval($url), PHP_URL_HOST);
$scope = 'private';
- if(isset($activity['to']) == true) {
- if(is_array($activity['to']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['to'])) {
+ if (isset($activity['to']) == true) {
+ if (is_array($activity['to']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['to'])) {
$scope = 'public';
}
- if(is_string($activity['to']) && 'https://www.w3.org/ns/activitystreams#Public' == $activity['to']) {
+ if (is_string($activity['to']) && $activity['to'] == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'public';
}
}
- if(isset($activity['cc']) == true) {
- if(is_array($activity['cc']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['cc'])) {
+ if (isset($activity['cc']) == true) {
+ if (is_array($activity['cc']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['cc'])) {
$scope = 'unlisted';
}
- if(is_string($activity['cc']) && 'https://www.w3.org/ns/activitystreams#Public' == $activity['cc']) {
+ if (is_string($activity['cc']) && $activity['cc'] == 'https://www.w3.org/ns/activitystreams#Public') {
$scope = 'unlisted';
}
}
- if($scope == 'public' && in_array($urlDomain, InstanceService::getUnlistedDomains())) {
+ if ($scope == 'public' && in_array($urlDomain, InstanceService::getUnlistedDomains())) {
$scope = 'unlisted';
}
@@ -643,15 +636,15 @@ class Helpers {
private static function storePoll($profile, $res, $url, $ts, $reply_to, $cw, $scope, $id)
{
- if(!isset($res['endTime']) || !isset($res['oneOf']) || !is_array($res['oneOf']) || count($res['oneOf']) > 4) {
+ if (! isset($res['endTime']) || ! isset($res['oneOf']) || ! is_array($res['oneOf']) || count($res['oneOf']) > 4) {
return;
}
- $options = collect($res['oneOf'])->map(function($option) {
+ $options = collect($res['oneOf'])->map(function ($option) {
return $option['name'];
})->toArray();
- $cachedTallies = collect($res['oneOf'])->map(function($option) {
+ $cachedTallies = collect($res['oneOf'])->map(function ($option) {
return $option['replies']['totalItems'] ?? 0;
})->toArray();
@@ -697,9 +690,10 @@ class Helpers {
public static function importNoteAttachment($data, Status $status)
{
- if(self::verifyAttachments($data) == false) {
+ if (self::verifyAttachments($data) == false) {
// \Log::info('importNoteAttachment::failedVerification.', [$data['id']]);
$status->viewType();
+
return;
}
$attachments = isset($data['object']) ? $data['object']['attachment'] : $data['attachment'];
@@ -712,11 +706,11 @@ class Helpers {
$storagePath = MediaPathService::get($user, 2);
$allowed = explode(',', config_cache('pixelfed.media_types'));
- foreach($attachments as $key => $media) {
+ foreach ($attachments as $key => $media) {
$type = $media['mediaType'];
$url = $media['url'];
$valid = self::validateUrl($url);
- if(in_array($type, $allowed) == false || $valid == false) {
+ if (in_array($type, $allowed) == false || $valid == false) {
continue;
}
$blurhash = isset($media['blurhash']) ? $media['blurhash'] : null;
@@ -735,50 +729,52 @@ class Helpers {
$media->remote_url = $url;
$media->caption = $caption;
$media->order = $key + 1;
- if($width) {
+ if ($width) {
$media->width = $width;
}
- if($height) {
+ if ($height) {
$media->height = $height;
}
- if($license) {
+ if ($license) {
$media->license = $license;
}
$media->mime = $type;
$media->version = 3;
$media->save();
- if(config_cache('pixelfed.cloud_storage') == true) {
+ if ((bool) config_cache('pixelfed.cloud_storage') == true) {
MediaStoragePipeline::dispatch($media);
}
}
$status->viewType();
- return;
+
}
public static function profileFirstOrNew($url)
{
$url = self::validateUrl($url);
- if($url == false) {
+ if ($url == false) {
return;
}
$host = parse_url($url, PHP_URL_HOST);
$local = config('pixelfed.domain.app') == $host ? true : false;
- if($local == true) {
+ if ($local == true) {
$id = last(explode('/', $url));
+
return Profile::whereNull('status')
->whereNull('domain')
->whereUsername($id)
->firstOrFail();
}
- if($profile = Profile::whereRemoteUrl($url)->first()) {
- if($profile->last_fetched_at && $profile->last_fetched_at->lt(now()->subHours(24))) {
+ if ($profile = Profile::whereRemoteUrl($url)->first()) {
+ if ($profile->last_fetched_at && $profile->last_fetched_at->lt(now()->subHours(24))) {
return self::profileUpdateOrCreate($url);
}
+
return $profile;
}
@@ -788,42 +784,42 @@ class Helpers {
public static function profileUpdateOrCreate($url)
{
$res = self::fetchProfileFromUrl($url);
- if(!$res || isset($res['id']) == false) {
+ if (! $res || isset($res['id']) == false) {
return;
}
$urlDomain = parse_url($url, PHP_URL_HOST);
$domain = parse_url($res['id'], PHP_URL_HOST);
- if(strtolower($urlDomain) !== strtolower($domain)) {
+ if (strtolower($urlDomain) !== strtolower($domain)) {
return;
}
- if(!isset($res['preferredUsername']) && !isset($res['nickname'])) {
+ if (! isset($res['preferredUsername']) && ! isset($res['nickname'])) {
return;
}
// skip invalid usernames
- if(!ctype_alnum($res['preferredUsername'])) {
+ if (! ctype_alnum($res['preferredUsername'])) {
$tmpUsername = str_replace(['_', '.', '-'], '', $res['preferredUsername']);
- if(!ctype_alnum($tmpUsername)) {
+ if (! ctype_alnum($tmpUsername)) {
return;
}
}
$username = (string) Purify::clean($res['preferredUsername'] ?? $res['nickname']);
- if(empty($username)) {
+ if (empty($username)) {
return;
}
$remoteUsername = $username;
$webfinger = "@{$username}@{$domain}";
- if(!self::validateUrl($res['inbox'])) {
+ if (! self::validateUrl($res['inbox'])) {
return;
}
- if(!self::validateUrl($res['id'])) {
+ if (! self::validateUrl($res['id'])) {
return;
}
$instance = Instance::updateOrCreate([
- 'domain' => $domain
+ 'domain' => $domain,
]);
- if($instance->wasRecentlyCreated == true) {
+ if ($instance->wasRecentlyCreated == true) {
\App\Jobs\InstancePipeline\FetchNodeinfoPipeline::dispatch($instance)->onQueue('low');
}
@@ -846,13 +842,14 @@ class Helpers {
]
);
- if( $profile->last_fetched_at == null ||
+ if ($profile->last_fetched_at == null ||
$profile->last_fetched_at->lt(now()->subMonths(3))
) {
RemoteAvatarFetch::dispatch($profile);
}
$profile->last_fetched_at = now();
$profile->save();
+
return $profile;
}
@@ -863,7 +860,7 @@ class Helpers {
public static function sendSignedObject($profile, $url, $body)
{
- if(app()->environment() !== 'production') {
+ if (app()->environment() !== 'production') {
return;
}
ActivityPubDeliveryService::queue()
diff --git a/app/Util/ActivityPub/Outbox.php b/app/Util/ActivityPub/Outbox.php
index 43adb36e3..aba34955e 100644
--- a/app/Util/ActivityPub/Outbox.php
+++ b/app/Util/ActivityPub/Outbox.php
@@ -2,34 +2,32 @@
namespace App\Util\ActivityPub;
-use App\Profile;
-use App\Status;
-use League\Fractal;
use App\Http\Controllers\ProfileController;
-use App\Transformer\ActivityPub\ProfileOutbox;
+use App\Status;
use App\Transformer\ActivityPub\Verb\CreateNote;
+use League\Fractal;
-class Outbox {
+class Outbox
+{
+ public static function get($profile)
+ {
+ abort_if(! (bool) config_cache('federation.activitypub.enabled'), 404);
+ abort_if(! config('federation.activitypub.outbox'), 404);
- public static function get($profile)
- {
- abort_if(!config_cache('federation.activitypub.enabled'), 404);
- abort_if(!config('federation.activitypub.outbox'), 404);
-
- if($profile->status != null) {
+ if ($profile->status != null) {
return ProfileController::accountCheck($profile);
}
- if($profile->is_private) {
- return ['error'=>'403', 'msg' => 'private profile'];
+ if ($profile->is_private) {
+ return ['error' => '403', 'msg' => 'private profile'];
}
$timeline = $profile
- ->statuses()
- ->whereScope('public')
- ->orderBy('created_at', 'desc')
- ->take(10)
- ->get();
+ ->statuses()
+ ->whereScope('public')
+ ->orderBy('created_at', 'desc')
+ ->take(10)
+ ->get();
$count = Status::whereProfileId($profile->id)->count();
@@ -38,14 +36,14 @@ class Outbox {
$res = $fractal->createData($resource)->toArray();
$outbox = [
- '@context' => 'https://www.w3.org/ns/activitystreams',
- '_debug' => 'Outbox only supports latest 10 objects, pagination is not supported',
- 'id' => $profile->permalink('/outbox'),
- 'type' => 'OrderedCollection',
- 'totalItems' => $count,
- 'orderedItems' => $res['data']
+ '@context' => 'https://www.w3.org/ns/activitystreams',
+ '_debug' => 'Outbox only supports latest 10 objects, pagination is not supported',
+ 'id' => $profile->permalink('/outbox'),
+ 'type' => 'OrderedCollection',
+ 'totalItems' => $count,
+ 'orderedItems' => $res['data'],
];
- return $outbox;
- }
+ return $outbox;
+ }
}
diff --git a/app/Util/Site/Config.php b/app/Util/Site/Config.php
index 02944defe..e661d82fe 100644
--- a/app/Util/Site/Config.php
+++ b/app/Util/Site/Config.php
@@ -30,16 +30,16 @@ class Config
'version' => config('pixelfed.version'),
'open_registration' => (bool) config_cache('pixelfed.open_registration'),
'uploader' => [
- 'max_photo_size' => (int) config('pixelfed.max_photo_size'),
+ 'max_photo_size' => (int) config_cache('pixelfed.max_photo_size'),
'max_caption_length' => (int) config_cache('pixelfed.max_caption_length'),
'max_altext_length' => (int) config_cache('pixelfed.max_altext_length', 150),
'album_limit' => (int) config_cache('pixelfed.max_album_length'),
'image_quality' => (int) config_cache('pixelfed.image_quality'),
- 'max_collection_length' => (int) config('pixelfed.max_collection_length', 18),
+ 'max_collection_length' => (int) config_cache('pixelfed.max_collection_length', 18),
- 'optimize_image' => (bool) config('pixelfed.optimize_image'),
- 'optimize_video' => (bool) config('pixelfed.optimize_video'),
+ 'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
+ 'optimize_video' => (bool) config_cache('pixelfed.optimize_video'),
'media_types' => config_cache('pixelfed.media_types'),
'mime_types' => config_cache('pixelfed.media_types') ? explode(',', config_cache('pixelfed.media_types')) : [],
diff --git a/database/migrations/2023_02_04_053028_fix_cloud_media_paths.php b/database/migrations/2023_02_04_053028_fix_cloud_media_paths.php
index b45ad7f80..31b16de1e 100644
--- a/database/migrations/2023_02_04_053028_fix_cloud_media_paths.php
+++ b/database/migrations/2023_02_04_053028_fix_cloud_media_paths.php
@@ -19,7 +19,7 @@ return new class extends Migration
public function up()
{
ini_set('memory_limit', '-1');
- if(config_cache('pixelfed.cloud_storage') == false) {
+ if((bool) config_cache('pixelfed.cloud_storage') == false) {
return;
}
diff --git a/public/css/admin.css b/public/css/admin.css
index 658de1dbc..54df3aa46 100644
Binary files a/public/css/admin.css and b/public/css/admin.css differ
diff --git a/public/css/spa.css b/public/css/spa.css
index fd4124d27..a88f8c257 100644
Binary files a/public/css/spa.css and b/public/css/spa.css differ
diff --git a/public/js/admin.js b/public/js/admin.js
index 4c442370f..44ec37600 100644
Binary files a/public/js/admin.js and b/public/js/admin.js differ
diff --git a/public/js/manifest.js b/public/js/manifest.js
index a61ead488..6eea38d8b 100644
Binary files a/public/js/manifest.js and b/public/js/manifest.js differ
diff --git a/public/js/profile.chunk.f74967e7910990ca.js b/public/js/profile.chunk.a2234f891ba86efd.js
similarity index 67%
rename from public/js/profile.chunk.f74967e7910990ca.js
rename to public/js/profile.chunk.a2234f891ba86efd.js
index 3792754dd..5103f5901 100644
Binary files a/public/js/profile.chunk.f74967e7910990ca.js and b/public/js/profile.chunk.a2234f891ba86efd.js differ
diff --git a/public/mix-manifest.json b/public/mix-manifest.json
index 1d908832a..121124a35 100644
Binary files a/public/mix-manifest.json and b/public/mix-manifest.json differ
diff --git a/resources/assets/components/Hashtag.vue b/resources/assets/components/Hashtag.vue
index e2ac77681..01094a85b 100644
--- a/resources/assets/components/Hashtag.vue
+++ b/resources/assets/components/Hashtag.vue
@@ -202,16 +202,12 @@
if(res.data && res.data.length) {
this.feed = res.data;
this.maxId = res.data[res.data.length - 1].id;
- return true;
+ this.canLoadMore = true;
} else {
this.feedLoaded = true;
this.isLoaded = true;
- return false;
}
})
- .then(res => {
- this.canLoadMore = res;
- })
.finally(() => {
this.feedLoaded = true;
this.isLoaded = true;
@@ -242,14 +238,11 @@
if(res.data && res.data.length) {
this.feed.push(...res.data);
this.maxId = res.data[res.data.length - 1].id;
- return true;
+ this.canLoadMore = true;
} else {
- return false;
+ this.canLoadMore = false;
}
})
- .then(res => {
- this.canLoadMore = res;
- })
.finally(() => {
this.isIntersecting = false;
})
diff --git a/resources/assets/components/admin/AdminInstances.vue b/resources/assets/components/admin/AdminInstances.vue
index e1c242d14..b0ecc098b 100644
--- a/resources/assets/components/admin/AdminInstances.vue
+++ b/resources/assets/components/admin/AdminInstances.vue
@@ -251,10 +251,11 @@
- Close
+ View More
diff --git a/resources/assets/components/admin/AdminSettings.vue b/resources/assets/components/admin/AdminSettings.vue
new file mode 100644
index 000000000..78ffd1b14
--- /dev/null
+++ b/resources/assets/components/admin/AdminSettings.vue
@@ -0,0 +1,1550 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Registration Status
+
+ Open - Anyone can register
+ Filtered - Anyone can apply (Curated Onboarding)
+ Closed - Nobody can register
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Admin Account
+
+ Select a designated admin
+ {{ acct.username }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Server Name
+
+
+
+ The instance name used in titles, metadata and apis.
+
+
+
+
+
+
+
+ Short Description
+
+
+
+ Short description of instance used on various pages and apis.
+
+
+
+
+
+ Long Description
+
+
+
+ Longer description of instance used on about page.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Maximum file upload size in KB
+
+
+
+
+
+
+
+
+
+
+ Supported mime types for media uploads
+
+
+
+
+
+
+ Photo Album Limit
+
+
+
+ The maximum number of photos or videos per album
+
+
+
+
+
+
+ Image Quality
+
+
+
+ Image optimization quality from 0-100%.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app_registration_rate_limit_attempts
+
+
+
+ app_registration_rate_limit_attempts.
+
+
+
+
+ app_registration_rate_limit_decay
+
+
+
+ app_registration_rate_limit_decay
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ hCaptcha Secret
+
+
+
+
+
+ hCaptcha Sitekey
+
+
+
+
+
+
+
+
+
+
+ Register Captcha
+
+
+
+
+
+
+ Enable hCaptcha on login and register pages
+
+
+
+
+
+
+ app_registration_confirm_rate_limit_attempts
+
+
+
+ app_registration_confirm_rate_limit_attempts.
+
+
+
+
+ app_registration_confirm_rate_limit_decay
+
+
+
+ app_registration_confirm_rate_limit_decay.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Max Caption Length
+
+
+
+ The maximum character count of post captions. We recommend a limit between 500-2000.
+
+
+
+
+
+
+
+ Max Alttext Length
+
+
+
+ The maximum character count of post media alttext captions. We recommend a limit between 2000-10000.
+
+
+
+
+
+
+
+
+
+
+
+
+
Duplicate rules detected, you should fix this!
+
+
+
+
+
+
+
+ Add New Rule
+
+
+
+
+ Add a new rule
+
+
+ {{ newRule && newRule.length ? newRule.length : 0 }}/1000
+
+
+
+
+ Add Rule
+
+
+
+
Delete all rules
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Primary Storage Disk
+
+ Local
+ Cloud/S3
+
+
+
+ The storage disk where avatars and media uploads are stored.
+
+
+
+
+
+
+
+
+
+
+
+ Disk
+
+ S3
+ DigitalOcean Spaces
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Maximum file storage limit per user account.
+
+
+
+
+
+
+
+
+
+
+
+
No autofollow accounts active.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/assets/components/admin/partial/AdminReadMore.vue b/resources/assets/components/admin/partial/AdminReadMore.vue
index 1a1b3d6ee..b5c1e47f2 100644
--- a/resources/assets/components/admin/partial/AdminReadMore.vue
+++ b/resources/assets/components/admin/partial/AdminReadMore.vue
@@ -1,7 +1,7 @@
diff --git a/resources/assets/components/admin/partial/AdminSettingsCheckbox.vue b/resources/assets/components/admin/partial/AdminSettingsCheckbox.vue
new file mode 100644
index 000000000..bb8cfec96
--- /dev/null
+++ b/resources/assets/components/admin/partial/AdminSettingsCheckbox.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
diff --git a/resources/assets/components/admin/partial/AdminSettingsInput.vue b/resources/assets/components/admin/partial/AdminSettingsInput.vue
new file mode 100644
index 000000000..25309134d
--- /dev/null
+++ b/resources/assets/components/admin/partial/AdminSettingsInput.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
diff --git a/resources/assets/components/admin/partial/AdminSettingsTabHeader.vue b/resources/assets/components/admin/partial/AdminSettingsTabHeader.vue
new file mode 100644
index 000000000..ac75d3f37
--- /dev/null
+++ b/resources/assets/components/admin/partial/AdminSettingsTabHeader.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
{{ title }}
+
+
+
+
+ {{ buttonLabel }}
+
+
+
+
+
+
+
+
diff --git a/resources/assets/js/admin.js b/resources/assets/js/admin.js
index 8d2b82ca1..e5a74d8e6 100644
--- a/resources/assets/js/admin.js
+++ b/resources/assets/js/admin.js
@@ -36,11 +36,21 @@ Vue.component(
require('./../components/admin/AdminReports.vue').default
);
+Vue.component(
+ 'admin-settings',
+ require('./../components/admin/AdminSettings.vue').default
+);
+
Vue.component(
'instances-component',
require('./../components/admin/AdminInstances.vue').default
);
+// Vue.component(
+// 'instance-details-component',
+// require('./../components/admin/AdminInstanceDetails.vue').default
+// );
+
Vue.component(
'hashtag-component',
require('./../components/admin/AdminHashtags.vue').default
diff --git a/resources/assets/sass/lib/nucleo.css b/resources/assets/sass/lib/nucleo.css
index b03698950..4171a5523 100644
--- a/resources/assets/sass/lib/nucleo.css
+++ b/resources/assets/sass/lib/nucleo.css
@@ -10,6 +10,7 @@ License - nucleoapp.com/license/
src: url('/fonts/nucleo-icons.eot') format('embedded-opentype'), url('/fonts/nucleo-icons.woff2') format('woff2'), url('/fonts/nucleo-icons.woff') format('woff'), url('/fonts/nucleo-icons.ttf') format('truetype'), url('/fonts/nucleo-icons.svg') format('svg');
font-weight: normal;
font-style: normal;
+ font-display: swap;
}
/*------------------------
base class definition
diff --git a/resources/assets/sass/spa.scss b/resources/assets/sass/spa.scss
index 72e08e16b..5b36b6ed1 100644
--- a/resources/assets/sass/spa.scss
+++ b/resources/assets/sass/spa.scss
@@ -392,6 +392,10 @@ span.twitter-typeahead .tt-suggestion:focus {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
+.timestamp-overlay-badge {
+ color: var(--dark);
+}
+
.timeline-status-component {
.username {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
diff --git a/resources/views/account/moderation/post/autospam.blade.php b/resources/views/account/moderation/post/autospam.blade.php
index 91296759d..d16d85f3e 100644
--- a/resources/views/account/moderation/post/autospam.blade.php
+++ b/resources/views/account/moderation/post/autospam.blade.php
@@ -69,7 +69,7 @@
Review the Community Guidelines
-
We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
+
We want to keep {{config_cache('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
@@ -100,4 +100,4 @@
ctx.putImageData(imageData, 0, 0);
@endif
-@endpush
\ No newline at end of file
+@endpush
diff --git a/resources/views/account/moderation/post/cw.blade.php b/resources/views/account/moderation/post/cw.blade.php
index d1e1d3537..bffa7a186 100644
--- a/resources/views/account/moderation/post/cw.blade.php
+++ b/resources/views/account/moderation/post/cw.blade.php
@@ -70,7 +70,7 @@
Review the Community Guidelines
-
We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
+
We want to keep {{config_cache('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
@@ -127,4 +127,4 @@
ctx.putImageData(imageData, 0, 0);
@endif
-@endpush
\ No newline at end of file
+@endpush
diff --git a/resources/views/account/moderation/post/removed.blade.php b/resources/views/account/moderation/post/removed.blade.php
index 123863489..4b8a1fee4 100644
--- a/resources/views/account/moderation/post/removed.blade.php
+++ b/resources/views/account/moderation/post/removed.blade.php
@@ -62,7 +62,7 @@
Review the Community Guidelines
-
We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
+
We want to keep {{config_cache('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
@@ -96,4 +96,4 @@
ctx.putImageData(imageData, 0, 0);
@endif
-@endpush
\ No newline at end of file
+@endpush
diff --git a/resources/views/account/moderation/post/unlist.blade.php b/resources/views/account/moderation/post/unlist.blade.php
index 3c86acb76..4f62a10bb 100644
--- a/resources/views/account/moderation/post/unlist.blade.php
+++ b/resources/views/account/moderation/post/unlist.blade.php
@@ -69,7 +69,7 @@
Review the Community Guidelines
-
We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
+
We want to keep {{config_cache('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.
@@ -125,4 +125,4 @@
ctx.putImageData(imageData, 0, 0);
@endif
-@endpush
\ No newline at end of file
+@endpush
diff --git a/resources/views/admin/diagnostics/home.blade.php b/resources/views/admin/diagnostics/home.blade.php
index db44a2332..b23652b51 100644
--- a/resources/views/admin/diagnostics/home.blade.php
+++ b/resources/views/admin/diagnostics/home.blade.php
@@ -66,7 +66,7 @@
OAUTH enabled:
- {{ config_cache('pixelfed.oauth_enabled') ? '✅ true' : '❌ false' }}
+ {{ (bool) config_cache('pixelfed.oauth_enabled') ? '✅ true' : '❌ false' }}
OAUTH token_expiration
@@ -298,7 +298,7 @@
FEDERATION
ACTIVITY_PUB
- {{config_cache('federation.activitypub.enabled') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('federation.activitypub.enabled') ? '✅ true' : '❌ false' }}
FEDERATION
@@ -358,7 +358,7 @@
FEDERATION
PF_NETWORK_TIMELINE
- {{config_cache('federation.network_timeline') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('federation.network_timeline') ? '✅ true' : '❌ false' }}
FEDERATION
@@ -368,7 +368,7 @@
FEDERATION
CUSTOM_EMOJI
- {{config_cache('federation.custom_emoji.enabled') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('federation.custom_emoji.enabled') ? '✅ true' : '❌ false' }}
FEDERATION
@@ -545,7 +545,7 @@
INSTANCE
STORIES_ENABLED
- {{config_cache('instance.stories.enabled') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('instance.stories.enabled') ? '✅ true' : '❌ false' }}
INSTANCE
@@ -740,7 +740,7 @@
PIXELFED
PF_ENABLE_CLOUD
- {{config_cache('pixelfed.cloud_storage') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('pixelfed.cloud_storage') ? '✅ true' : '❌ false' }}
PIXELFED
@@ -750,12 +750,12 @@
PIXELFED
PF_OPTIMIZE_IMAGES
- {{config_cache('pixelfed.optimize_image') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('pixelfed.optimize_image') ? '✅ true' : '❌ false' }}
PIXELFED
PF_OPTIMIZE_VIDEOS
- {{config_cache('pixelfed.optimize_video') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('pixelfed.optimize_video') ? '✅ true' : '❌ false' }}
PIXELFED
@@ -810,12 +810,12 @@
PIXELFED
OAUTH_ENABLED
- {{config_cache('pixelfed.oauth_enabled') ? '✅ true' : '❌ false' }}
+ {{ (bool) config_cache('pixelfed.oauth_enabled') ? '✅ true' : '❌ false' }}
PIXELFED
PF_BOUNCER_ENABLED
- {{config_cache('pixelfed.bouncer.enabled') ? '✅ true' : '❌ false' }}
+ {{(bool) config_cache('pixelfed.bouncer.enabled') ? '✅ true' : '❌ false' }}
PIXELFED
diff --git a/resources/views/admin/settings/home.blade.php b/resources/views/admin/settings/home.blade.php
index c2254f700..d78780878 100644
--- a/resources/views/admin/settings/home.blade.php
+++ b/resources/views/admin/settings/home.blade.php
@@ -1,421 +1,12 @@
@extends('admin.partial.template-full')
@section('section')
-
-
Settings
-@if(config('instance.enable_cc'))
-
Manage instance settings
-
-@else
-
-
-
Not enabled
-
Add ENABLE_CONFIG_CACHE=true
in your .env file and run php artisan config:cache
-
-@endif
+
@endsection
@push('scripts')
@endpush
diff --git a/resources/views/auth/email/forgot.blade.php b/resources/views/auth/email/forgot.blade.php
index 898d19fb5..e4b67d792 100644
--- a/resources/views/auth/email/forgot.blade.php
+++ b/resources/views/auth/email/forgot.blade.php
@@ -65,7 +65,7 @@
- @if(config('captcha.enabled') || config('captcha.active.login') || config('captcha.active.register'))
+ @if((bool) config_cache('captcha.enabled'))
Captcha
{!! Captcha::display(['data-theme' => 'dark']) !!}
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php
index 9df9ea8c9..0f77f778e 100644
--- a/resources/views/auth/login.blade.php
+++ b/resources/views/auth/login.blade.php
@@ -76,10 +76,10 @@
@if(
- config('captcha.enabled') ||
- config('captcha.active.login') ||
+ (bool) config_cache('captcha.enabled') &&
+ (bool) config_cache('captcha.active.login') ||
(
- config('captcha.triggers.login.enabled') &&
+ (bool) config_cache('captcha.triggers.login.enabled') &&
request()->session()->has('login_attempts') &&
request()->session()->get('login_attempts') >= config('captcha.triggers.login.attempts')
)
diff --git a/resources/views/auth/passwords/email.blade.php b/resources/views/auth/passwords/email.blade.php
index 4f2825e29..19461fa29 100644
--- a/resources/views/auth/passwords/email.blade.php
+++ b/resources/views/auth/passwords/email.blade.php
@@ -54,7 +54,7 @@
- @if(config('captcha.enabled'))
+ @if((bool) config_cache('captcha.enabled'))
Captcha
{!! Captcha::display(['data-theme' => 'dark']) !!}
diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php
index 1a740fa7d..ecabcaddf 100644
--- a/resources/views/auth/passwords/reset.blade.php
+++ b/resources/views/auth/passwords/reset.blade.php
@@ -109,7 +109,7 @@
- @if(config('captcha.enabled'))
+ @if((bool) config_cache('captcha.enabled'))
Captcha
{!! Captcha::display(['data-theme' => 'dark']) !!}
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php
index a2c008bd7..3cb70c7fe 100644
--- a/resources/views/auth/register.blade.php
+++ b/resources/views/auth/register.blade.php
@@ -81,7 +81,7 @@
- @if(config('captcha.enabled') || config('captcha.active.register'))
+ @if((bool) config_cache('captcha.enabled') && (bool) config_cache('captcha.active.register'))
{!! Captcha::display() !!}
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
index 2f7b05cd3..e5aed6dad 100644
--- a/resources/views/home.blade.php
+++ b/resources/views/home.blade.php
@@ -1,4 +1,4 @@
-@extends('layouts.app',['title' => 'Welcome to ' . config('app.name')])
+@extends('layouts.app',['title' => 'Welcome to ' . config_cache('app.name')])
@section('content')
@@ -14,7 +14,7 @@
@endif
- Welcome to {{config('app.name')}}!
+ Welcome to {{config_cache('app.name')}}!
diff --git a/resources/views/layouts/app-guest.blade.php b/resources/views/layouts/app-guest.blade.php
index 6adcffac4..7d8dbd201 100644
--- a/resources/views/layouts/app-guest.blade.php
+++ b/resources/views/layouts/app-guest.blade.php
@@ -5,11 +5,11 @@
- {{ $title ?? config('app.name', 'Pixelfed') }}
+ {{ $title ?? config_cache('app.name', 'Pixelfed') }}
-
-
+
+
@stack('meta')
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
index 0136842bb..168992aaf 100644
--- a/resources/views/layouts/app.blade.php
+++ b/resources/views/layouts/app.blade.php
@@ -70,11 +70,11 @@
- {{ $title ?? config('app.name', 'Pixelfed') }}
+ {{ $title ?? config_cache('app.name', 'Pixelfed') }}
-
+
@stack('meta')
diff --git a/resources/views/layouts/blank.blade.php b/resources/views/layouts/blank.blade.php
index 00042315d..deaf71d62 100644
--- a/resources/views/layouts/blank.blade.php
+++ b/resources/views/layouts/blank.blade.php
@@ -11,8 +11,8 @@
{{ $title ?? config_cache('app.name') }}
-
-
+
+
@stack('meta')
diff --git a/resources/views/layouts/bundle.blade.php b/resources/views/layouts/bundle.blade.php
index 1050a39d6..94e0c2c00 100644
--- a/resources/views/layouts/bundle.blade.php
+++ b/resources/views/layouts/bundle.blade.php
@@ -9,11 +9,11 @@
- {{ $title ?? config('app.name', 'Laravel') }}
+ {{ $title ?? config_cache('app.name', 'Pixelfed') }}
-
-
+
+
@stack('meta')
diff --git a/resources/views/layouts/partial/nav.blade.php b/resources/views/layouts/partial/nav.blade.php
index 1d89902bf..56fe7da4a 100644
--- a/resources/views/layouts/partial/nav.blade.php
+++ b/resources/views/layouts/partial/nav.blade.php
@@ -105,7 +105,7 @@
{{__('navmenu.discover')}}
- @if(config_cache('instance.stories.enabled'))
+ @if((bool) config_cache('instance.stories.enabled'))
diff --git a/resources/views/layouts/partial/noauthnav.blade.php b/resources/views/layouts/partial/noauthnav.blade.php
index 465b51354..004c8497f 100644
--- a/resources/views/layouts/partial/noauthnav.blade.php
+++ b/resources/views/layouts/partial/noauthnav.blade.php
@@ -2,7 +2,7 @@
diff --git a/resources/views/portfolio/layout.blade.php b/resources/views/portfolio/layout.blade.php
index 14158fb37..89e909284 100644
--- a/resources/views/portfolio/layout.blade.php
+++ b/resources/views/portfolio/layout.blade.php
@@ -11,8 +11,8 @@
{!! $title ?? config_cache('app.name') !!}
-
-
+
+
@stack('meta')
diff --git a/resources/views/profile/embed-removed.blade.php b/resources/views/profile/embed-removed.blade.php
index 7a49d2e79..c236eb790 100644
--- a/resources/views/profile/embed-removed.blade.php
+++ b/resources/views/profile/embed-removed.blade.php
@@ -9,8 +9,8 @@
Pixelfed | 404 Embed Not Found
-
-
+
+
diff --git a/resources/views/profile/embed.blade.php b/resources/views/profile/embed.blade.php
index cc6097e3a..aeb6a5b99 100644
--- a/resources/views/profile/embed.blade.php
+++ b/resources/views/profile/embed.blade.php
@@ -9,8 +9,8 @@
{{ $title ?? config('app.name', 'Pixelfed') }}
-
-
+
+
diff --git a/resources/views/profile/private.blade.php b/resources/views/profile/private.blade.php
index ffff37d49..118ef643e 100644
--- a/resources/views/profile/private.blade.php
+++ b/resources/views/profile/private.blade.php
@@ -1,4 +1,4 @@
-@extends('layouts.app-guest',['title' => $user->username . " on " . config('app.name')])
+@extends('layouts.app-guest',['title' => $user->username . " on " . config_cache('app.name')])
@section('content')
@if (session('error'))
diff --git a/resources/views/settings/applications.blade.php b/resources/views/settings/applications.blade.php
index 691ab0c81..97270fb62 100644
--- a/resources/views/settings/applications.blade.php
+++ b/resources/views/settings/applications.blade.php
@@ -6,7 +6,7 @@
Applications
-@if(config_cache('pixelfed.oauth_enabled') == true)
+@if((bool) config_cache('pixelfed.oauth_enabled') == true)
@else
diff --git a/resources/views/settings/developers.blade.php b/resources/views/settings/developers.blade.php
index 8b4c94471..22d869580 100644
--- a/resources/views/settings/developers.blade.php
+++ b/resources/views/settings/developers.blade.php
@@ -6,7 +6,7 @@
Developers
-@if(config_cache('pixelfed.oauth_enabled') == true)
+@if((bool) config_cache('pixelfed.oauth_enabled') == true)
@else
OAuth has not been enabled on this instance.
diff --git a/resources/views/settings/parental-controls/invite-register-form.blade.php b/resources/views/settings/parental-controls/invite-register-form.blade.php
index 5b894e8d2..a21808efa 100644
--- a/resources/views/settings/parental-controls/invite-register-form.blade.php
+++ b/resources/views/settings/parental-controls/invite-register-form.blade.php
@@ -91,7 +91,7 @@
- @if(config('captcha.enabled') || config('captcha.active.register'))
+ @if((bool) config_cache('captcha.enabled'))
{!! Captcha::display() !!}
diff --git a/resources/views/settings/partial/sidebar.blade.php b/resources/views/settings/partial/sidebar.blade.php
index b971e1f5d..0eadb9773 100644
--- a/resources/views/settings/partial/sidebar.blade.php
+++ b/resources/views/settings/partial/sidebar.blade.php
@@ -39,7 +39,7 @@
- @if(config_cache('pixelfed.oauth_enabled') == true)
+ @if((bool) config_cache('pixelfed.oauth_enabled') == true)
Applications
diff --git a/resources/views/site/index.blade.php b/resources/views/site/index.blade.php
index e6753a727..b7d3befaa 100644
--- a/resources/views/site/index.blade.php
+++ b/resources/views/site/index.blade.php
@@ -8,7 +8,7 @@
- {{ config('app.name', 'Pixelfed') }}
+ {{ config_cache('app.name', 'Pixelfed') }}
diff --git a/resources/views/status/embed-removed.blade.php b/resources/views/status/embed-removed.blade.php
index e5f94525b..b9f0a2df6 100644
--- a/resources/views/status/embed-removed.blade.php
+++ b/resources/views/status/embed-removed.blade.php
@@ -9,8 +9,8 @@
Pixelfed | 404 Embed Not Found
-
-
+
+
diff --git a/resources/views/vendor/mail/html/message.blade.php b/resources/views/vendor/mail/html/message.blade.php
index deec4a1f4..26c1f7d80 100644
--- a/resources/views/vendor/mail/html/message.blade.php
+++ b/resources/views/vendor/mail/html/message.blade.php
@@ -2,7 +2,7 @@
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
-{{ config('app.name') }}
+{{ config_cache('app.name') }}
@endcomponent
@endslot
@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
-© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
+© {{ date('Y') }} {{ config_cache('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent
diff --git a/resources/views/vendor/mail/text/message.blade.php b/resources/views/vendor/mail/text/message.blade.php
index 1ae9ed8f1..3416a9bd4 100644
--- a/resources/views/vendor/mail/text/message.blade.php
+++ b/resources/views/vendor/mail/text/message.blade.php
@@ -2,7 +2,7 @@
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
- {{ config('app.name') }}
+ {{ config_cache('app.name') }}
@endcomponent
@endslot
@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
- © {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
+ © {{ date('Y') }} {{ config_cache('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent
diff --git a/resources/views/vendor/passport/authorize.blade.php b/resources/views/vendor/passport/authorize.blade.php
index 986f76801..a644289ca 100644
--- a/resources/views/vendor/passport/authorize.blade.php
+++ b/resources/views/vendor/passport/authorize.blade.php
@@ -4,7 +4,7 @@
- {{ config('app.name') }} - Authorization
+ {{ config_cache('app.name') }} - Authorization