Merge pull request #6326 from pixelfed/staging

Staging
pull/6335/head
dansup 4 days ago committed by GitHub
commit 82a82ec3e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -13,7 +13,20 @@ class Installer extends Command
*
* @var string
*/
protected $signature = 'install {--dangerously-overwrite-env : Re-run installation and overwrite current .env }';
protected $signature = 'install
{--dangerously-overwrite-env : Re-run installation and overwrite current .env}
{--domain= : Pre-fill site domain}
{--name= : Pre-fill site name}
{--email= : Pre-fill admin email}
{--db-driver= : Pre-fill database driver (mysql/pgsql)}
{--db-host= : Pre-fill database host}
{--db-port= : Pre-fill database port}
{--db-database= : Pre-fill database name}
{--db-username= : Pre-fill database username}
{--db-password= : Pre-fill database password}
{--redis-host= : Pre-fill Redis host}
{--redis-port= : Pre-fill Redis port}
{--redis-password= : Pre-fill Redis password}';
/**
* The console command description.
@ -22,8 +35,7 @@ class Installer extends Command
*/
protected $description = 'CLI Installer';
public $installType = 'Simple';
public $continue;
protected $migrationsRan = false;
/**
* Create a new command instance.
@ -65,38 +77,22 @@ class Installer extends Command
{
$this->envCheck();
$this->envCreate();
$this->installType();
if ($this->installType === 'Advanced') {
$this->info('Installer: Advanced...');
$this->checkPHPRequiredDependencies();
$this->checkFFmpegDependencies();
$this->checkOptimiseDependencies();
$this->checkDiskPermissions();
$this->envProd();
$this->instanceDB();
$this->instanceRedis();
$this->instanceURL();
$this->activityPubSettings();
$this->laravelSettings();
$this->instanceSettings();
$this->mediaSettings();
$this->dbMigrations();
$this->validateEnv();
$this->resetArtisanCache();
} else {
$this->info('Installer: Simple...');
$this->checkDiskPermissions();
$this->envProd();
$this->instanceDB();
$this->instanceRedis();
$this->instanceURL();
$this->activityPubSettings();
$this->instanceSettings();
$this->dbMigrations();
$this->validateEnv();
$this->resetArtisanCache();
}
$this->checkPHPRequiredDependencies();
$this->checkFFmpegDependencies();
$this->checkOptimiseDependencies();
$this->checkDiskPermissions();
$this->envProd();
$this->instanceDB();
$this->instanceRedis();
$this->instanceURL();
$this->activityPubSettings();
$this->laravelSettings();
$this->instanceSettings();
$this->mediaSettings();
$this->dbMigrations();
$this->setupPrep();
$this->validateEnv();
$this->resetArtisanCache();
}
protected function envCheck()
@ -118,16 +114,10 @@ class Installer extends Command
$this->line('');
$this->info('Creating .env if required');
if (!file_exists(app()->environmentFilePath())) {
exec('cp .env.example .env');
copy(base_path('.env.example'), app()->environmentFilePath());
}
}
protected function installType()
{
$type = $this->choice('Select installation type', ['Simple', 'Advanced'], 1);
$this->installType = $type;
}
protected function checkPHPRequiredDependencies()
{
$this->line(' ');
@ -145,21 +135,25 @@ class Installer extends Command
'xml',
'zip',
'redis',
'vips',
];
$missing = [];
foreach ($extensions as $ext) {
if (extension_loaded($ext) == false) {
$this->error("- \"{$ext}\" not found");
$missing[] = $ext;
} else {
$this->info("- \"{$ext}\" found");
}
}
$continue = $this->choice('Do you wish to continue?', ['yes', 'no'], 0);
$this->continue = $continue;
if ($this->continue === 'no') {
$this->info('Exiting Installer.');
exit;
if (!empty($missing)) {
$continue = $this->choice('Some extensions are missing. Do you wish to continue?', ['yes', 'no'], 1);
if ($continue === 'no') {
$this->info('Exiting Installer.');
return 1;
}
}
}
@ -167,12 +161,17 @@ class Installer extends Command
protected function checkFFmpegDependencies()
{
$this->line(' ');
$this->info('Checking for Required FFmpeg dependencies...');
$this->info('Checking for FFmpeg (required for video processing)...');
$ffmpeg = exec('which ffmpeg');
if (empty($ffmpeg)) {
$this->error('- FFmpeg not found, aborting installation');
exit;
$this->warn('- FFmpeg not found');
$this->warn(' Video uploads will not work without FFmpeg');
$continue = $this->choice('Do you want to continue without FFmpeg?', ['yes', 'no'], 1);
if ($continue === 'no') {
$this->info('Exiting Installer. Please install FFmpeg and try again.');
return 1;
}
} else {
$this->info('- Found FFmpeg!');
}
@ -212,7 +211,7 @@ class Installer extends Command
];
foreach ($paths as $path) {
if (is_writeable($path) == false) {
if (is_writable($path) == false) {
$this->error("- Invalid permission found! Aborting installation.");
$this->error(" Please make the following path writeable by the web server:");
$this->error(" $path");
@ -237,14 +236,15 @@ class Installer extends Command
{
$this->line('');
$this->info('Database Settings:');
$database = $this->choice('Select database driver', ['mysql', 'pgsql'], 0);
$database_host = $this->ask('Select database host', '127.0.0.1');
$database = $this->choice('Select database driver', ['mysql', 'pgsql'], $this->option('db-driver') ?: 0);
$database_host = $this->ask('Select database host', $this->option('db-host') ?: '127.0.0.1');
$database_port_default = $database === 'mysql' ? 3306 : 5432;
$database_port = $this->ask('Select database port', $database_port_default);
$database_port = $this->ask('Select database port', $this->option('db-port') ?: $database_port_default);
$database_db = $this->ask('Select database', 'pixelfed');
$database_username = $this->ask('Select database username', 'pixelfed');
$database_password = $this->secret('Select database password');
$database_db = $this->ask('Select database', $this->option('db-database') ?: 'pixelfed');
$database_username = $this->ask('Select database username', $this->option('db-username') ?: 'pixelfed');
$database_password = $this->ask('Select database password', $this->option('db-password') ?: null);
$this->updateEnvFile('DB_CONNECTION', $database);
$this->updateEnvFile('DB_HOST', $database_host);
@ -257,8 +257,10 @@ class Installer extends Command
$dsn = "{$database}:dbname={$database_db};host={$database_host};port={$database_port};";
try {
$dbh = new PDO($dsn, $database_username, $database_password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$dbh = null; // Close connection
} catch (\PDOException $e) {
$this->error('Cannot connect to database, check your details and try again');
$this->error('Error: ' . $e->getMessage());
exit;
}
$this->info('- Connected to DB Successfully');
@ -269,22 +271,29 @@ class Installer extends Command
$this->line('');
$this->info('Redis Settings:');
$redis_client = $this->choice('Set redis client (PHP extension)', ['phpredis', 'predis'], 0);
$redis_host = $this->ask('Set redis host', 'localhost');
$redis_password = $this->ask('Set redis password', 'null');
$redis_port = $this->ask('Set redis port', 6379);
$redis_host = $this->ask('Set redis host', $this->option('redis-host') ?: 'localhost');
$redis_password = $this->ask('Set redis password (leave empty for none)', $this->option('redis-password') ?? '');
$redis_port = $this->ask('Set redis port', $this->option('redis-port') ?: 6379);
$this->updateEnvFile('REDIS_CLIENT', $redis_client);
$this->updateEnvFile('REDIS_SCHEME', 'tcp');
$this->updateEnvFile('REDIS_HOST', $redis_host);
$this->updateEnvFile('REDIS_PASSWORD', $redis_password);
$this->updateEnvFile('REDIS_PASSWORD', empty($redis_password) ? 'null' : $redis_password);
$this->updateEnvFile('REDIS_PORT', $redis_port);
$this->info('Testing Redis...');
$redis = Redis::connection();
if ($redis->ping()) {
$this->info('- Connected to Redis Successfully!');
} else {
$this->call('config:clear');
try {
$redis = Redis::connection();
if ($redis->ping()) {
$this->info('- Connected to Redis Successfully!');
} else {
$this->error('Cannot connect to Redis, check your details and try again');
exit;
}
} catch (\Exception $e) {
$this->error('Cannot connect to Redis, check your details and try again');
$this->error('Error: ' . $e->getMessage());
exit;
}
}
@ -293,21 +302,30 @@ class Installer extends Command
{
$this->line('');
$this->info('Instance URL Settings:');
$name = $this->ask('Site name [ex: Pixelfed]', 'Pixelfed');
$domain = $this->ask('Site Domain [ex: pixelfed.com]');
$domain = strtolower($domain);
if (empty($domain)) {
$this->error('You must set the site domain');
exit;
}
if (starts_with($domain, 'http')) {
$this->error('The site domain cannot start with https://, you must use the FQDN (eg: example.org)');
exit;
}
if (strpos($domain, '.') == false) {
$this->error('You must enter a valid site domain');
exit;
$name = $this->ask('Site name [ex: Pixelfed]', $this->option('name') ?: 'Pixelfed');
$domain = '';
while (empty($domain)) {
$domain = $this->ask('Site Domain [ex: pixelfed.com]', $this->option('domain') ?: null);
$domain = strtolower(trim($domain));
if (empty($domain)) {
$this->error('You must set the site domain');
continue;
}
if (str_starts_with($domain, 'http://') || str_starts_with($domain, 'https://')) {
$this->error('The site domain cannot start with http:// or https://, you must use the FQDN (eg: example.org)');
$domain = '';
continue;
}
// Better domain validation
if (!preg_match('/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i', $domain)) {
$this->error('Invalid domain format. Please enter a valid domain (eg: example.org)');
$domain = '';
continue;
}
}
$this->updateEnvFile('APP_NAME', $name);
@ -317,6 +335,19 @@ class Installer extends Command
$this->updateEnvFile('SESSION_DOMAIN', $domain);
}
protected function activityPubSettings()
{
$this->line('');
$this->info('Federation Settings:');
$activitypub_federation = $this->choice('Enable ActivityPub federation?', ['false', 'true'], 1);
$this->updateEnvFile('ACTIVITY_PUB', $activitypub_federation);
$this->updateEnvFile('AP_REMOTE_FOLLOW', $activitypub_federation);
$this->updateEnvFile('AP_INBOX', $activitypub_federation);
$this->updateEnvFile('AP_OUTBOX', $activitypub_federation);
$this->updateEnvFile('AP_SHAREDINBOX', $activitypub_federation);
}
protected function laravelSettings()
{
$this->line('');
@ -340,7 +371,15 @@ class Installer extends Command
{
$this->line('');
$this->info('Instance Settings:');
$max_registration = $this->ask('Set Maximum users on this instance.', '1000');
$max_registration = '';
while (!is_numeric($max_registration) || $max_registration < 1) {
$max_registration = $this->ask('Set Maximum users on this instance', '1000');
if (!is_numeric($max_registration) || $max_registration < 1) {
$this->error('Please enter a valid number greater than 0');
}
}
$open_registration = $this->choice('Allow new registrations?', ['false', 'true'], 0);
$enforce_email_verification = $this->choice('Enforce email verification?', ['false', 'true'], 0);
$enable_mobile_apis = $this->choice('Enable mobile app/apis support?', ['false', 'true'], 1);
@ -352,50 +391,43 @@ class Installer extends Command
$this->updateEnvFile('EXP_EMC', $enable_mobile_apis);
}
protected function activityPubSettings()
{
$this->line('');
$this->info('Federation Settings:');
$activitypub_federation = $this->choice('Enable ActivityPub federation?', ['false', 'true'], 1);
$this->updateEnvFile('ACTIVITY_PUB', $activitypub_federation);
$this->updateEnvFile('AP_REMOTE_FOLLOW', $activitypub_federation);
$this->updateEnvFile('AP_INBOX', $activitypub_federation);
$this->updateEnvFile('AP_OUTBOX', $activitypub_federation);
$this->updateEnvFile('AP_SHAREDINBOX', $activitypub_federation);
}
protected function mediaSettings()
{
$this->line('');
$this->info('Media Settings:');
$optimize_media = $this->choice('Optimize media uploads? Requires jpegoptim and other dependencies!', ['false', 'true'], 1);
$image_quality = $this->ask('Set image optimization quality between 1-100. Default is 80%, lower values use less disk space at the expense of image quality.', '80');
if ($image_quality < 1) {
$this->error('Min image quality is 1. You should avoid such a low value, 60 at minimum is recommended.');
exit;
}
if ($image_quality > 100) {
$this->error('Max image quality is 100');
exit;
$image_quality = '';
while (!is_numeric($image_quality) || $image_quality < 1 || $image_quality > 100) {
$image_quality = $this->ask('Set image optimization quality between 1-100 (default: 80)', '80');
if (!is_numeric($image_quality) || $image_quality < 1 || $image_quality > 100) {
$this->error('Please enter a number between 1 and 100');
}
}
$this->info('Note: Max photo size cannot exceed `post_max_size` in php.ini.');
$max_photo_size = $this->ask('Max photo upload size in kilobytes. Default 15000 which is equal to 15MB', '15000');
$max_caption_length = $this->ask('Max caption limit. Default to 500, max 5000.', '500');
if ($max_caption_length > 5000) {
$this->error('Max caption length is 5000 characters.');
exit;
$max_photo_size = '';
while (!is_numeric($max_photo_size) || $max_photo_size < 1) {
$max_photo_size = $this->ask('Max photo upload size in kilobytes (default: 15000 = 15MB)', '15000');
if (!is_numeric($max_photo_size) || $max_photo_size < 1) {
$this->error('Please enter a valid number greater than 0');
}
}
$max_album_length = $this->ask('Max photos allowed per album. Choose a value between 1 and 10.', '4');
if ($max_album_length < 1) {
$this->error('Min album length is 1 photos per album.');
exit;
$max_caption_length = '';
while (!is_numeric($max_caption_length) || $max_caption_length < 1 || $max_caption_length > 5000) {
$max_caption_length = $this->ask('Max caption limit (1-5000, default: 500)', '500');
if (!is_numeric($max_caption_length) || $max_caption_length < 1 || $max_caption_length > 5000) {
$this->error('Please enter a number between 1 and 5000');
}
}
if ($max_album_length > 10) {
$this->error('Max album length is 10 photos per album.');
exit;
$max_album_length = '';
while (!is_numeric($max_album_length) || $max_album_length < 1 || $max_album_length > 10) {
$max_album_length = $this->ask('Max photos per album (1-10, default: 4)', '4');
if (!is_numeric($max_album_length) || $max_album_length < 1 || $max_album_length > 10) {
$this->error('Please enter a number between 1 and 10');
}
}
$this->updateEnvFile('PF_OPTIMIZE_IMAGES', $optimize_media);
@ -413,32 +445,58 @@ class Installer extends Command
if ($confirm === 'Yes') {
sleep(3);
// Clear any cached config
$this->call('config:clear');
// Force reload environment variables
$app = app();
$app->bootstrapWith([
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
]);
// Purge database connections to force reconnect with new credentials
$app->forgetInstance('db');
$app->forgetInstance('db.connection');
\Illuminate\Support\Facades\DB::purge();
// Rebuild config cache
$this->call('config:cache');
$this->line('');
$this->info('Migrating DB:');
$this->call('migrate', ['--force' => true]);
$this->line('');
$this->info('Importing Cities:');
$this->call('import:cities');
$this->line('');
$this->info('Creating Federation Instance Actor:');
$this->call('instance:actor');
$this->line('');
$this->info('Creating Password Keys for API:');
$this->call('passport:keys', ['--force' => true]);
$confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0);
if ($confirm === 'Yes') {
$this->call('user:create');
}
$this->migrationsRan = true;
}
}
protected function resetArtisanCache()
protected function setupPrep()
{
$this->call('config:cache');
$this->call('route:cache');
$this->call('view:cache');
if (!$this->migrationsRan) {
$this->warn('Skipping setup tasks because migrations were not run.');
$this->warn('You can run these commands manually later:');
$this->warn(' php artisan import:cities');
$this->warn(' php artisan instance:actor');
$this->warn(' php artisan passport:keys');
return;
}
$this->line('');
$this->info('Running setup tasks...');
$this->line('');
$this->info('Importing Cities:');
$this->call('import:cities');
$this->line('');
$this->info('Creating Federation Instance Actor:');
$this->call('instance:actor');
$this->line('');
$this->info('Creating Password Keys for API:');
$this->call('passport:keys', ['--force' => true]);
$confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0);
if ($confirm === 'Yes') {
$this->call('user:create');
}
}
protected function validateEnv()
@ -448,6 +506,15 @@ class Installer extends Command
$this->checkEnvKeys('APP_DEBUG', "APP_DEBUG value should be false");
}
protected function resetArtisanCache()
{
$this->call('config:clear');
$this->call('config:cache');
$this->call('route:cache');
$this->call('view:cache');
$this->line('');
}
#####
# Installer Functions
#####
@ -467,6 +534,9 @@ class Installer extends Command
{
$envPath = app()->environmentFilePath();
$payload = file_get_contents($envPath);
// Escape special characters for .env format
$value = str_replace(['\\', '"', "\n", "\r"], ['\\\\', '\\"', '\\n', '\\r'], $value);
if ($existing = $this->existingEnv($key, $payload)) {
$payload = str_replace("{$key}={$existing}", "{$key}=\"{$value}\"", $payload);
@ -488,19 +558,22 @@ class Installer extends Command
protected function storeEnv($payload)
{
$file = fopen(app()->environmentFilePath(), 'w');
$envPath = app()->environmentFilePath();
$tempPath = $envPath . '.tmp';
// Write to temp file first
$file = fopen($tempPath, 'w');
if ($file === false) {
throw new \RuntimeException("Cannot write to {$tempPath}");
}
fwrite($file, $payload);
fclose($file);
}
protected function parseSize($size)
{
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
$size = preg_replace('/[^0-9\.]/', '', $size);
if ($unit) {
return round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
} else {
return round($size);
// Atomic rename
if (!rename($tempPath, $envPath)) {
@unlink($tempPath);
throw new \RuntimeException("Cannot update .env file");
}
}
}

@ -15,7 +15,6 @@ class Handler extends ExceptionHandler
*/
protected $dontReport = [
OAuthServerException::class,
\Zttp\ConnectionException::class,
\GuzzleHttp\Exception\ConnectException::class,
\Illuminate\Http\Client\ConnectionException::class
];

