From becaa3b920bfe87c031c01bdf35d35db5c82e31e Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 17 Jun 2019 18:30:05 -0700 Subject: minor zot6 compatibility issues uncovered through daily use --- Zotlabs/Lib/Activity.php | 1 - 1 file changed, 1 deletion(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index bc86ae0e0..331e4f777 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -151,7 +151,6 @@ class Activity { static function fetch_image($x) { - $ret = [ 'type' => 'Image', 'id' => $x['id'], -- cgit v1.2.3 From 619b39f9553db3f88b5a8061c423f1eee37bdd3b Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 18 Jun 2019 10:33:30 +0200 Subject: fix typo --- Zotlabs/Lib/Activity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index bc86ae0e0..2998dbe98 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1570,7 +1570,7 @@ class Activity { $s['verb'] = self::activity_decode_mapper($act->type); - if($act->type === 'Tombstone' || $act-type === 'Delete' || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) { + if($act->type === 'Tombstone' || $act->type === 'Delete' || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) { $s['item_deleted'] = 1; } @@ -2253,4 +2253,4 @@ class Activity { } -} \ No newline at end of file +} -- cgit v1.2.3 From 9d156141b1205e48bbb3008f2a3040caa4c33192 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 19 Jun 2019 17:32:38 -0700 Subject: changes to support direct messages in zot6 (set item.item_private = 2 when private mentions are used and federate with zot:directMessage attribute which aligns with litepub:directMessage) --- Zotlabs/Lib/Activity.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 331e4f777..912b74a70 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -312,6 +312,10 @@ class Activity { } } + if (intval($i['item_private']) === 2) { + $ret['directMessage'] = true; + } + $ret['attributedTo'] = $i['author']['xchan_url']; if($i['id'] != $i['parent']) { @@ -1415,6 +1419,11 @@ class Activity { if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips))) $s['item_private'] = 1; + + if (array_key_exists('directMessage',$act->obj) && intval($act->obj['directMessage'])) { + $s['item_private'] = 2; + } + set_iconfig($s,'activitypub','recips',$act->raw_recips); if($parent) { set_iconfig($s,'activitypub','rawmsg',$act->raw,1); -- cgit v1.2.3 From 5ccef18d4e5b7901f78a11e0124c16e1c484e3bf Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 26 Jun 2019 14:00:44 +0200 Subject: port some functions from osada --- Zotlabs/Lib/Activity.php | 287 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 272 insertions(+), 15 deletions(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 931238a25..701e19d37 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1844,7 +1844,8 @@ class Activity { $s['item_private'] = 1; set_iconfig($s,'activitypub','recips',$act->raw_recips); - // @FIXME: $parent is not defined + + $parent = (($s['parent_mid'] && $s['parent_mid'] === $s['mid']) ? true : false); if($parent) { set_iconfig($s,'activitypub','rawmsg',$act->raw,1); } @@ -1853,6 +1854,266 @@ class Activity { } + static function store($channel,$observer_hash,$act,$item,$fetch_parents = true) { + + $is_sys_channel = is_sys_channel($channel['channel_id']); + + // Mastodon only allows visibility in public timelines if the public inbox is listed in the 'to' field. + // They are hidden in the public timeline if the public inbox is listed in the 'cc' field. + // This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point. + + $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); + + if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) { + logger('no permission'); + return; + } + + if(is_array($act->obj)) { + $content = self::get_content($act->obj); + } + if(! $content) { + logger('no content'); + return; + } + + $item['aid'] = $channel['channel_account_id']; + $item['uid'] = $channel['channel_id']; + $s['uuid'] = ''; + + // Friendica sends the diaspora guid in a nonstandard field via AP + if($act->obj['diaspora:guid']) + $s['uuid'] = $act->obj['diaspora:guid']; + + if(! ( $item['author_xchan'] && $item['owner_xchan'])) { + logger('owner or author missing.'); + return; + } + + if($channel['channel_system']) { + if(! MessageFilter::evaluate($item,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { + logger('post is filtered'); + return; + } + } + + $abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc($observer_hash), + intval($channel['channel_id']) + ); + + if($abook) { + if(! post_is_importable($item,$abook[0])) { + logger('post is filtered'); + return; + } + } + + + if($act->obj['conversation']) { + set_iconfig($item,'ostatus','conversation',$act->obj['conversation'],1); + } + + // This isn't perfect but the best we can do for now. + + $item['comment_policy'] = 'authenticated'; + + set_iconfig($item,'activitypub','recips',$act->raw_recips); + + $parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); + + if(! $parent) { + $p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + if(! $p) { + $a = (($fetch_parents) ? self::fetch_and_store_parents($channel,$act,$item) : false); + if($a) { + $p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + } + else { + logger('could not fetch parents'); + return; + + // @TODO we maybe could accept these is we formatted the body correctly with share_bb() + // or at least provided a link to the object + // if(in_array($act->type,[ 'Like','Dislike' ])) { + // return; + // } + + // @TODO do we actually want that? + // if no parent was fetched, turn into a top-level post + + // turn into a top level post + // $s['parent_mid'] = $s['mid']; + // $s['thr_parent'] = $s['mid']; + } + } + if($p[0]['parent_mid'] !== $item['parent_mid']) { + $item['thr_parent'] = $item['parent_mid']; + } + else { + $item['thr_parent'] = $p[0]['parent_mid']; + } + $item['parent_mid'] = $p[0]['parent_mid']; + } + + $r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", + dbesc($item['mid']), + intval($item['uid']) + ); + if($r) { + if($item['edited'] > $r[0]['edited']) { + $item['id'] = $r[0]['id']; + $x = item_store_update($item); + } + else { + return; + } + } + else { + $x = item_store($item); + } + + if(is_array($x) && $x['item_id']) { + if($parent) { + if($item['owner_xchan'] === $channel['channel_hash']) { + // We are the owner of this conversation, so send all received comments back downstream + Master::Summon(array('Notifier','comment-import',$x['item_id'])); + } + $r = q("select * from item where id = %d limit 1", + intval($x['item_id']) + ); + if($r) { + send_status_notifications($x['item_id'],$r[0]); + } + } + sync_an_item($channel['channel_id'],$x['item_id']); + } + + } + + static public function fetch_and_store_parents($channel,$act,$item) { + + logger('fetching parents'); + + $p = []; + + $current_act = $act; + $current_item = $item; + + while($current_item['parent_mid'] !== $current_item['mid']) { + $n = ActivityStreams::fetch($current_item['parent_mid'], $channel); + if(! $n) { + break; + } + $a = new ActivityStreams($n); + + logger($a->debug()); + + if(! $a->is_valid()) { + break; + } + + $replies = null; + if(isset($n['replies']['first']['items'])) { + $replies = $n['replies']['first']['items']; + // we already have this one + array_diff($replies, [$current_item['mid']]); + } + + $item = null; + + switch($a->type) { + case 'Create': + case 'Update': + case 'Like': + case 'Dislike': + case 'Announce': + $item = self::decode_note($a); + break; + default: + break; + + } + if(! $item) { + break; + } + + array_unshift($p,[ $a, $item, $replies]); + + if($item['parent_mid'] === $item['mid'] || count($p) > 20) { + break; + } + + $current_act = $a; + $current_item = $item; + } + + if($p) { + foreach($p as $pv) { + self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false); + if($pv[2]) + self::fetch_and_store_replies($channel, $pv[2]); + } + return true; + } + + return false; + } + + static public function fetch_and_store_replies($channel, $arr) { + + logger('fetching replies'); + + $p = []; + + foreach($arr as $url) { + + $n = ActivityStreams::fetch($url, $channel); + if(! $n) { + break; + } + + $a = new ActivityStreams($n); + + if(! $a->is_valid()) { + break; + } + + $item = null; + + switch($a->type) { + case 'Create': + case 'Update': + case 'Like': + case 'Dislike': + case 'Announce': + $item = self::decode_note($a); + break; + default: + break; + } + if(! $item) { + break; + } + + array_unshift($p,[ $a, $item ]); + + } + + if($p) { + foreach($p as $pv) { + self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false); + } + } + + } + static function announce_note($channel,$observer_hash,$act) { $s = []; @@ -1973,25 +2234,21 @@ class Activity { $x = item_store($s); } - if(is_array($x) && $x['item_id']) { - // @FIXME: $parent is not defined - if($parent) { - if($s['owner_xchan'] === $channel['channel_hash']) { - // We are the owner of this conversation, so send all received comments back downstream - Master::Summon(array('Notifier','comment-import',$x['item_id'])); - } - $r = q("select * from item where id = %d limit 1", - intval($x['item_id']) - ); - if($r) { - send_status_notifications($x['item_id'],$r[0]); - } + if($s['owner_xchan'] === $channel['channel_hash']) { + // We are the owner of this conversation, so send all received comments back downstream + Master::Summon(array('Notifier','comment-import',$x['item_id'])); } + $r = q("select * from item where id = %d limit 1", + intval($x['item_id']) + ); + if($r) { + send_status_notifications($x['item_id'],$r[0]); + } + sync_an_item($channel['channel_id'],$x['item_id']); } - } static function like_note($channel,$observer_hash,$act) { -- cgit v1.2.3 From cf844cb27c02c3aae636eb1aa1587b1d5e3e81a0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 26 Jun 2019 21:45:21 -0700 Subject: http signature consolidation --- Zotlabs/Lib/Activity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 912b74a70..d96ab95b0 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -3,7 +3,7 @@ namespace Zotlabs\Lib; use Zotlabs\Daemon\Master; -use Zotlabs\Zot6\HTTPSig; +use Zotlabs\Web\HTTPSig; require_once('include/event.php'); -- cgit v1.2.3 From 302d2dbd51dbea544ef1c3e5e1397b7c4201b230 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 27 Jun 2019 13:11:59 +0200 Subject: do not check send_stream permission for comments --- Zotlabs/Lib/Activity.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index f974d215b..f4307f490 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1863,8 +1863,9 @@ class Activity { // This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point. $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); + $is_parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) { + if($is_parent && (! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream))) { logger('no permission'); return; } @@ -1920,9 +1921,7 @@ class Activity { set_iconfig($item,'activitypub','recips',$act->raw_recips); - $parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); - - if(! $parent) { + if(! $is_parent) { $p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) @@ -1980,7 +1979,7 @@ class Activity { } if(is_array($x) && $x['item_id']) { - if($parent) { + if($is_parent) { if($item['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream Master::Summon(array('Notifier','comment-import',$x['item_id'])); @@ -2020,8 +2019,8 @@ class Activity { } $replies = null; - if(isset($n['replies']['first']['items'])) { - $replies = $n['replies']['first']['items']; + if(isset($a->obj['replies']['first']['items']))) { + $replies = $a->obj['replies']['first']['items']; // we already have this one array_diff($replies, [$current_item['mid']]); } -- cgit v1.2.3 From 145295302d74af176d3f25d871cf6979bf36bc23 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 27 Jun 2019 13:45:51 +0200 Subject: fix typo --- Zotlabs/Lib/Activity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index f4307f490..c70d5f4dc 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2019,7 +2019,7 @@ class Activity { } $replies = null; - if(isset($a->obj['replies']['first']['items']))) { + if(isset($a->obj['replies']['first']['items'])) { $replies = $a->obj['replies']['first']['items']; // we already have this one array_diff($replies, [$current_item['mid']]); -- cgit v1.2.3 From 39c0a7525b27fa2f8fff8a6d67104ed98acbf046 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 11 Jul 2019 20:47:38 -0700 Subject: emoji reactions from hubzilla becoming top level posts on zap because of missing object --- Zotlabs/Lib/Activity.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index c70d5f4dc..8168e7354 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -487,6 +487,19 @@ class Activity { $ret['type'] = self::activity_mapper($i['verb']); + if($ret['type'] === 'emojiReaction') { + // There may not be an object for these items for legacy reasons - it should be the conversation parent. + $p = q("select * from item where mid = '%s' and uid = %d", + dbesc($i['parent_mid']), + intval($i['uid']) + ); + if($p) { + xchan_query($p,true); + $p = fetch_post_tags($p,true); + $i['obj'] = self::encode_item($p[0]); + } + } + $ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/activity/' . urlencode($i['mid'])); -- cgit v1.2.3 From 71056e1db11caf7b30627bbdc5c44c21405966ae Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 18 Jul 2019 13:02:19 +0200 Subject: fix issue with encoding hashtags and silence parent fetch logging --- Zotlabs/Lib/Activity.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 8168e7354..bd84d877e 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -392,9 +392,9 @@ class Activity { foreach($item['term'] as $t) { switch($t['ttype']) { case TERM_HASHTAG: - // An id is required so if we don't have a url in the taxonomy, ignore it and keep going. + // href is required so if we don't have a url in the taxonomy, ignore it and keep going. if($t['url']) { - $ret[] = [ 'id' => $t['url'], 'name' => '#' . $t['term'] ]; + $ret[] = [ 'type' => 'Hashtag', 'href' => $t['url'], 'name' => '#' . $t['term'] ]; } break; @@ -2025,7 +2025,7 @@ class Activity { } $a = new ActivityStreams($n); - logger($a->debug()); + //logger($a->debug()); if(! $a->is_valid()) { break; -- cgit v1.2.3 From 8ced3699c21bd76f1a1f3c08b97dd7bf41d3e88a Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 18 Jul 2019 13:52:39 +0200 Subject: fallback to id if href is not available --- Zotlabs/Lib/Activity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index bd84d877e..520c456cc 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -361,7 +361,7 @@ class Activity { switch($t['type']) { case 'Hashtag': - $ret[] = [ 'ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'],0,1) === '#') ? substr($t['name'],1) : $t['name']) ]; + $ret[] = [ 'ttype' => TERM_HASHTAG, 'url' => ((isset($t['href'])) ? $t['href'] : $t['id']), 'term' => escape_tags((substr($t['name'],0,1) === '#') ? substr($t['name'],1) : $t['name']) ]; break; case 'Mention': -- cgit v1.2.3 From ad58697521dcdca8f4f38db9f69588d7d27df486 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 19 Jul 2019 18:45:34 +0200 Subject: move image attachments to the top --- Zotlabs/Lib/Activity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 520c456cc..0808228a6 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1769,14 +1769,14 @@ class Activity { } foreach($ptr as $vurl) { if(strpos($s['body'],$vurl['href']) === false) { - $s['body'] .= "\n\n" . '[zmg]' . $vurl['href'] . '[/zmg]'; + $s['body'] .= '[zmg]' . $vurl['href'] . '[/zmg]' . "\n\n" . $s['body']; break; } } } elseif(is_string($act->obj['url'])) { if(strpos($s['body'],$act->obj['url']) === false) { - $s['body'] .= "\n\n" . '[zmg]' . $act->obj['url'] . '[/zmg]'; + $s['body'] .= '[zmg]' . $act->obj['url'] . '[/zmg]' . "\n\n" . $s['body']; } } } -- cgit v1.2.3 From 130cfbf2317f1fce9cd73b40cf58a06180875c67 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 9 Aug 2019 20:33:03 +0200 Subject: make fetch logging less chatty --- Zotlabs/Lib/Activity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Lib/Activity.php') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 0808228a6..f86dc1604 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -75,7 +75,7 @@ class Activity { if($x['success']) { $y = json_decode($x['body'],true); - logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); + logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DEBUG); return json_decode($x['body'], true); } else { -- cgit v1.2.3