mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 06:21:27 +00:00
commit
6350b71cdd
5 changed files with 250 additions and 31 deletions
|
@ -9,6 +9,7 @@
|
|||
- Updated StatusController, restrict edits to 24 hours ([ae24433b](https://github.com/pixelfed/pixelfed/commit/ae24433b))
|
||||
- Updated RateLimit, add max post edits per hour and day ([51fbfcdc](https://github.com/pixelfed/pixelfed/commit/51fbfcdc))
|
||||
- Updated Timeline.vue, move announcements from sidebar to top of timeline ([228f5044](https://github.com/pixelfed/pixelfed/commit/228f5044))
|
||||
- Updated lexer autolinker and extractor, add support for mentioned usernames containing dashes, periods and underscore characters ([f911c96d](https://github.com/pixelfed/pixelfed/commit/f911c96d))
|
||||
|
||||
## [v0.10.8 (2020-01-29)](https://github.com/pixelfed/pixelfed/compare/v0.10.7...v0.10.8)
|
||||
### Added
|
||||
|
|
61
app/Services/ActivityPubDeliveryService.php
Normal file
61
app/Services/ActivityPubDeliveryService.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Profile;
|
||||
use App\Util\ActivityPub\Helpers;
|
||||
use App\Util\ActivityPub\HttpSignature;
|
||||
|
||||
class ActivityPubDeliveryService {
|
||||
|
||||
public $sender;
|
||||
public $to;
|
||||
public $payload;
|
||||
|
||||
public static function queue()
|
||||
{
|
||||
return new self;
|
||||
}
|
||||
|
||||
public function from($profile)
|
||||
{
|
||||
$this->sender = $profile;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function to(string $url)
|
||||
{
|
||||
$this->to = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function payload($payload)
|
||||
{
|
||||
$this->payload = $payload;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
return $this->queueDelivery();
|
||||
}
|
||||
|
||||
protected function queueDelivery()
|
||||
{
|
||||
abort_if(!$this->sender || !$this->to || !$this->payload, 400);
|
||||
abort_if(!Helpers::validateUrl($this->to), 400);
|
||||
abort_if($this->sender->domain != null || $this->sender->status != null, 400);
|
||||
|
||||
$body = $this->payload;
|
||||
$payload = json_encode($body);
|
||||
$headers = HttpSignature::sign($this->sender, $this->to, $body);
|
||||
|
||||
$ch = curl_init($this->to);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_exec($ch);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ use App\Jobs\ImageOptimizePipeline\{ImageOptimize,ImageThumbnail};
|
|||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||
use App\Util\ActivityPub\HttpSignature;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Services\ActivityPubDeliveryService;
|
||||
|
||||
class Helpers {
|
||||
|
||||
|
@ -435,35 +436,12 @@ class Helpers {
|
|||
return self::profileFirstOrNew($url);
|
||||
}
|
||||
|
||||
public static function sendSignedObject($senderProfile, $url, $body)
|
||||
public static function sendSignedObject($profile, $url, $body)
|
||||
{
|
||||
abort_if(!self::validateUrl($url), 400);
|
||||
|
||||
$payload = json_encode($body);
|
||||
$headers = HttpSignature::sign($senderProfile, $url, $body);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
$response = curl_exec($ch);
|
||||
return;
|
||||
}
|
||||
|
||||
public static function apSignedPostRequest($senderProfile, $url, $body)
|
||||
{
|
||||
abort_if(!self::validateUrl($url), 400);
|
||||
|
||||
$payload = json_encode($body);
|
||||
$headers = HttpSignature::sign($senderProfile, $url, $body);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
$response = curl_exec($ch);
|
||||
return;
|
||||
ActivityPubDeliveryService::queue()
|
||||
->from($profile)
|
||||
->to($url)
|
||||
->payload($body)
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,9 +162,9 @@ abstract class Regex
|
|||
// look-ahead capture here and don't append $after when we return.
|
||||
$tmp['valid_mention_preceding_chars'] = '([^a-zA-Z0-9_!#\$%&*@@\/]|^|(?:^|[^a-z0-9_+~.-])RT:?)';
|
||||
|
||||
$re['valid_mentions_or_lists'] = '/'.$tmp['valid_mention_preceding_chars'].'(['.$tmp['at_signs'].'])([a-z0-9_]{1,20})((\/[a-z][a-z0-9_\-]{0,24})?(?=(.*|$))(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i';
|
||||
$re['valid_mentions_or_lists'] = '/'.$tmp['valid_mention_preceding_chars'].'(['.$tmp['at_signs'].'])([a-z0-9_\-.]{1,20})((\/[a-z][a-z0-9_\-]{0,24})?(?=(.*|$))(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i';
|
||||
|
||||
$re['valid_reply'] = '/^(?:['.$tmp['spaces'].'])*['.$tmp['at_signs'].']([a-z0-9_]{1,20})(?=(.*|$))/iu';
|
||||
$re['valid_reply'] = '/^(?:['.$tmp['spaces'].'])*['.$tmp['at_signs'].']([a-z0-9_\-.]{1,20})(?=(.*|$))/iu';
|
||||
$re['end_mention_match'] = '/\A(?:['.$tmp['at_signs'].']|['.$tmp['latin_accents'].']|:\/\/)/iu';
|
||||
|
||||
// URL related hash regex collection
|
||||
|
|
179
tests/Unit/Lexer/UsernameTest.php
Normal file
179
tests/Unit/Lexer/UsernameTest.php
Normal file
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Lexer;
|
||||
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use App\Util\Lexer\Autolink;
|
||||
use App\Util\Lexer\Extractor;
|
||||
|
||||
class UsernameTest extends TestCase
|
||||
{
|
||||
/** @test **/
|
||||
public function genericUsername()
|
||||
{
|
||||
$username = '@dansup';
|
||||
$entities = Extractor::create()->extract($username);
|
||||
$autolink = Autolink::create()->autolink($username);
|
||||
$expectedAutolink = '<a class="u-url mention" href="https://pixelfed.dev/dansup" rel="external nofollow noopener" target="_blank">@dansup</a>';
|
||||
$expectedEntity = [
|
||||
"hashtags" => [],
|
||||
"urls" => [],
|
||||
"mentions" => [
|
||||
"dansup",
|
||||
],
|
||||
"replyto" => "dansup",
|
||||
"hashtags_with_indices" => [],
|
||||
"urls_with_indices" => [],
|
||||
"mentions_with_indices" => [
|
||||
[
|
||||
"screen_name" => "dansup",
|
||||
"indices" => [
|
||||
0,
|
||||
7,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedAutolink, $autolink);
|
||||
$this->assertEquals($expectedEntity, $entities);
|
||||
}
|
||||
|
||||
/** @test **/
|
||||
public function usernameWithPeriod()
|
||||
{
|
||||
$username = '@dansup.two';
|
||||
$autolink = Autolink::create()->autolink($username);
|
||||
$entities = Extractor::create()->extract($username);
|
||||
$expectedAutolink = '<a class="u-url mention" href="https://pixelfed.dev/dansup.two" rel="external nofollow noopener" target="_blank">@dansup.two</a>';
|
||||
$expectedEntity = [
|
||||
"hashtags" => [],
|
||||
"urls" => [],
|
||||
"mentions" => [
|
||||
"dansup.two",
|
||||
],
|
||||
"replyto" => "dansup.two",
|
||||
"hashtags_with_indices" => [],
|
||||
"urls_with_indices" => [],
|
||||
"mentions_with_indices" => [
|
||||
[
|
||||
"screen_name" => "dansup.two",
|
||||
"indices" => [
|
||||
0,
|
||||
11,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedAutolink, $autolink);
|
||||
$this->assertEquals($expectedEntity, $entities);
|
||||
}
|
||||
|
||||
/** @test **/
|
||||
public function usernameWithDash()
|
||||
{
|
||||
$username = '@dansup-too';
|
||||
$autolink = Autolink::create()->autolink($username);
|
||||
$entities = Extractor::create()->extract($username);
|
||||
$expectedAutolink = '<a class="u-url mention" href="https://pixelfed.dev/dansup-too" rel="external nofollow noopener" target="_blank">@dansup-too</a>';
|
||||
$expectedEntity = [
|
||||
"hashtags" => [],
|
||||
"urls" => [],
|
||||
"mentions" => [
|
||||
"dansup-too",
|
||||
],
|
||||
"replyto" => "dansup-too",
|
||||
"hashtags_with_indices" => [],
|
||||
"urls_with_indices" => [],
|
||||
"mentions_with_indices" => [
|
||||
[
|
||||
"screen_name" => "dansup-too",
|
||||
"indices" => [
|
||||
0,
|
||||
11,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedAutolink, $autolink);
|
||||
$this->assertEquals($expectedEntity, $entities);
|
||||
}
|
||||
|
||||
/** @test **/
|
||||
public function usernameWithUnderscore()
|
||||
{
|
||||
$username = '@dansup_too';
|
||||
$autolink = Autolink::create()->autolink($username);
|
||||
$entities = Extractor::create()->extract($username);
|
||||
$expectedAutolink = '<a class="u-url mention" href="https://pixelfed.dev/dansup_too" rel="external nofollow noopener" target="_blank">@dansup_too</a>';
|
||||
$expectedEntity = [
|
||||
"hashtags" => [],
|
||||
"urls" => [],
|
||||
"mentions" => [
|
||||
"dansup_too",
|
||||
],
|
||||
"replyto" => "dansup_too",
|
||||
"hashtags_with_indices" => [],
|
||||
"urls_with_indices" => [],
|
||||
"mentions_with_indices" => [
|
||||
[
|
||||
"screen_name" => "dansup_too",
|
||||
"indices" => [
|
||||
0,
|
||||
11,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedAutolink, $autolink);
|
||||
$this->assertEquals($expectedEntity, $entities);
|
||||
}
|
||||
|
||||
/** @test **/
|
||||
public function multipleMentions()
|
||||
{
|
||||
$text = 'hello @dansup and @pixelfed.team from @username_underscore';
|
||||
$autolink = Autolink::create()->autolink($text);
|
||||
$entities = Extractor::create()->extract($text);
|
||||
$expectedAutolink = 'hello <a class="u-url mention" href="https://pixelfed.dev/dansup" rel="external nofollow noopener" target="_blank">@dansup</a> and <a class="u-url mention" href="https://pixelfed.dev/pixelfed.team" rel="external nofollow noopener" target="_blank">@pixelfed.team</a> from <a class="u-url mention" href="https://pixelfed.dev/username_underscore" rel="external nofollow noopener" target="_blank">@username_underscore</a>';
|
||||
$expectedEntity = [
|
||||
"hashtags" => [],
|
||||
"urls" => [],
|
||||
"mentions" => [
|
||||
"dansup",
|
||||
"pixelfed.team",
|
||||
"username_underscore",
|
||||
],
|
||||
"replyto" => null,
|
||||
"hashtags_with_indices" => [],
|
||||
"urls_with_indices" => [],
|
||||
"mentions_with_indices" => [
|
||||
[
|
||||
"screen_name" => "dansup",
|
||||
"indices" => [
|
||||
6,
|
||||
13,
|
||||
],
|
||||
],
|
||||
[
|
||||
"screen_name" => "pixelfed.team",
|
||||
"indices" => [
|
||||
18,
|
||||
32,
|
||||
],
|
||||
],
|
||||
[
|
||||
"screen_name" => "username_underscore",
|
||||
"indices" => [
|
||||
38,
|
||||
58,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expectedAutolink, $autolink);
|
||||
$this->assertEquals($expectedEntity, $entities);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue