From fa6ecd8df1651c3292493e77276ce653cd32b368 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:36:03 -0700 Subject: [PATCH 1/6] Add migration --- app/Util/Site/Config.php | 5 +-- config/exp.php | 5 +-- ...15_050602_create_instance_actors_table.php | 33 +++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2021_01_15_050602_create_instance_actors_table.php diff --git a/app/Util/Site/Config.php b/app/Util/Site/Config.php index b59b610f0..88c211ca9 100644 --- a/app/Util/Site/Config.php +++ b/app/Util/Site/Config.php @@ -8,7 +8,7 @@ use Illuminate\Support\Str; class Config { public static function get() { - return Cache::remember('api:site:configuration:_v0', now()->addHours(30), function() { + return Cache::remember('api:site:configuration:_v0.1', now()->addHours(30), function() { return [ 'open_registration' => config('pixelfed.open_registration'), 'uploader' => [ @@ -34,7 +34,8 @@ class Config { 'ab' => [ 'lc' => config('exp.lc'), 'rec' => config('exp.rec'), - 'loops' => config('exp.loops') + 'loops' => config('exp.loops'), + 'top' => config('exp.top') ], 'site' => [ diff --git a/config/exp.php b/config/exp.php index 440997614..74e9a5e49 100644 --- a/config/exp.php +++ b/config/exp.php @@ -3,6 +3,7 @@ return [ 'lc' => env('EXP_LC', false), - 'rec' => env('EXP_REC', false), - 'loops' => env('EXP_LOOPS', false), + 'rec' => false, + 'loops' => false, + 'top' => env('EXP_TOP', false), ]; diff --git a/database/migrations/2021_01_15_050602_create_instance_actors_table.php b/database/migrations/2021_01_15_050602_create_instance_actors_table.php new file mode 100644 index 000000000..2f06cd3fb --- /dev/null +++ b/database/migrations/2021_01_15_050602_create_instance_actors_table.php @@ -0,0 +1,33 @@ +id(); + $table->text('private_key')->nullable(); + $table->text('public_key')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('instance_actors'); + } +} From aafd023c5a4139b2440ce606770a5060abfd4c59 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:36:59 -0700 Subject: [PATCH 2/6] Add InstanceActor model --- app/Models/InstanceActor.php | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 app/Models/InstanceActor.php diff --git a/app/Models/InstanceActor.php b/app/Models/InstanceActor.php new file mode 100644 index 000000000..fad1fc86b --- /dev/null +++ b/app/Models/InstanceActor.php @@ -0,0 +1,41 @@ + 'https://www.w3.org/ns/activitystreams', + 'id' => $this->permalink(), + 'type' => 'Application', + 'inbox' => $this->permalink('/inbox'), + 'outbox' => $this->permalink('/outbox'), + 'preferredUsername' => config('pixelfed.domain.app'), + 'publicKey' => [ + 'id' => $this->permalink('#main-key'), + 'owner' => $this->permalink(), + 'publicKeyPem' => $this->public_key + ], + 'manuallyApprovesFollowers' => true, + 'url' => route('help.instance-actor') + ]; + } +} From 2159eecdbc55c16b5a999e2b9793060d1b6b904b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:38:01 -0700 Subject: [PATCH 3/6] Add InstanceActorController --- .../Controllers/InstanceActorController.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 app/Http/Controllers/InstanceActorController.php diff --git a/app/Http/Controllers/InstanceActorController.php b/app/Http/Controllers/InstanceActorController.php new file mode 100644 index 000000000..136a2ede5 --- /dev/null +++ b/app/Http/Controllers/InstanceActorController.php @@ -0,0 +1,37 @@ +first()->getActor(); + return json_encode($res); + }); + return response($res)->header('Content-Type', 'application/json'); + } + + public function inbox() + { + return; + } + + public function outbox() + { + $res = [ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => config('app.url') . '/i/actor/outbox', + 'type' => 'OrderedCollection', + 'totalItems' => 0, + 'first' => config('app.url') . '/i/actor/outbox?page=true', + 'last' => config('app.url') . '/i/actor/outbox?min_id=0page=true' + ]; + return response()->json($res); + } +} From 844ae6224aeafbe9d751b91fbb059883de73685a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:43:57 -0700 Subject: [PATCH 4/6] Add InstanceActor generate command --- .../Commands/GenerateInstanceActor.php | 75 +++++++++++++++++++ app/Util/ActivityPub/HttpSignature.php | 26 ++++++- app/Util/Lexer/RestrictedNames.php | 14 ++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 app/Console/Commands/GenerateInstanceActor.php diff --git a/app/Console/Commands/GenerateInstanceActor.php b/app/Console/Commands/GenerateInstanceActor.php new file mode 100644 index 000000000..c70b13a12 --- /dev/null +++ b/app/Console/Commands/GenerateInstanceActor.php @@ -0,0 +1,75 @@ +line(' '); + $this->error('Missing instance_actors table.'); + $this->info('Run "php artisan migrate" and try again.'); + $this->line(' '); + exit; + } + + if(InstanceActor::exists()) { + $this->line(' '); + $this->error('Instance actor already exists!'); + $this->line(' '); + $actor = InstanceActor::whereNotNull('public_key') + ->whereNotNull('private_key') + ->firstOrFail(); + Cache::rememberForever(InstanceActor::PKI_PUBLIC, function() use($actor) { + return $actor->public_key; + }); + + Cache::rememberForever(InstanceActor::PKI_PRIVATE, function() use($actor) { + return $actor->private_key; + }); + exit; + } + + $pkiConfig = [ + 'digest_alg' => 'sha512', + 'private_key_bits' => 2048, + 'private_key_type' => OPENSSL_KEYTYPE_RSA, + ]; + $pki = openssl_pkey_new($pkiConfig); + openssl_pkey_export($pki, $pki_private); + $pki_public = openssl_pkey_get_details($pki); + $pki_public = $pki_public['key']; + + $actor = new InstanceActor(); + $actor->public_key = $pki_public; + $actor->private_key = $pki_private; + $actor->save(); + + Cache::rememberForever(InstanceActor::PKI_PUBLIC, function() use($actor) { + return $actor->public_key; + }); + + Cache::rememberForever(InstanceActor::PKI_PRIVATE, function() use($actor) { + return $actor->private_key; + }); + + $this->info('Instance actor succesfully generated. You do not need to run this command again.'); + + return 0; + } +} diff --git a/app/Util/ActivityPub/HttpSignature.php b/app/Util/ActivityPub/HttpSignature.php index d6ed0040b..516979f5c 100644 --- a/app/Util/ActivityPub/HttpSignature.php +++ b/app/Util/ActivityPub/HttpSignature.php @@ -2,7 +2,8 @@ namespace App\Util\ActivityPub; -use Log; +use Cache, Log; +use App\Models\InstanceActor; use App\Profile; use \DateTime; @@ -32,6 +33,29 @@ class HttpSignature { return self::_headersToCurlArray($headers); } + public static function instanceActorSign($url, $body = false, $addlHeaders = []) + { + $keyId = config('app.url') . '/i/actor#main-key'; + $privateKey = Cache::rememberForever(InstanceActor::PKI_PRIVATE, function() { + return InstanceActor::first()->private_key; + }); + if($body) { + $digest = self::_digest($body); + } + $headers = self::_headersToSign($url, $body ? $digest : false); + $headers = array_merge($headers, $addlHeaders); + $stringToSign = self::_headersToSigningString($headers); + $signedHeaders = implode(' ', array_map('strtolower', array_keys($headers))); + $key = openssl_pkey_get_private($privateKey); + openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); + $signature = base64_encode($signature); + $signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + unset($headers['(request-target)']); + $headers['Signature'] = $signatureHeader; + + return self::_headersToCurlArray($headers); + } + public static function parseSignatureHeader($signature) { $parts = explode(',', $signature); $signatureData = []; diff --git a/app/Util/Lexer/RestrictedNames.php b/app/Util/Lexer/RestrictedNames.php index e104b31d2..09af01bfa 100644 --- a/app/Util/Lexer/RestrictedNames.php +++ b/app/Util/Lexer/RestrictedNames.php @@ -98,6 +98,8 @@ class RestrictedNames 'aboutus', 'about-us', 'abuse', + 'actor', + 'actors', 'account', 'admins', 'api', @@ -179,6 +181,7 @@ class RestrictedNames 'help-center_', 'help_center-', 'i', + 'instance', 'inbox', 'img', 'imgs', @@ -208,6 +211,17 @@ class RestrictedNames 'media', 'menu', 'music', + 'my2020', + 'my2021', + 'my2022', + 'my2023', + 'my2024', + 'my2025', + 'my2026', + 'my2027', + 'my2028', + 'my2029', + 'my2030', 'n', 'news', 'new', From 21837be99f5804949c7220af3ea3dc5789beecfb Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:45:56 -0700 Subject: [PATCH 5/6] Update media:optimize command --- app/Console/Commands/CatchUnoptimizedMedia.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Console/Commands/CatchUnoptimizedMedia.php b/app/Console/Commands/CatchUnoptimizedMedia.php index 6b3c3547d..9038c12fb 100644 --- a/app/Console/Commands/CatchUnoptimizedMedia.php +++ b/app/Console/Commands/CatchUnoptimizedMedia.php @@ -42,9 +42,11 @@ class CatchUnoptimizedMedia extends Command { DB::transaction(function() { Media::whereNull('processed_at') + ->where('skip_optimize', '!=', true) ->whereNull('remote_url') ->whereNotNull('status_id') ->whereNotNull('media_path') + ->where('created_at', '>', now()->subHours(1)) ->whereIn('mime', [ 'image/jpeg', 'image/png', From e71e525ac9be17ca5584a3e8bbe2a709220353fd Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 17 Jan 2021 01:47:02 -0700 Subject: [PATCH 6/6] Update console kernel --- .../Commands/FixSoftDeletedProfile.php | 60 ------------------- app/Console/Kernel.php | 7 +-- 2 files changed, 2 insertions(+), 65 deletions(-) delete mode 100644 app/Console/Commands/FixSoftDeletedProfile.php diff --git a/app/Console/Commands/FixSoftDeletedProfile.php b/app/Console/Commands/FixSoftDeletedProfile.php deleted file mode 100644 index 3fe90ff3c..000000000 --- a/app/Console/Commands/FixSoftDeletedProfile.php +++ /dev/null @@ -1,60 +0,0 @@ -withTrashed() - ->where('deleted_at', '>', now()->subDays(14)) - ->whereNull('status') - ->pluck('username'); - - if($profiles->count() == 0) { - return 0; - } - - foreach($profiles as $p) { - if(User::whereUsername($p)->first()->status == null) { - $pro = Profile::withTrashed()->whereUsername($p)->firstOrFail(); - $pro->deleted_at = null; - $pro->save(); - } - } - } -} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index d5e1d47a4..0dd65888a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -25,13 +25,10 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - $schedule->command('media:optimize') - ->hourly(); - $schedule->command('media:gc') - ->hourly(); + $schedule->command('media:optimize')->hourly(); + $schedule->command('media:gc')->hourly(); $schedule->command('horizon:snapshot')->everyFiveMinutes(); $schedule->command('story:gc')->everyFiveMinutes(); - $schedule->command('fix:sdprofile')->everyFiveMinutes(); $schedule->command('gc:failedjobs')->dailyAt(3); $schedule->command('gc:passwordreset')->dailyAt('09:41'); }