@ -34,6 +34,7 @@ use App\Services\PublicTimelineService;
use App\Services\PushNotificationService;
use App\Services\SanitizeService;
use App\Services\StatusService;
use App\Services\UserRoleService;
use App\Services\UserStorageService;
use App\Status;
use App\StatusArchived;

@ -100,7 +100,7 @@ class BaseApiController extends Controller
Cache::forget("avatar:{$profile->id}");
AvatarOptimize::dispatch($user->profile, $currentAvatar);
} catch (Exception $e) {
} catch (\Exception $e) {
}
return response()->json([

@ -1,63 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\{Profile, Instance, Status, User};
use Cache;
use App\Services\StatusService;
class InstanceApiController extends Controller {
protected function getData()
{
$contact = Cache::remember('api:v1:instance:contact', now()->addMinutes(1440), function() {
$admin = User::whereIsAdmin(true)->first()->profile;
return [
'id' => $admin->id,
'username' => $admin->username,
'acct' => $admin->username,
'display_name' => e($admin->name),
'locked' => (bool) $admin->is_private,
'created_at' => str_replace('+00:00', 'Z', $admin->created_at->format(DATE_RFC3339_EXTENDED)),
'note' => e($admin->bio),
'url' => $admin->url(),
'avatar' => $admin->avatarUrl(),
'avatar_static' => $admin->avatarUrl(),
'header' => null,
'header_static' => null,
'moved' => null,
'fields' => null,
'bot' => null,
];
});
$res = [
'uri' => config('pixelfed.domain.app'),
'title' => config_cache('app.name'),
'description' => '',
'version' => config('pixelfed.version'),
'urls' => [],
'stats' => [
'user_count' => User::count(),
'status_count' => StatusService::totalLocalStatuses(),
'domain_count' => Instance::count()
],
'thumbnail' => '',
'languages' => [],
'contact_account' => $contact
];
return $res;
}
public function instance()
{
$res = Cache::remember('api:v1:instance', now()->addMinutes(60), function() {
return json_encode($this->getData());
});
return response($res)->header('Content-Type', 'application/json');
}
}

@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use App\Services\BouncerService;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class ForgotPasswordController extends Controller
{

@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Password;
use Illuminate\Http\Request;
use App\Services\BouncerService;
use Illuminate\Validation\Rules;
use Illuminate\Validation\ValidationException;
class ResetPasswordController extends Controller
{

@ -42,7 +42,7 @@ class AvatarController extends Controller
Cache::forget("avatar:{$profile->id}");
Cache::forget('user:account:id:'.$user->id);
AvatarOptimize::dispatch($user->profile, $currentAvatar);
} catch (Exception $e) {
} catch (\Exception $e) {
}
return redirect()->back()->with('status', 'Avatar updated successfully. It may take a few minutes to update across the site.');

@ -517,7 +517,7 @@ class ComposeController extends Controller
public function store(Request $request)
{
$this->validate($request, [
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length', 500),
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length'),
'media.*' => 'required',
'media.*.id' => 'required|integer|min:1',
'media.*.filter_class' => 'nullable|alpha_dash|max:30',
@ -697,7 +697,7 @@ class ComposeController extends Controller
{
abort_unless(config('exp.top'), 404);
$this->validate($request, [
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length', 500),
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length'),
'cw' => 'nullable|boolean',
'visibility' => 'required|string|in:public,private,unlisted|min:2|max:10',
'place' => 'nullable',
@ -848,7 +848,7 @@ class ComposeController extends Controller
public function createPoll(Request $request)
{
$this->validate($request, [
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length', 500),
'caption' => 'nullable|string|max:'.config_cache('pixelfed.max_caption_length'),
'cw' => 'nullable|boolean',
'visibility' => 'required|string|in:public,private',
'comments_disabled' => 'nullable',

@ -258,7 +258,6 @@ class CustomFilterController extends Controller
$validatedData = $request->validate([
'title' => 'string|max:100',
'context' => 'array|max:10',
'context.*' => 'string|in:home,notifications,public,thread,account,tags,groups',
'context.*' => [
'string',
Rule::in(self::ACTIVE_TYPES),

@ -636,7 +636,7 @@ class GroupController extends GroupFederationController
{
abort_unless(config('groups.enabled'), 404);
$group = GroupService::get($id);
abort_if(! $group || empty($group), 404);
abort_if(! $group, 404);
return view('groups.invite-claim', compact('group'));
}

@ -26,6 +26,10 @@ use App\Models\GroupMedia;
use App\Jobs\GroupsPipeline\ImageResizePipeline;
use App\Jobs\GroupsPipeline\ImageS3UploadPipeline;
use App\Jobs\GroupsPipeline\NewPostPipeline;
use App\Jobs\VideoPipeline\VideoThumbnail;
use App\Jobs\StatusPipeline\StatusDelete;
use App\Media;
use App\Services\PollService;
class GroupsPostController extends Controller
{
@ -38,7 +42,7 @@ class GroupsPostController extends Controller
{
$this->validate($request, [
'group_id' => 'required|exists:groups,id',
'caption' => 'sometimes|string|max:'.config_cache('pixelfed.max_caption_length', 500),
'caption' => 'sometimes|string|max:'.config_cache('pixelfed.max_caption_length'),
'pollOptions' => 'sometimes|array|min:1|max:4'
]);

@ -117,7 +117,7 @@ trait Instagram
$data->save();
});
}
DB::transaction(function() use ($profile, $job) {
DB::transaction(function() use ($job) {
$job->stage = 2;
$job->save();
});
@ -196,7 +196,7 @@ trait Instagram
->whereStage(3)
->firstOrFail();
ImportInstagram::dispatch($import);
} catch (Exception $e) {
} catch (\Exception $e) {
\Log::info($e);
}

@ -203,7 +203,7 @@ class PortfolioController extends Controller
->pluck('status_id');
});
return $media->map(function($sid) use($id) {
return $media->map(function($sid) {
return StatusService::get($sid);
})
->filter(function($post) {

@ -50,7 +50,7 @@ class ProfileAliasController extends Controller
$webfingerService = WebfingerService::lookup($acct);
$webfingerUrl = WebfingerService::rawGet($acct);
if (! $webfingerService || ! isset($webfingerService['url']) || ! $webfingerUrl || empty($webfingerUrl)) {
if (! $webfingerService || ! isset($webfingerService['url']) || ! $webfingerUrl) {
return back()->with('error', 'Invalid account, cannot add alias at this time.');
}
$alias = new ProfileAlias;

@ -593,7 +593,7 @@ class RemoteAuthController extends Controller
}
} catch (\GuzzleHttp\Exception\RequestException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return [];
}
}

@ -125,7 +125,7 @@ class SeasonalController extends Controller
];
});
$res = Cache::remember($userKey, $userTtl, function() use($uid, $pid, $epochStart, $epochEnd, $request) {
$res = Cache::remember($userKey, $userTtl, function() use($pid, $epochStart, $epochEnd, $request) {
return [
'account' => [
'user_id' => $request->user()->id,

@ -44,7 +44,7 @@ class StoreStatusEditRequest extends FormRequest
public function rules(): array
{
return [
'status' => 'sometimes|max:'.config_cache('pixelfed.max_caption_length', 500),
'status' => 'sometimes|max:'.config_cache('pixelfed.max_caption_length'),
'spoiler_text' => 'nullable|string|max:140',
'sensitive' => 'sometimes|boolean',
'media_ids' => [

@ -116,7 +116,7 @@ class AvatarOptimize implements ShouldQueue
$avatar->cdn_url = null;
$avatar->save();
}
} catch (Exception $e) {
} catch (\Exception $e) {
}
}

@ -84,7 +84,7 @@ class FollowPipeline implements ShouldQueue
$notification->item_id = $target->id;
$notification->item_type = "App\Profile";
$notification->save();
} catch (Exception $e) {
} catch (\Exception $e) {
Log::error($e);
}

@ -11,6 +11,8 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
use App\Services\MediaStorageService;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File;
class GroupMediaPipeline implements ShouldQueue
{

@ -85,7 +85,7 @@ class LikePipeline implements ShouldQueue
$notification->item_type = "App\Status";
$notification->save();
} catch (Exception $e) {
} catch (\Exception $e) {
}
}

@ -11,6 +11,7 @@ use App\Services\StatusService;
use App\Status;
use App\Util\Lexer\Autolink;
use App\Util\Lexer\Extractor;
use App\Jobs\MentionPipeline\MentionPipeline;
use DB;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@ -58,7 +59,7 @@ class NewStatusPipeline implements ShouldQueue
}
if (count($this->mentions)) {
$this->storeMentions($this->mentions);
$this->storeMentions();
}
}
@ -90,10 +91,6 @@ class NewStatusPipeline implements ShouldQueue
});
}
if (count($this->mentions)) {
$this->storeMentions();
}
StatusService::del($status->id);
}

@ -16,6 +16,7 @@ use GuzzleHttp\Exception\ClientException;
use Aws\S3\Exception\S3Exception;
use GuzzleHttp\Exception\ConnectException;
use League\Flysystem\UnableToWriteFile;
use Illuminate\Support\Facades\Log;
class ImageS3UploadPipeline implements ShouldQueue
{
@ -86,7 +87,7 @@ class ImageS3UploadPipeline implements ShouldQueue
protected function handleResilientStore($storagePath, $path, $name)
{
$attempts = 0;
return retry(4, function() use($storagePath, $path, $name, $attempts) {
return retry(4, function() use($storagePath, $path, $name) {
self::$attempts++;
usleep(100000);
$baseDisk = self::$attempts > 1 ? $this->getAltDriver() : config('filesystems.cloud');

@ -118,7 +118,7 @@ class ImageUpdate implements ShouldQueue
$disk = Storage::disk(config('filesystems.default'));
$localFs = config('filesystems.default') === 'local';
if (! $path || empty($path)) {
if (! $path) {
return 0;
}

@ -72,7 +72,7 @@ class ImportInstagram implements ShouldQueue
if(!$min->lt($taken_at)) {
$taken_at = Carbon::now();
}
} catch (Exception $e) {
} catch (\Exception $e) {
}
$filename = last( explode('/', $import['path']) );
@ -85,7 +85,7 @@ class ImportInstagram implements ShouldQueue
}
DB::transaction(function() use(
$fs, $job, $profile, $caption, $taken_at, $filename,
$fs, $profile, $caption, $taken_at, $filename,
$monthHash, $userHash, $importData
) {
$status = new Status();

@ -71,7 +71,7 @@ class DeleteWorker implements ShouldQueue
return;
}
if(empty($headers) || empty($payload)) {
if(!$headers || !$payload) {
Log::info("DeleteWorker: Empty headers or payload, skipping job");
return;
}

@ -73,7 +73,7 @@ class InboxValidator implements ShouldQueue
return;
}
if(empty($headers) || empty($payload) || !isset($headers['signature']) || !isset($headers['date'])) {
if(!$headers || !$payload || !isset($headers['signature']) || !isset($headers['date'])) {
Log::info("InboxValidator: Invalid headers or payload structure, skipping job");
return;
}
@ -97,7 +97,7 @@ class InboxValidator implements ShouldQueue
return;
}
if(empty($profile) || empty($headers) || empty($payload)) {
if(!$profile || !$headers || !$payload) {
return;
}
@ -233,7 +233,7 @@ class InboxValidator implements ShouldQueue
}
$res = json_decode($res->body(), true, 8);
if(!$res || empty($res) || !isset($res['publicKey']) || !isset($res['publicKey']['id'])) {
if(!$res || !isset($res['publicKey']) || !isset($res['publicKey']['id'])) {
return;
}
if($res['publicKey']['id'] !== $actor->key_id) {

@ -64,7 +64,7 @@ class InboxWorker implements ShouldQueue
return;
}
if(empty($headers) || empty($payload) || !isset($headers['signature']) || !isset($headers['date'])) {
if(!$headers || !$payload || !isset($headers['signature']) || !isset($headers['date'])) {
Log::info("InboxWorker: Invalid headers or payload structure, skipping job");
return;
}
@ -201,7 +201,7 @@ class InboxWorker implements ShouldQueue
}
$res = json_decode($res->body(), true, 8);
if(!$res || empty($res) || !isset($res['publicKey']) || !isset($res['publicKey']['id'])) {
if(!$res || !isset($res['publicKey']) || !isset($res['publicKey']['id'])) {
return;
}
if($res['publicKey']['id'] !== $actor->key_id) {

@ -102,7 +102,7 @@ class LikePipeline implements ShouldQueue
$notification->item_type = "App\Status";
$notification->save();
} catch (Exception $e) {
} catch (\Exception $e) {
Log::warning("LikePipeline: Failed to create notification for like {$like->id}: " . $e->getMessage());
}

@ -44,7 +44,7 @@ class HandleUpdateActivity implements ShouldQueue
return;
}
if (empty($payload) || ! isset($payload['actor'])) {
if (! $payload || ! isset($payload['actor'])) {
Log::info("HandleUpdateActivity: Invalid payload or missing actor, skipping job");
return;
}

@ -96,7 +96,7 @@ class ProfileMigrationMoveFollowersPipeline implements ShouldBeUniqueUntilProces
$followerProfile = Profile::find($follower->profile_id);
(new FollowerController)->sendFollow($followerProfile, $ne);
}
} catch (Exception $e) {
} catch (\Exception $e) {
Log::error($e);
}
}

@ -15,7 +15,7 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Log;
use Storage;
use Zttp\Zttp;
use Illuminate\Support\Facades\Http;
use App\Util\ActivityPub\Helpers;
use App\Services\MediaPathService;
@ -65,7 +65,7 @@ class RemoteFollowImportRecent implements ShouldQueue
if(Helpers::validateUrl($url) == false) {
return;
}
$response = Zttp::withHeaders([
$response = Http::withHeaders([
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
])->get($url);
@ -201,7 +201,7 @@ class RemoteFollowImportRecent implements ShouldQueue
Log::info(count($attachments).' media found...');
if ($count !== 0) {
NewStatusPipeline::dispatch($status, $status->media->first());
NewStatusPipeline::dispatch($status);
}
}
@ -232,7 +232,7 @@ class RemoteFollowImportRecent implements ShouldQueue
@unlink($file);
return true;
} catch (Exception $e) {
} catch (\Exception $e) {
return false;
}
}

@ -14,7 +14,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Zttp\Zttp;
use Illuminate\Support\Facades\Http;
class RemoteFollowPipeline implements ShouldQueue
{
@ -81,7 +81,7 @@ class RemoteFollowPipeline implements ShouldQueue
$handlerStack = GuzzleHttpSignatures::defaultHandlerFromContext($context);
$client = new Client(['handler' => $handlerStack]);
$response = Zttp::withHeaders([
$response = Http::withHeaders([
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
])->get($url);
@ -136,7 +136,7 @@ class RemoteFollowPipeline implements ShouldQueue
$res = $this->response;
$url = $res['inbox'];
$activity = Zttp::withHeaders(['Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'])->post($url, [
$activity = Http::withHeaders(['Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'])->post($url, [
'type' => 'Follow',
'object' => $this->follower->url(),
]);

@ -663,7 +663,7 @@ class StoryFetch implements ShouldQueue
*/
private function getAllowedMimeTypes(): array
{
$mediaTypes = config_cache('pixelfed.media_types', 'image/jpeg,image/png');
$mediaTypes = config_cache('pixelfed.media_types');
return array_map('trim', explode(',', $mediaTypes));
}

@ -104,7 +104,7 @@ class VideoThumbnail implements ShouldQueue, ShouldBeUniqueUntilProcessing
if(config('media.hls.enabled')) {
VideoHlsPipeline::dispatch($media)->onQueue('mmo');
}
} catch (Exception $e) {
} catch (\Exception $e) {
}

@ -132,7 +132,7 @@ class VideoThumbnailToCloudPipeline implements ShouldQueue, ShouldBeUniqueUntilP
if(str_starts_with($media->media_path, 'public/m/_v2/') && str_ends_with($media->media_path, '.mp4')) {
Storage::disk('local')->delete($media->media_path);
}
} catch (Exception $e) {
} catch (\Exception $e) {
}
if($media->status_id) {

@ -11,6 +11,8 @@ class ConfirmEmail extends Mailable
{
use Queueable, SerializesModels;
protected $verify;
/**
* Create a new message instance.
*

@ -11,6 +11,8 @@ class PasswordChange extends Mailable
{
use Queueable, SerializesModels;
protected $user;
/**
* Create a new message instance.
*

@ -45,7 +45,7 @@ class StatusHashtagObserver implements ShouldHandleEventsAfterCommit
*/
public function deleted(StatusHashtag $hashtag)
{
StatusHashtagService::del($hashtag->hashtag_id, $hashtag->status_id);
StatusHashtagService::del($hashtag->hashtag_id);
DB::table('hashtags')->where('id', $hashtag->hashtag_id)->decrement('cached_count');
if($hashtag->status_visibility && $hashtag->status_visibility === 'public') {
HashtagRemoveFanoutPipeline::dispatch($hashtag->status_id, $hashtag->hashtag_id)->onQueue('feed');
@ -71,6 +71,6 @@ class StatusHashtagObserver implements ShouldHandleEventsAfterCommit
*/
public function forceDeleted(StatusHashtag $hashtag)
{
StatusHashtagService::del($hashtag->hashtag_id, $hashtag->status_id);
StatusHashtagService::del($hashtag->hashtag_id);
}
}

@ -14,7 +14,7 @@ class ExpoPushTokenRule implements ValidationRule
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (! $value || empty($value)) {
if (! $value) {
$fail('The :attribute must not be empty.');
}

@ -42,7 +42,7 @@ class RemoteAuthService
return false;
} catch (ConnectionException $e) {
return false;
} catch (Exception $e) {
} catch (\Exception $e) {
return false;
}
@ -129,7 +129,7 @@ class RemoteAuthService
return false;
} catch (ConnectionException $e) {
return false;
} catch (Exception $e) {
} catch (\Exception $e) {
return false;
}
$json = $res->json();
@ -153,7 +153,7 @@ class RemoteAuthService
return false;
} catch (ConnectionException $e) {
return false;
} catch (Exception $e) {
} catch (\Exception $e) {
return false;
}
$json = $res->json();
@ -182,7 +182,7 @@ class RemoteAuthService
return;
} catch (ConnectionException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return;
}

@ -105,7 +105,7 @@ class ActivityPubFetchService
return;
} catch (ConnectionException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return;
}

@ -73,7 +73,7 @@ class AutospamService
return Cache::remember(self::MODEL_CACHE_KEY, 86400, function () {
$res = Storage::get(self::MODEL_FILE_PATH);
if (! $res || empty($res)) {
if (! $res) {
return null;
}

@ -10,6 +10,7 @@ use App\Profile;
use App\Jobs\AvatarPipeline\AvatarStorageLargePurge;
use League\Flysystem\UnableToCheckDirectoryExistence;
use League\Flysystem\UnableToRetrieveMetadata;
use Exception;
class AvatarService
{

@ -131,7 +131,7 @@ class CollectionService
public static function getThumb($id)
{
$item = self::getItems($id, 0, 1);
if(!$item || empty($item)) {
if(!$item) {
return url('/storage/no-preview.png');
}
$status = StatusService::get($item[0]);

@ -4,6 +4,7 @@ namespace App\Services;
use App\Models\ConfigCache as ConfigCacheModel;
use Cache;
use Exception;
use Illuminate\Database\QueryException;
class ConfigCacheService

@ -62,7 +62,7 @@ class FetchCacheService
Cache::put($key, 1, $ttl);
return false;
} catch (Exception $e) {
} catch (\Exception $e) {
Cache::put($key, 1, $ttl);
return false;

@ -12,6 +12,8 @@ use League\Flysystem\FilesystemException;
use League\Flysystem\UnableToListContents;
use League\Flysystem\FileAttributes;
use League\Flysystem\UnableToWriteFile;
use League\Flysystem\UnableToReadFile;
use League\Flysystem\UnableToDeleteFile;
class FilesystemService
{

@ -28,7 +28,7 @@ class GroupService
$res = Cache::remember(
self::key($id),
1209600,
function() use($id, $pid) {
function() use($id) {
$group = (new Group)->withoutRelations()->whereNull('status')->find($id);
if(!$group) {

@ -9,6 +9,8 @@ use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Transformer\Api\GroupPostTransformer;
use Illuminate\Http\Request;
use App\Models\Group;
class GroupPostService
{

@ -6,6 +6,7 @@ use App\Instance;
use App\Util\Blurhash\Blurhash;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class InstanceService
{

@ -31,7 +31,7 @@ class BeagleService
return;
} catch (ConnectionException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return;
}
@ -72,7 +72,7 @@ class BeagleService
return;
} catch (ConnectionException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return;
}

@ -60,7 +60,7 @@ class SoftwareUpdateService
return;
} catch (ConnectionException $e) {
return;
} catch (Exception $e) {
} catch (\Exception $e) {
return;
}

@ -74,10 +74,10 @@ class LandingService
'uploader' => [
'max_photo_size' => (int) (config_cache('pixelfed.max_photo_size') * 1024),
'max_caption_length' => (int) config_cache('pixelfed.max_caption_length'),
'max_altext_length' => (int) config_cache('pixelfed.max_altext_length', 150),
'max_altext_length' => (int) config_cache('pixelfed.max_altext_length'),
'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('pixelfed.max_collection_length'),
'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
'optimize_video' => (bool) config_cache('pixelfed.optimize_video'),
'media_types' => config_cache('pixelfed.media_types'),

@ -23,7 +23,7 @@ class NotificationAppGatewayService
}
$apiKey = config('instance.notifications.nag.api_key');
if (! $apiKey || empty($apiKey) || strlen($apiKey) !== 45) {
if (! $apiKey || strlen($apiKey) !== 45) {
return false;
}
@ -64,7 +64,7 @@ class NotificationAppGatewayService
public static function isValidExpoPushToken($token)
{
if (! $token || empty($token)) {
if (! $token) {
return false;
}
@ -89,19 +89,19 @@ class NotificationAppGatewayService
return false;
}
if (! $userToken || empty($userToken) || ! self::isValidExpoPushToken($userToken)) {
if (! $userToken || ! self::isValidExpoPushToken($userToken)) {
return false;
}
$types = PushNotificationService::NOTIFY_TYPES;
if (! $type || empty($type) || ! in_array($type, $types)) {
if (! $type || ! in_array($type, $types)) {
return false;
}
$apiKey = config('instance.notifications.nag.api_key');
if (! $apiKey || empty($apiKey)) {
if (! $apiKey) {
return false;
}
$url = 'https://'.config('instance.notifications.nag.endpoint').'/api/v1/relay/deliver';

@ -9,6 +9,7 @@ use GuzzleHttp\Exception\ClientException;
use Aws\S3\Exception\S3Exception;
use GuzzleHttp\Exception\ConnectException;
use League\Flysystem\UnableToWriteFile;
use Illuminate\Support\Facades\Log;
class ResilientMediaStorageService
{
@ -34,7 +35,7 @@ class ResilientMediaStorageService
public static function handleResilientStore($storagePath, $path, $name)
{
$attempts = 0;
return retry(4, function() use($storagePath, $path, $name, $attempts) {
return retry(4, function() use($storagePath, $path, $name) {
self::$attempts++;
usleep(100000);
$baseDisk = self::$attempts > 1 ? self::getAltDriver() : config('filesystems.cloud');

@ -238,7 +238,10 @@ class StoryIndexService
{
$lockKey = $this->rebuildLockKey();
$lockAcquired = Redis::set($lockKey, '1', 'EX', self::REBUILD_LOCK_TTL, 'NX');
$lockAcquired = Redis::setnx($lockKey, '1');
if ($lockAcquired) {
Redis::expire($lockKey, self::REBUILD_LOCK_TTL);
}
if (! $lockAcquired) {
return ['status' => 'already_rebuilding', 'message' => 'Index rebuild already in progress'];

@ -20,7 +20,7 @@ class WebfingerService
if (! $n) {
return false;
}
if (empty($n) || ! str_starts_with($n, 'https://')) {
if (! str_starts_with($n, 'https://')) {
return false;
}
$host = parse_url($n, PHP_URL_HOST);

@ -2,7 +2,7 @@
namespace App\Util\ActivityPub;
use Zttp\Zttp;
use Illuminate\Support\Facades\Http;
class DiscoverActor
{
@ -17,7 +17,7 @@ class DiscoverActor
public function fetch()
{
$res = Zttp::withHeaders([
$res = Http::withHeaders([
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'User-Agent' => 'PixelfedBot - https://pixelfed.org',
])->get($this->url);

@ -182,7 +182,7 @@ class Helpers
return $uri->toString();
} catch (UriException $e) {
} catch (UriException|\Exception $e) {
return false;
}
}
@ -302,7 +302,7 @@ class Helpers
$uri = Uri::new($url);
$host = $uri->getHost();
if (! $host || empty($host)) {
if (! $host) {
return false;
}
@ -338,7 +338,7 @@ class Helpers
return Cache::remember($key, $ttl, function () use ($url) {
$res = ActivityPubFetchService::get($url);
if (! $res || empty($res)) {
if (! $res) {
return false;
}
$res = json_decode($res, true, 8);
@ -477,7 +477,6 @@ class Helpers
public static function isValidStatusData(?array $res): bool
{
return $res &&
! empty($res) &&
! isset($res['error']) &&
isset($res['@context']) &&
isset($res['published']);

@ -30,6 +30,8 @@ use App\Services\AccountService;
use App\Services\FollowerService;
use App\Services\NotificationAppGatewayService;
use App\Services\PollService;
use App\Models\PollVote;
use App\User;
use App\Services\PushNotificationService;
use App\Services\ReblogService;
use App\Services\RelationshipService;
@ -473,7 +475,7 @@ class Inbox
]
);
if (count($activity['attachment'])) {
if (count($activity['attachment'] ?? [])) {
$photos = 0;
$videos = 0;
$allowed = explode(',', config_cache('pixelfed.media_types'));

@ -39,7 +39,6 @@ class Classifier
public function tokenize(string $string): Collection
{
if ($this->tokenizer) {
/** @var array<int, string> */
$tokens = call_user_func($this->tokenizer, $string);
return collect($tokens);

@ -5,7 +5,7 @@
"license": "AGPL-3.0-only",
"type": "project",
"require": {
"php": "^8.2|^8.3|^8.4",
"php": "^8.3|^8.4",
"ext-bcmath": "*",
"ext-ctype": "*",
"ext-curl": "*",
@ -16,9 +16,10 @@
"bacon/bacon-qr-code": "^3.0",
"brick/math": "^0.11",
"buzz/laravel-h-captcha": "^1.0.4",
"doctrine/dbal": "^3.0",
"endroid/qr-code": "^6.0",
"guzzlehttp/guzzle": "^7.10",
"intervention/image": "^3.11.2",
"intervention/image-driver-vips": "^1.0",
"jenssegers/agent": "^2.6",
"laravel-notification-channels/expo": "^2.0.0",
"laravel-notification-channels/webpush": "^10.2",
@ -33,8 +34,9 @@
"league/iso3166": "^2.1|^4.0",
"league/oauth2-client": "^2.8",
"league/uri": "^7.4",
"nesbot/carbon": "^3.10",
"pbmedia/laravel-ffmpeg": "^8.0",
"phpseclib/phpseclib": "~2.0",
"phpseclib/phpseclib": "~3.0",
"pixelfed/fractal": "^0.18.0",
"pixelfed/laravel-snowflake": "^2.0",
"pragmarx/google2fa": "^8.0",

1957
composer.lock generated

File diff suppressed because it is too large Load Diff

@ -150,6 +150,7 @@ return [
/*
* Package Service Providers...
*/
ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider::class,
/*
* Application Service Providers...
@ -215,7 +216,7 @@ return [
'PrettyNumber' => App\Util\Lexer\PrettyNumber::class,
'Purify' => Stevebauman\Purify\Facades\Purify::class,
'FFMpeg' => Pbmedia\LaravelFFMpeg\FFMpegFacade::class,
'FFMpeg' => ProtoneMedia\LaravelFFMpeg\Support\FFMpeg::class,
'Captcha' => Buzz\LaravelHCaptcha\CaptchaFacade::class,
],

@ -160,12 +160,5 @@ return [
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DATABASE_PULSE', 2),
],
],
'dbal' => [
'types' => [
'timestamp' => TimestampType::class,
],
],
];

@ -9,14 +9,12 @@ return [
'notifications' => 'Benachrichtigungen',
'password' => 'Passwort',
'privacy' => 'Privatsphäre',
'relationships' => 'Beziehungen',
'security' => 'Sicherheit',
'timelines' => 'Zeitleisten',
'applications' => 'Anwendungen',
'developers' => 'Entwicklung',
'import' => 'Import',
'export' => 'Export',
'labs' => 'Labs',
'parental_controls' => 'Elterliche Kontrolle',
'submit' => 'Absenden',

@ -197,15 +197,6 @@ return [
'emptyFeed' => 'Wir können keine Beiträge mit diesem Hashtag finden'
],
'report' => [
'report' => 'Melden',
'selectReason' => 'Wähle einen Grund',
'reported' => 'Gemeldet',
'sendingReport' => 'Sende Meldung',
'thanksMsg' => 'Danke für deine Meldung! Damit erhöhst du die Sicherheit der Community!',
'contactAdminMsg' => 'Wenn du die Administration wegen diesem Beitrag oder dieser Meldung kontaktieren möchtest',
],
'report' => [
'report' => 'Melden',
'selectReason' => 'Einen Grund auswählen',

@ -2,19 +2,6 @@
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'verifyYourEmailAddress' => ' - Verify Your Email Address',
'loginTitle' => 'Account Login',
'failed' => 'These credentials do not match our records.',

@ -10,14 +10,12 @@ return [
'notifications' => 'Notifications',
'password' => 'Password',
'privacy' => 'Privacy',
'relationships' => 'Relationships',
'security' => 'Security',
'timelines' => 'Timelines',
'applications' => 'Applications',
'developers' => 'Developers',
'import' => 'Import',
'export' => 'Export',
'labs' => 'Labs',
'parental_controls' => 'Parental Controls',
'submit' => 'Submit',

@ -311,7 +311,6 @@ return [
'create_new_filter' => 'Create new Filter',
'filter_title' => 'Filter Title',
'edit_filter' => 'Edit Filter',
'create_filter' => 'Create Filter',
'advance_mode' => 'Advanced Mode',
'simple_mode' => 'Simple Mode',
'keywords' => 'Keywords',

@ -9,14 +9,12 @@ return [
'notifications' => 'Notificaciones',
'password' => 'Contraseña',
'privacy' => 'Privacidad',
'relationships' => 'Relaciones',
'security' => 'Seguridad',
'timelines' => 'Líneas Temporales',
'applications' => 'Aplicaciones',
'developers' => 'Desarrolladoras',
'import' => 'Importar',
'export' => 'Exportar',
'labs' => 'Labs',
'parental_controls' => 'Control Parental',
'submit' => 'Enviar',

@ -9,14 +9,12 @@ return [
'notifications' => 'Notifications',
'password' => 'Mot de passe',
'privacy' => 'Confidentialité',
'relationships' => 'Relations',
'security' => 'Sécurité',
'timelines' => 'Fil dactualité',
'applications' => 'Applications',
'developers' => 'Développement',
'import' => 'Import',
'export' => 'Export',
'labs' => 'Labo',
'parental_controls' => 'Contrôle parental',
'submit' => 'Enregistrer',

@ -10,14 +10,12 @@ return [
'notifications' => 'Notificações',
'password' => 'Senha',
'privacy' => 'Privacidade',
'relationships' => 'Relacionamentos',
'security' => 'Segurança',
'timelines' => 'Linhas do Tempo',
'applications' => 'Aplicativos',
'developers' => 'Desenvolvedores',
'import' => 'Importar',
'export' => 'Exportar',
'labs' => 'Laboratórios',
'parental_controls' => 'Controles Parentais',
'submit' => 'Enviar',

@ -9,7 +9,6 @@ return [
'notifications' => 'Bildirimler',
'password' => 'Parola',
'privacy' => 'Gizlilik',
'relationships' => 'İlişkiler',
'security' => 'Güvenlik',
'timelines' => 'Akış',
'applications' => 'Uygulamalar',

@ -2,7 +2,8 @@
namespace Tests\Unit;
use phpseclib\Crypt\RSA;
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
@ -16,18 +17,18 @@ class CryptoTest extends TestCase
#[Test]
public function libraryInstalled()
{
$this->assertTrue(class_exists('\phpseclib\Crypt\RSA'));
$this->assertTrue(class_exists('\phpseclib3\Crypt\RSA'));
}
#[Test]
public function RSASigning()
{
$rsa = new RSA();
extract($rsa->createKey());
$rsa->loadKey($privatekey);
$private = RSA::createKey();
$publicKey = $private->getPublicKey();
$plaintext = 'pixelfed rsa test';
$signature = $rsa->sign($plaintext);
$rsa->loadKey($publickey);
$this->assertTrue($rsa->verify($plaintext, $signature));
$signature = $private->sign($plaintext);
$this->assertTrue($publicKey->verify($plaintext, $signature));
}
}

Loading…
Cancel
Save