Unverified Commit 30b5f43f authored by daniel's avatar daniel Committed by GitHub
Browse files

Merge pull request #2570 from pixelfed/staging

Staging
parents 91b7c043 e71e525a
......@@ -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',
......
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Profile;
use App\User;
class FixSoftDeletedProfile extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fix:sdprofile';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$profiles = Profile::whereNull('domain')
->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();
}
}
}
}
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use App\Models\InstanceActor;
use Cache;
class GenerateInstanceActor extends Command
{
protected $signature = 'instance:actor';
protected $description = 'Generate instance actor';
public function __construct()
{
parent::__construct();
}
public function handle()
{
if(Schema::hasTable('instance_actors') == false) {
$this->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;
}
}
......@@ -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');
}
......
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\InstanceActor;
use Cache;
class InstanceActorController extends Controller
{
public function profile()
{
$res = Cache::rememberForever(InstanceActor::PROFILE_KEY, function() {
$res = (new InstanceActor())->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);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class InstanceActor extends Model
{
use HasFactory;
const PROFILE_BASE = '/i/actor';
const KEY_ID = '/i/actor#main-key';
const PROFILE_KEY = 'federation:_v2:instance:actor:profile';
const PKI_PUBLIC = 'federation:_v1:instance:actor:profile:pki_public';
const PKI_PRIVATE = 'federation:_v1:instance:actor:profile:pki_private';
public function permalink($suffix = '')
{
return url(self::PROFILE_BASE . $suffix);
}
public function getActor()
{
return [
'@context' => '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')
];
}
}
......@@ -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 = [];
......
......@@ -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',
......
......@@ -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' => [
......
......@@ -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),
];
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateInstanceActorsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('instance_actors', function (Blueprint $table) {
$table->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');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment