From f100533fe809fd0488e1caab9f711f25f358ebae Mon Sep 17 00:00:00 2001 From: Aditoo17 <42938951+Aditoo17@users.noreply.github.com> Date: Mon, 17 Dec 2018 17:39:58 +0100 Subject: [PATCH 01/29] L10n: Update Czech translation --- .../lang/vendor/backup/cs/notifications.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 resources/lang/vendor/backup/cs/notifications.php diff --git a/resources/lang/vendor/backup/cs/notifications.php b/resources/lang/vendor/backup/cs/notifications.php new file mode 100644 index 000000000..947eb436e --- /dev/null +++ b/resources/lang/vendor/backup/cs/notifications.php @@ -0,0 +1,35 @@ + 'Zpráva výjimky: :message', + 'exception_trace' => 'Stopa výjimky: :trace', + 'exception_message_title' => 'Zpráva výjimky', + 'exception_trace_title' => 'Stopa výjimky', + + 'backup_failed_subject' => 'Záloha :application_name neuspěla', + 'backup_failed_body' => 'Důležité: Při záloze :application_name se vyskytla chyba', + + 'backup_successful_subject' => 'Úspěšná nová záloha :application_name', + 'backup_successful_subject_title' => 'Úspěšná nová záloha!', + 'backup_successful_body' => 'Dobrá zpráva, na disku jménem :disk_name byla úspěšně vytvořena nová záloha :application_name.', + + 'cleanup_failed_subject' => 'Vyčištění záloh :application_name neuspělo.', + 'cleanup_failed_body' => 'Při vyčištění záloh :application_name se vyskytla chyba', + + 'cleanup_successful_subject' => 'Vyčištění záloh :application_name úspěšné', + 'cleanup_successful_subject_title' => 'Vyčištění záloh bylo úspěšné!', + 'cleanup_successful_body' => 'Vyčištění záloh :application_name na disku jménem :disk_name bylo úspěšné.', + + 'healthy_backup_found_subject' => 'Zálohy pro :application_name na disku :disk_name jsou zdravé', + 'healthy_backup_found_subject_title' => 'Zálohy pro :application_name jsou zdravé', + 'healthy_backup_found_body' => 'Zálohy pro :application_name jsou považovány za zdravé. Dobrá práce!', + + 'unhealthy_backup_found_subject' => 'Důležité: Zálohy pro :application_name jsou nezdravé', + 'unhealthy_backup_found_subject_title' => 'Důležité: Zálohy pro :application_name jsou nezdravé. :problem', + 'unhealthy_backup_found_body' => 'Zálohy pro :application_name na disku :disk_name Jsou nezdravé.', + 'unhealthy_backup_found_not_reachable' => 'Nelze se dostat k cíli zálohy. :error', + 'unhealthy_backup_found_empty' => 'Tato aplikace nemá vůbec žádné zálohy.', + 'unhealthy_backup_found_old' => 'Poslední záloha vytvořená dne :date je považována za příliš starou.', + 'unhealthy_backup_found_unknown' => 'Omlouváme se, nemůžeme určit přesný důvod.', + 'unhealthy_backup_found_full' => 'Zálohy zabírají příliš mnoho místa na disku. Aktuální využití disku je :disk_usage, což je vyšší než povolený limit :disk_limit.', +]; From bffaac1b08cd63fb27708a8001e25fd32ffb0c24 Mon Sep 17 00:00:00 2001 From: Carly Ho Date: Tue, 25 Dec 2018 15:42:12 -0600 Subject: [PATCH 02/29] Add comment button to comment form where browser has 'Touch' event enabled --- resources/assets/js/components.js | 13 +++++++--- .../assets/js/components/PostComponent.vue | 21 ++++++++------- resources/assets/sass/custom.scss | 26 ++++++++++++++++--- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/resources/assets/js/components.js b/resources/assets/js/components.js index 50aa36bda..3acb43982 100644 --- a/resources/assets/js/components.js +++ b/resources/assets/js/components.js @@ -25,6 +25,13 @@ pixelfed.readmore = () => { }); }; +try { + document.createEvent("TouchEvent"); + $('body').addClass('touch'); +} catch (e) { + return false; +} + window.InfiniteScroll = require('infinite-scroll'); window.filesize = require('filesize'); window.Plyr = require('plyr'); @@ -137,10 +144,10 @@ window.pixelfed.copyToClipboard = (str) => { const el = document.createElement('textarea'); el.value = str; el.setAttribute('readonly', ''); - el.style.position = 'absolute'; + el.style.position = 'absolute'; el.style.left = '-9999px'; document.body.appendChild(el); - const selected = + const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; @@ -162,4 +169,4 @@ $(document).ready(function() { const warningTitleCSS = 'color:red; font-size:60px; font-weight: bold; -webkit-text-stroke: 1px black;'; const warningDescCSS = 'font-size: 18px;'; console.log('%cStop!', warningTitleCSS); -console.log("%cThis is a browser feature intended for developers. If someone told you to copy and paste something here to enable a Pixelfed feature or \"hack\" someone's account, it is a scam and will give them access to your Pixelfed account.", warningDescCSS); \ No newline at end of file +console.log("%cThis is a browser feature intended for developers. If someone told you to copy and paste something here to enable a Pixelfed feature or \"hack\" someone's account, it is a scam and will give them access to your Pixelfed account.", warningDescCSS); diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index c3b9f6258..cba5e9d62 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -56,11 +56,11 @@
-
+
- +
@@ -156,6 +156,7 @@ +
@@ -164,10 +165,10 @@
-
@@ -195,10 +196,10 @@
-
@@ -281,7 +282,7 @@ export default { $('head title').text(title); } }, - + methods: { authCheck() { let authed = $('body').hasClass('loggedIn'); @@ -510,4 +511,4 @@ export default { } } } - \ No newline at end of file + diff --git a/resources/assets/sass/custom.scss b/resources/assets/sass/custom.scss index ea2e55bd8..45068728b 100644 --- a/resources/assets/sass/custom.scss +++ b/resources/assets/sass/custom.scss @@ -267,6 +267,26 @@ body, button, input, textarea { .card { box-shadow: 0 2px 6px 0 hsla(0, 0%, 0%, 0.2); border: none; + + .comment-submit { + display: none; + position: absolute; + bottom: 12px; + right: 20px; + width: 60px; + text-align: center; + border-radius: 0 3px 3px 0; + } +} + +.touch .card { + input[name="comment"] { + padding-right: 70px; + } + + .comment-submit { + display: block; + } } .box-shadow { @@ -319,7 +339,7 @@ details summary::-webkit-details-marker { box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08); border-radius: 5px; padding: .5em 1em .5em .5em; -} +} .input-elevated::placeholder { color: #838D99; @@ -417,7 +437,7 @@ details summary::-webkit-details-marker { background: rgba(0,0,0,0.04); } -.timeline-sidenav.nav-pills .nav-link.active, +.timeline-sidenav.nav-pills .nav-link.active, .timeline-sidenav.nav-pills .show > .nav-link { color: #08d; background: transparent; @@ -434,4 +454,4 @@ details summary::-webkit-details-marker { .notification-tooltip .arrow::before { border-bottom-color:#dc3545 !important; -} \ No newline at end of file +} From 94a1d7da90a56cee42c805f1e44d6574ed000d19 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Tue, 25 Dec 2018 21:59:32 +0000 Subject: [PATCH 03/29] Correct spelling mistakes --- resources/assets/js/components.js | 2 +- resources/assets/js/components/DiscoverComponent.vue | 2 +- resources/assets/js/components/PostComments.vue | 4 ++-- resources/assets/js/components/PostComponent.vue | 4 ++-- resources/assets/js/components/notifications.js | 2 +- resources/views/settings/remove/permanent.blade.php | 2 +- resources/views/site/help/getting-started.blade.php | 2 +- resources/views/status/compose.blade.php | 4 ++-- resources/views/status/edit.blade.php | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/resources/assets/js/components.js b/resources/assets/js/components.js index 50aa36bda..cc91bc2f4 100644 --- a/resources/assets/js/components.js +++ b/resources/assets/js/components.js @@ -55,7 +55,7 @@ require('./components/statusform'); // }); // } -// Initalize Notification Helper +// Initialize Notification Helper window.pixelfed.n = {}; Vue.component( diff --git a/resources/assets/js/components/DiscoverComponent.vue b/resources/assets/js/components/DiscoverComponent.vue index 974234b45..7cec33b60 100644 --- a/resources/assets/js/components/DiscoverComponent.vue +++ b/resources/assets/js/components/DiscoverComponent.vue @@ -70,7 +70,7 @@ export default { }).catch(err => { swal( 'Whoops! Something went wrong...', - 'An error occured, please try again later.', + 'An error occurred, please try again later.', 'error' ); }); diff --git a/resources/assets/js/components/PostComments.vue b/resources/assets/js/components/PostComments.vue index cc57ad699..6122f0b21 100644 --- a/resources/assets/js/components/PostComments.vue +++ b/resources/assets/js/components/PostComments.vue @@ -104,7 +104,7 @@ export default { $('.postCommentsLoader .lds-ring') .attr('style','width:100%') .addClass('pt-4 font-weight-bold text-muted') - .text('An error occured, cannot fetch comments. Please try again later.'); + .text('An error occurred, cannot fetch comments. Please try again later.'); } else { switch(error.response.status) { case 401: @@ -118,7 +118,7 @@ export default { $('.postCommentsLoader .lds-ring') .attr('style','width:100%') .addClass('pt-4 font-weight-bold text-muted') - .text('An error occured, cannot fetch comments. Please try again later.'); + .text('An error occurred, cannot fetch comments. Please try again later.'); break; } } diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index c3b9f6258..50a6970e2 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -339,7 +339,7 @@ export default { $('.postPresenterContainer').removeClass('d-none'); }).catch(error => { if(!error.response) { - $('.postPresenterLoader .lds-ring').attr('style','width:100%').addClass('pt-4 font-weight-bold text-muted').text('An error occured, cannot fetch media. Please try again later.'); + $('.postPresenterLoader .lds-ring').attr('style','width:100%').addClass('pt-4 font-weight-bold text-muted').text('An error occurred, cannot fetch media. Please try again later.'); } else { switch(error.response.status) { case 401: @@ -350,7 +350,7 @@ export default { break; default: - $('.postPresenterLoader .lds-ring').attr('style','width:100%').addClass('pt-4 font-weight-bold text-muted').text('An error occured, cannot fetch media. Please try again later.'); + $('.postPresenterLoader .lds-ring').attr('style','width:100%').addClass('pt-4 font-weight-bold text-muted').text('An error occurred, cannot fetch media. Please try again later.'); break; } } diff --git a/resources/assets/js/components/notifications.js b/resources/assets/js/components/notifications.js index 3ca2d8451..687c70e54 100644 --- a/resources/assets/js/components/notifications.js +++ b/resources/assets/js/components/notifications.js @@ -96,7 +96,7 @@ $(document).ready(function() { }).catch(err => { swal( 'Something went wrong!', - 'An error occured, please try again later.', + 'An error occurred, please try again later.', 'error' ); }); diff --git a/resources/views/settings/remove/permanent.blade.php b/resources/views/settings/remove/permanent.blade.php index b95aa2894..a805ce668 100644 --- a/resources/views/settings/remove/permanent.blade.php +++ b/resources/views/settings/remove/permanent.blade.php @@ -16,7 +16,7 @@

When you press the button below, your photos, comments, likes, friendships and all other data will be removed permanently and will not be recoverable. If you decide to create another Pixelfed account in the future, you cannot sign up with the same username again on this instance.

- Warning: Some remote servers may contain your public data (statuses, avatars, ect) and will not be deleted until federation support is launched. + Warning: Some remote servers may contain your public data (statuses, avatars, etc) and will not be deleted until federation support is launched.

diff --git a/resources/views/site/help/getting-started.blade.php b/resources/views/site/help/getting-started.blade.php index 10adae72f..a764433f1 100644 --- a/resources/views/site/help/getting-started.blade.php +++ b/resources/views/site/help/getting-started.blade.php @@ -64,7 +64,7 @@

diff --git a/resources/views/status/compose.blade.php b/resources/views/status/compose.blade.php index 8b5251a2f..691a97a3e 100644 --- a/resources/views/status/compose.blade.php +++ b/resources/views/status/compose.blade.php @@ -354,7 +354,7 @@ $(document).on('change', '.file-input', function(e) { el.remove(); } }).catch(function(e) { - swal('Oops, something went wrong!', 'An unexpected error occured.', 'error'); + swal('Oops, something went wrong!', 'An unexpected error occurred.', 'error'); }); io.value = null; }); @@ -478,7 +478,7 @@ $(document).on('click', '#create', function(e) { let data = res.data; window.location.href = data; }).catch(err => { - swal('Oops, something went wrong!', 'An unexpected error occured.', 'error'); + swal('Oops, something went wrong!', 'An unexpected error occurred.', 'error'); }); }) diff --git a/resources/views/status/edit.blade.php b/resources/views/status/edit.blade.php index ffb23cb37..d69843552 100644 --- a/resources/views/status/edit.blade.php +++ b/resources/views/status/edit.blade.php @@ -83,7 +83,7 @@ }).then((res) => { swal('Success!', 'You have successfully updated your post', 'success'); }).catch((err) => { - swal('Something went wrong', 'An error occured, please try again later', 'error'); + swal('Something went wrong', 'An error occurred, please try again later', 'error'); }); }); From 14d43ba845042a6b63a5c6c2c2ce161935ebade7 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 25 Dec 2018 15:21:25 -0700 Subject: [PATCH 04/29] Fix AP fanout --- app/Jobs/StatusPipeline/StatusActivityPubDeliver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/StatusPipeline/StatusActivityPubDeliver.php b/app/Jobs/StatusPipeline/StatusActivityPubDeliver.php index 1100f0988..12a66c373 100644 --- a/app/Jobs/StatusPipeline/StatusActivityPubDeliver.php +++ b/app/Jobs/StatusPipeline/StatusActivityPubDeliver.php @@ -38,7 +38,7 @@ class StatusActivityPubDeliver implements ShouldQueue { $status = $this->status; - if($status->local == true || $status->url || $status->uri) { + if($status->local == false || $status->url || $status->uri) { return; } From 55ca00ba3006ccd9263a1a4b948c8543843aa619 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 25 Dec 2018 17:45:29 -0700 Subject: [PATCH 05/29] Update FederationController, fixes #680 --- app/Http/Controllers/FederationController.php | 11 +++++++++-- app/Util/ActivityPub/Inbox.php | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index 2511b9984..b1e7d18cd 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -181,13 +181,20 @@ XML; return ProfileController::accountCheck($profile); } $body = $request->getContent(); - $bodyDecoded = json_decode($body, true); + $bodyDecoded = json_decode($body, true, 8); $signature = $request->header('signature'); if(!$signature) { abort(400, 'Missing signature header'); } $signatureData = HttpSignature::parseSignatureHeader($signature); - $actor = Profile::whereKeyId($signatureData['keyId'])->first(); + $keyId = Helpers::validateUrl($signatureData['keyId']); + $id = Helpers::validateUrl($bodyDecoded['id']); + $keyDomain = parse_url($keyId, PHP_URL_HOST); + $idDomain = parse_url($id, PHP_URL_HOST); + if(!$keyDomain || !$idDomain || $keyDomain !== $idDomain) { + abort(400, 'Invalid request'); + } + $actor = Profile::whereKeyId($keyId)->first(); if(!$actor) { $actor = Helpers::profileFirstOrNew($bodyDecoded['actor']); } diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 7791fe977..5b2b6bfe9 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -167,12 +167,13 @@ class Inbox return; } - $status = DB::transaction(function() use($activity, $actor) { + $status = DB::transaction(function() use($activity, $actor, $url) { $caption = str_limit(strip_tags($activity['content']), config('pixelfed.max_caption_length')); $status = new Status; $status->profile_id = $actor->id; $status->caption = $caption; $status->visibility = $status->scope = 'public'; + $status->uri = $url; $status->url = $url; $status->save(); return $status; From fedcdb204db420368401db92b81273764c1c18d6 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 25 Dec 2018 18:06:12 -0700 Subject: [PATCH 06/29] Update FederationController --- app/Http/Controllers/FederationController.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index b1e7d18cd..27b657b3a 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -191,6 +191,14 @@ XML; $id = Helpers::validateUrl($bodyDecoded['id']); $keyDomain = parse_url($keyId, PHP_URL_HOST); $idDomain = parse_url($id, PHP_URL_HOST); + if(isset($bodyDecoded['object']) + && is_array($bodyDecoded['object']) + && isset($bodyDecoded['object']['attributedTo']) + ) { + if(parse_url($bodyDecoded['object']['attributedTo'], PHP_URL_HOST) !== $idDomain) { + abort(400, 'Invalid request'); + } + } if(!$keyDomain || !$idDomain || $keyDomain !== $idDomain) { abort(400, 'Invalid request'); } From eaaf8fbcd709ebb95668aa2b95ec6875bd740295 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 25 Dec 2018 18:07:32 -0700 Subject: [PATCH 07/29] Update FederationController --- app/Http/Controllers/FederationController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index 27b657b3a..c93b1b664 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -195,7 +195,7 @@ XML; && is_array($bodyDecoded['object']) && isset($bodyDecoded['object']['attributedTo']) ) { - if(parse_url($bodyDecoded['object']['attributedTo'], PHP_URL_HOST) !== $idDomain) { + if(parse_url($bodyDecoded['object']['attributedTo'], PHP_URL_HOST) !== $keyDomain) { abort(400, 'Invalid request'); } } From 310d427a34eb4c0fd311ff1ed61b41cb35bc4314 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 25 Dec 2018 19:41:12 -0700 Subject: [PATCH 08/29] Update Timeline.vue, fix notification avatar bug --- public/js/components.js | Bin 580538 -> 580617 bytes public/mix-manifest.json | Bin 321 -> 321 bytes resources/assets/js/components/Timeline.vue | 11 +++++++---- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/public/js/components.js b/public/js/components.js index 176e3326510210d720f22be2e85f4e9dadc341b5..1a5ce592677fbf99c80ec244dfd56607a201662f 100644 GIT binary patch delta 336 zcmdnBUAc3I@`e-_mh^OOrRfLVn7*j%mFE|w=q44VCT3S7m{wo`-Nc-nS|uGNrC80$ z2`+0{9E+2~CJVZXvXonz`%hnZi$i6zpX+OBu=w+rHPG35c1u?{#N+wVF*SG+nkTqobC7I*|*=5=eV;Q0Q-M)1ONa4 delta 240 zcmeC&p}cFm@`e-_mK>K5rRn@~>}Hb>y5_TlJ8< zH&5?gD#i>HntYI7ipAfpuz0$GHfxZCWr}fXnz@mIl1`?MqJd6zt!Ax`b8ceB<#SBVVHTghKZi+fvO~iTnBZowMqjS>S{YU#X4_sX!~TJZIXS6v U`f5W~({^12_U*a~9CvmD0C)deP5=M^ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 54baaeb4051ca1c4006d450e362a032d03ddcc4f..44662a12af5711b690e64fd15d63102d131e1ddf 100644 GIT binary patch delta 30 lcmX@ebdYI+p@@Z+qWMJEKLCzL3AF$K diff --git a/resources/assets/js/components/Timeline.vue b/resources/assets/js/components/Timeline.vue index baf48c9c8..e265ae6fc 100644 --- a/resources/assets/js/components/Timeline.vue +++ b/resources/assets/js/components/Timeline.vue @@ -156,22 +156,22 @@ @@ -211,6 +211,9 @@ .cursor-pointer { cursor: pointer; } + .word-break { + word-break: break-all; + } @endpush From 1cca479fad6a2f4a35d3bef9238f252150051c99 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 27 Dec 2018 22:55:21 -0700 Subject: [PATCH 25/29] Update AP Inbox --- app/Util/ActivityPub/Inbox.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 5b2b6bfe9..2d764f040 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -220,7 +220,7 @@ class Inbox // send Accept to remote profile $accept = [ '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => $target->permalink().'#accepts/follows/', + 'id' => $target->permalink().'#accepts/follows/' . $follower->id, 'type' => 'Accept', 'actor' => $target->permalink(), 'object' => [ From a2a69c9d6c8c812964c3a54b279cb3ad18d706ad Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Fri, 28 Dec 2018 20:25:19 -0700 Subject: [PATCH 26/29] Update config --- config/pixelfed.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/pixelfed.php b/config/pixelfed.php index 25c9c0870..feb3ed318 100644 --- a/config/pixelfed.php +++ b/config/pixelfed.php @@ -23,7 +23,7 @@ return [ | This value is the version of your PixelFed instance. | */ - 'version' => '0.7.6', + 'version' => '0.7.7', /* |-------------------------------------------------------------------------- @@ -59,7 +59,7 @@ return [ */ 'restricted_names' => [ 'reserved_routes' => true, - 'use_blacklist' => false, + 'use_blacklist' => env('USERNAME_BLACKLIST', false), ], /* From cfbd7d5a1a1aca0e9ac36d2bbe0fbb6320e3993b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Fri, 28 Dec 2018 20:39:16 -0700 Subject: [PATCH 27/29] Update RestrictedNames --- app/Util/Lexer/RestrictedNames.php | 31 ++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/app/Util/Lexer/RestrictedNames.php b/app/Util/Lexer/RestrictedNames.php index 0bd2648b6..5fe8d4d38 100644 --- a/app/Util/Lexer/RestrictedNames.php +++ b/app/Util/Lexer/RestrictedNames.php @@ -39,7 +39,6 @@ class RestrictedNames 'ftp', 'guest', 'guests', - 'help', 'hostmaster', 'hostmaster', 'image', @@ -94,9 +93,6 @@ class RestrictedNames 'ssladmin', 'ssladministrator', 'sslwebmaster', - 'status', - 'support', - 'support', 'sys', 'sysadmin', 'system', @@ -107,7 +103,6 @@ class RestrictedNames 'uucp', 'webmaster', 'wpad', - 'www', ]; public static $reserved = [ @@ -126,36 +121,60 @@ class RestrictedNames 'account', 'api', 'auth', + 'broadcast', + 'broadcaster', 'css', 'checkpoint', + 'collection', + 'collections', 'c', - 'i', + 'cdn', 'dashboard', 'deck', 'discover', 'docs', + 'error', + 'explore', 'fonts', 'home', + 'help', + 'helpcenter', + 'i', 'img', 'js', + 'live', 'login', 'logout', 'media', + 'official', 'p', 'password', + 'reset', 'report', 'reports', + 'robot', + 'robots', 'search', + 'send', 'settings', + 'status', 'statuses', 'site', 'sites', + 'static', + 'story', + 'stories', + 'support', + 'telescope', 'timeline', 'timelines', 'tour', 'user', 'users', 'vendor', + 'ws', + 'wss', + 'www', '400', '401', '403', From 714e47f38700d6cbb6ba8c338be238a79fd7a333 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 29 Dec 2018 16:56:39 -0700 Subject: [PATCH 28/29] Add Accept validator/test --- .env.testing | 2 + app/Util/ActivityPub/Validator/Accept.php | 32 +++++++++++++ tests/Unit/ActivityPub/AcceptVerbTest.php | 55 +++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 app/Util/ActivityPub/Validator/Accept.php create mode 100644 tests/Unit/ActivityPub/AcceptVerbTest.php diff --git a/.env.testing b/.env.testing index f7dcfe55e..a37e329eb 100644 --- a/.env.testing +++ b/.env.testing @@ -53,3 +53,5 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" MIX_APP_URL="${APP_URL}" MIX_API_BASE="${API_BASE}" MIX_API_SEARCH="${API_SEARCH}" + +TELESCOPE_ENABLED=false diff --git a/app/Util/ActivityPub/Validator/Accept.php b/app/Util/ActivityPub/Validator/Accept.php new file mode 100644 index 000000000..7230a37f3 --- /dev/null +++ b/app/Util/ActivityPub/Validator/Accept.php @@ -0,0 +1,32 @@ + 'required', + 'id' => 'required|string', + 'type' => [ + 'required', + Rule::in(['Accept']) + ], + 'actor' => 'required|url|active_url', + 'object' => 'required', + 'object.id' => 'required|url|active_url', + 'object.type' => [ + 'required', + Rule::in(['Follow']) + ], + 'object.actor' => 'required|url|active_url', + 'object.object' => 'required|url|active_url|same:actor', + ])->passes(); + + return $valid; + } +} \ No newline at end of file diff --git a/tests/Unit/ActivityPub/AcceptVerbTest.php b/tests/Unit/ActivityPub/AcceptVerbTest.php new file mode 100644 index 000000000..c949624db --- /dev/null +++ b/tests/Unit/ActivityPub/AcceptVerbTest.php @@ -0,0 +1,55 @@ +validAccept = [ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => 'https://example.org/og/b3e4a40b-0b26-4c5a-9079-094bd633fab7', + 'type' => 'Accept', + 'actor' => 'https://example.org/u/alice', + 'object' => [ + 'id' => 'https://example.net/u/bob#follows/bb27f601-ddb9-4567-8f16-023d90605ca9', + 'type' => 'Follow', + 'actor' => 'https://example.net/u/bob', + 'object' => 'https://example.org/u/alice' + ] + ]; + $this->invalidAccept = [ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => 'https://example.org/og/b3e4a40b-0b26-4c5a-9079-094bd633fab7', + 'type' => 'Accept2', + 'actor' => 'https://example.org/u/alice', + 'object' => [ + 'id' => 'https://example.net/u/bob#follows/bb27f601-ddb9-4567-8f16-023d90605ca9', + 'type' => 'Follow', + 'actor' => 'https://example.net/u/bob', + 'object' => 'https://example.org/u/alice' + ] + ]; + } + + /** @test */ + public function basic_accept() + { + $this->assertTrue(Accept::validate($this->validAccept)); + } + + /** @test */ + public function invalid_accept() + { + $this->assertFalse(Accept::validate($this->invalidAccept)); + } +} From 2d2c9a60f8b118b7fbe34c70ea820f4b9094be4a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 29 Dec 2018 21:50:37 -0700 Subject: [PATCH 29/29] Fixes #719, add blind key rotation --- app/Http/Controllers/FederationController.php | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index c93b1b664..508874341 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -180,6 +180,20 @@ XML; if($profile->status != null) { return ProfileController::accountCheck($profile); } + $body = $request->getContent(); + $bodyDecoded = json_decode($body, true, 8); + if($this->verifySignature($request, $profile) == true) { + InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded); + } else if($this->blindKeyRotation($request, $profile) == true) { + InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded); + } else { + abort(400, 'Bad Signature'); + } + return; + } + + protected function verifySignature(Request $request, Profile $profile) + { $body = $request->getContent(); $bodyDecoded = json_decode($body, true, 8); $signature = $request->header('signature'); @@ -209,11 +223,33 @@ XML; $pkey = openssl_pkey_get_public($actor->public_key); $inboxPath = "/users/{$profile->username}/inbox"; list($verified, $headers) = HTTPSignature::verify($pkey, $signatureData, $request->headers->all(), $inboxPath, $body); - if($verified !== 1) { - abort(400, 'Invalid signature.'); + if($verified == 1) { + return true; + } else { + return false; } - InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded); - return; + } + + protected function blindKeyRotation(Request $request, Profile $profile) + { + $signature = $request->header('signature'); + if(!$signature) { + abort(400, 'Missing signature header'); + } + $signatureData = HttpSignature::parseSignatureHeader($signature); + $keyId = Helpers::validateUrl($signatureData['keyId']); + $actor = Profile::whereKeyId($keyId)->first(); + $res = Zttp::timeout(5)->withHeaders([ + 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + 'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org', + ])->get($actor->remote_url); + $res = json_decode($res->body(), true, 8); + if($res['publicKey']['id'] !== $actor->key_id) { + return false; + } + $actor->public_key = $res['publicKey']['publicKeyPem']; + $actor->save(); + return $this->verifySignature($request, $profile); } public function userFollowing(Request $request, $username)