diff options
author | Mario <mario@mariovavti.com> | 2023-07-11 18:57:18 +0000 |
---|---|---|
committer | Mario <mario@mariovavti.com> | 2023-07-11 18:57:18 +0000 |
commit | 63fb8d03929189bfc8cbf53d23cb79984fe2c3cd (patch) | |
tree | b9f74bd8c7721dca7ece251fdbb9a7c4fe9b949a /Zotlabs/Lib | |
parent | 57796a2f962d045445cbf69237bb3d6786e4d0d4 (diff) | |
parent | 384de0925e502cfa8fe6ca287530ef5529fdff10 (diff) | |
download | volse-hubzilla-8.6.tar.gz volse-hubzilla-8.6.tar.bz2 volse-hubzilla-8.6.zip |
Merge branch '8.6RC'8.6
Diffstat (limited to 'Zotlabs/Lib')
-rw-r--r-- | Zotlabs/Lib/Activity.php | 154 | ||||
-rw-r--r-- | Zotlabs/Lib/ActivityStreams.php | 33 | ||||
-rw-r--r-- | Zotlabs/Lib/Enotify.php | 15 | ||||
-rw-r--r-- | Zotlabs/Lib/IConfig.php | 14 | ||||
-rw-r--r-- | Zotlabs/Lib/Libsync.php | 2 | ||||
-rw-r--r-- | Zotlabs/Lib/Libzot.php | 8 | ||||
-rw-r--r-- | Zotlabs/Lib/ThreadItem.php | 5 |
7 files changed, 162 insertions, 69 deletions
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index ced361fe5..992ade200 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -50,7 +50,27 @@ class Activity { } + public static function fetch_local($url, $portable_id) { + $sql_extra = item_permissions_sql(0, $portable_id); + $item_normal = item_normal(); + + // Find the original object + $j = q( + "select *, id as item_id from item where mid = '%s' and item_wall = 1 $item_normal $sql_extra", + dbesc($url) + ); + if ($j) { + xchan_query($j, true); + $items = fetch_post_tags($j); + } + if ($items) { + return self::encode_item(array_shift($items), true); + } + return null; + } + static function fetch($url, $channel = null) { + $redirects = 0; if (!check_siteallowed($url)) { logger('blacklisted: ' . $url); @@ -459,6 +479,30 @@ class Activity { $ret['id'] = ((strpos($i['mid'], 'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid'])); $ret['diaspora:guid'] = $i['uuid']; + $images = []; + $has_images = preg_match_all('/\[[zi]mg(.*?)](.*?)\[/ism', $i['body'], $images, PREG_SET_ORDER); + + // provide ocap access token for private media. + // set this for descendants even if the current item is not private + // because it may have been relayed from a private item. + + $token = get_iconfig($i, 'ocap', 'relay'); + if ($token && $has_images) { + $matches_processed = []; + for ($n = 0; $n < count($images); $n++) { + $match = $images[$n]; + if (str_starts_with($match[1], '=http') && str_contains($match[1], z_root() . '/photo/') && !in_array($match[1], $matches_processed)) { + $i['body'] = str_replace($match[1], $match[1] . '?token=' . $token, $i['body']); + $images[$n][2] = substr($match[1], 1) . '?token=' . $token; + $matches_processed[] = $match[1]; + } elseif (str_contains($match[2], z_root() . '/photo/') && !in_array($match[2], $matches_processed)) { + $i['body'] = str_replace($match[2], $match[2] . '?token=' . $token, $i['body']); + $images[$n][2] = $match[2] . '?token=' . $token; + $matches_processed[] = $match[2]; + } + } + } + if ($i['title']) $ret['name'] = $i['title']; @@ -627,10 +671,10 @@ class Activity { } if (isset($att['type']) && strpos($att['type'], 'image')) { - $ret[] = ['type' => 'Image', 'url' => $att['href']]; + $ret[] = ['type' => 'Image', 'mediaType' => $att['type'], 'name' => $att['title'], 'url' => $att['href']]; } else { - $ret[] = ['type' => 'Link', 'mediaType' => $att['type'], 'href' => $att['href']]; + $ret[] = ['type' => 'Link', 'mediaType' => $att['type'], 'name' => $att['title'], 'href' => $att['href']]; } } } @@ -841,7 +885,7 @@ class Activity { if (isset($i['app']) && $i['app']) { $ret['generator'] = ['type' => 'Application', 'name' => $i['app']]; } - if (isset($i['location']) || isset($i['coord'])) { + if (!empty($i['location']) || !empty($i['coord'])) { $ret['location'] = ['type' => 'Place']; if ($i['location']) { $ret['location']['name'] = $i['location']; @@ -929,7 +973,6 @@ class Activity { ]; call_hooks('encode_activity', $hookinfo); - return $hookinfo['encoded']; } @@ -974,10 +1017,14 @@ class Activity { $tmp = expand_acl($i['allow_cid']); $list = stringify_array($tmp, true); if ($list) { - $details = q("select hubloc_id_url from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != '' and hubloc_deleted = 0"); + $details = q("select hubloc_id_url, hubloc_hash, hubloc_network from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != '' and hubloc_deleted = 0"); if ($details) { foreach ($details as $d) { - $ret[] = $d['hubloc_id_url']; + if ($d['hubloc_network'] === 'activitypub') { + $ret[] = $d['hubloc_hash']; + } else { + $ret[] = $d['hubloc_id_url']; + } } } } @@ -1007,16 +1054,19 @@ class Activity { static function encode_person($p, $extended = true) { - if (!$p['xchan_url']) - return []; + $c = ((array_key_exists('channel_id', $p)) ? $p : channelx_by_hash($p['xchan_hash'])); - if (!$extended) { - return $p['xchan_url']; - } + $id = (($c) ? channel_url($c) : ((filter_var($p['xchan_hash'], FILTER_VALIDATE_URL)) ? $p['xchan_hash'] : $p['xchan_url'])); - $ret = []; + $ret = (($extended) ? [] : ''); - $c = ((array_key_exists('channel_id', $p)) ? $p : channelx_by_hash($p['xchan_hash'])); + if (!$id) { + return $ret; + } + + if (!$extended) { + return $id; + } $ret['type'] = 'Person'; @@ -1028,15 +1078,9 @@ class Activity { $ret['manuallyApprovesFollowers'] = ((get_pconfig($c['channel_id'], 'system', 'autoperms')) ? false : true); } - if ($c) { - $ret['id'] = channel_url($c); - } - else { - $ret['id'] = ((strpos($p['xchan_hash'], 'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); - } + $ret['id'] = $id; - if ($p['xchan_addr'] && strpos($p['xchan_addr'], '@')) - $ret['preferredUsername'] = substr($p['xchan_addr'], 0, strpos($p['xchan_addr'], '@')); + $ret['preferredUsername'] = (($c) ? $c['channel_address'] : substr($p['xchan_addr'], 0, strpos($p['xchan_addr'], '@'))); $ret['name'] = $p['xchan_name']; $ret['updated'] = datetime_convert('UTC', 'UTC', $p['xchan_name_date'], ATOM_TIME); @@ -1074,11 +1118,11 @@ class Activity { ]; */ - $ret['url'] = $p['xchan_url']; + $ret['url'] = $id; $ret['publicKey'] = [ - 'id' => $p['xchan_url'], - 'owner' => $p['xchan_url'], + 'id' => $id, + 'owner' => $id, 'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', 'publicKeyPem' => $p['xchan_pubkey'] ]; @@ -1101,6 +1145,7 @@ class Activity { call_hooks('encode_person', $arr); $ret = $arr['encoded']; + return $ret; } @@ -1541,10 +1586,17 @@ class Activity { } if (in_array($observer, [$r[0]['author_xchan'], $r[0]['owner_xchan']])) { - drop_item($r[0]['id'], false); + drop_item($r[0]['id'], false, (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); } elseif (in_array($act->actor['id'], [$r[0]['author_xchan'], $r[0]['owner_xchan']])) { - drop_item($r[0]['id'], false); + drop_item($r[0]['id'], false, (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + } + + sync_an_item($channel['channel_id'], $r[0]['id']); + + if ($r[0]['item_wall']) { + Master::Summon(['Notifier', 'drop', $r[0]['id']]); } + } @@ -2113,6 +2165,10 @@ class Activity { return false; } + if (intval($post['item_blocked']) === ITEM_MODERATED) { + return false; + } + dbq("START TRANSACTION"); $item = q("SELECT * FROM item WHERE id = %d FOR UPDATE", @@ -2888,6 +2944,12 @@ class Activity { // TODO: if we do not have a parent stop here and move the fetch to background? + if ($parent && $parent[0]['obj_type'] === 'Question') { + if ($item['obj_type'] === ACTIVITY_OBJ_COMMENT && $item['title'] && (!$item['body'])) { + $item['obj_type'] = 'Answer'; + } + } + if ($parent && $parent[0]['item_wall']) { // set the owner to the owner of the parent $item['owner_xchan'] = $parent[0]['owner_xchan']; @@ -2920,13 +2982,20 @@ class Activity { }*/ if (!$allowed) { - logger('rejected comment from ' . $item['author_xchan'] . ' for ' . $channel['channel_address']); - logger('rejected: ' . print_r($item, true), LOGGER_DATA); + if (get_pconfig($channel['channel_id'], 'system', 'moderate_unsolicited_comments') && $item['obj_type'] !== 'Answer') { + $item['item_blocked'] = ITEM_MODERATED; + $allowed = true; + } + else { + logger('rejected comment from ' . $item['author_xchan'] . ' for ' . $channel['channel_address']); + logger('rejected: ' . print_r($item, true), LOGGER_DATA); - // TODO: not implemented - // let the sender know we received their comment but we don't permit spam here. - // self::send_rejection_activity($channel,$item['author_xchan'],$item); - return; + // TODO: not implemented + // let the sender know we received their comment but we don't permit spam here. + // self::send_rejection_activity($channel,$item['author_xchan'],$item); + + return; + } } // TODO: not implemented @@ -2935,7 +3004,6 @@ class Activity { }*/ } else { - $allowed = true; // reject public stream comments that weren't sent by the conversation owner @@ -2943,12 +3011,6 @@ class Activity { $allowed = false; } } - - if ($parent && $parent[0]['obj_type'] === 'Question') { - if ($item['obj_type'] === ACTIVITY_OBJ_COMMENT && $item['title'] && (!$item['body'])) { - $item['obj_type'] = 'Answer'; - } - } } else { @@ -3128,6 +3190,16 @@ class Activity { } } + // private conversation, but this comment went rogue and was published publicly + // hide it from everybody except the channel owner + + if (intval($parent[0]['item_private'])) { + if (!intval($item['item_private'])) { + $item['item_private'] = intval($parent_item['item_private']); + $item['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + $item['allow_gid'] = $item['deny_cid'] = $item['deny_gid'] = ''; + } + } } // An ugly and imperfect way to recognise a mastodon direct message @@ -3143,7 +3215,6 @@ class Activity { // TODO: not implemented // self::rewrite_mentions($item); - $r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($item['uid']) @@ -3896,12 +3967,11 @@ class Activity { } if (array_path_exists('source/mediaType', $act) && array_path_exists('source/content', $act)) { - if (in_array($act['source']['mediaType'], ['text/bbcode', 'text/x-multicode'])) { + if (in_array($act['source']['mediaType'], ['text/bbcode'])) { $content['bbcode'] = purify_html($act['source']['content']); } } - return $content; } diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php index f07f99ac3..8b8c95ad8 100644 --- a/Zotlabs/Lib/ActivityStreams.php +++ b/Zotlabs/Lib/ActivityStreams.php @@ -14,6 +14,7 @@ class ActivityStreams { public $meta = null; public $valid = false; public $deleted = false; + public $portable_id = null; public $id = ''; public $parent_id = ''; public $type = ''; @@ -35,12 +36,13 @@ class ActivityStreams { * * @param string $string */ - function __construct($string) { + function __construct($string, $portable_id = null) { if(!$string) return; $this->raw = $string; + $this->portable_id = $portable_id; if (is_array($string)) { $this->data = $string; @@ -123,13 +125,14 @@ class ActivityStreams { $this->parent_id = $this->get_property_obj('inReplyTo'); - if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['inReplyTo'])) { + if (!$this->parent_id && is_array($this->obj) && isset($this->obj['inReplyTo'])) { $this->parent_id = $this->obj['inReplyTo']; } - if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['id'])) { + if (!$this->parent_id && is_array($this->obj) && isset($this->obj['id'])) { $this->parent_id = $this->obj['id']; } + } } @@ -302,12 +305,26 @@ class ActivityStreams { * @return NULL|mixed */ - function fetch_property($url) { - return self::fetch($url); - } + function fetch_property($url, $channel = null) { + $x = null; + + if (str_starts_with($url, z_root() . '/item/')) { + $x = Activity::fetch_local($url, $this->portable_id ?? ''); + logger('local: ' . print_r($x,true)); + } + + if (!$x) { + $x = Activity::fetch($url, $channel); + if ($x === null && strpos($url, '/channel/')) { + // look for other nomadic channels which might be alive + $zf = Zotfinger::exec($url, $channel); - static function fetch($url, $channel = null) { - return Activity::fetch($url, $channel); + $url = $zf['signature']['signer']; + $x = Activity::fetch($url, $channel); + } + } + + return $x; } static function is_an_actor($s) { diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index 585761cc4..c3f96e103 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -145,7 +145,7 @@ class Enotify { $itemlink = $params['link']; - $action = t('commented on'); + $action = (($moderated) ? t('requested to comment on') : t('commented on')); if(array_key_exists('item',$params)) { @@ -158,10 +158,10 @@ class Enotify { } if(activity_match($params['verb'], ACTIVITY_LIKE)) - $action = t('liked'); + $action = (($moderated) ? t('requested to like') : t('liked')); if(activity_match($params['verb'], ACTIVITY_DISLIKE)) - $action = t('disliked'); + $action = (($moderated) ? t('requested to dislike') : t('disliked')); } @@ -307,7 +307,14 @@ class Enotify { $parent_item = $p[0]; - $verb = ((activity_match($params['item']['verb'], ACTIVITY_DISLIKE)) ? t('disliked') : t('liked')); + //$verb = ((activity_match($params['item']['verb'], ACTIVITY_DISLIKE)) ? t('disliked') : t('liked')); + $moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false); + + if(activity_match($params['item']['verb'], ACTIVITY_LIKE)) + $verb = (($moderated) ? t('requested to like') : t('liked')); + + if(activity_match($params['item']['verb'], ACTIVITY_DISLIKE)) + $verb = (($moderated) ? t('requested to dislike') : t('disliked')); // "your post" if($p[0]['owner']['xchan_name'] === $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) diff --git a/Zotlabs/Lib/IConfig.php b/Zotlabs/Lib/IConfig.php index 33d94bd49..74c1107f0 100644 --- a/Zotlabs/Lib/IConfig.php +++ b/Zotlabs/Lib/IConfig.php @@ -13,7 +13,7 @@ class IConfig { static public function Get(&$item, $family, $key, $default = false) { $is_item = false; - + if(is_array($item)) { $is_item = true; if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) @@ -22,7 +22,7 @@ class IConfig { if(array_key_exists('item_id',$item)) $iid = $item['item_id']; else - $iid = $item['id']; + $iid = $item['id'] ?? 0; } elseif(intval($item)) $iid = $item; @@ -36,7 +36,7 @@ class IConfig { return $c['v']; } } - + $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1", intval($iid), dbesc($family), @@ -63,11 +63,11 @@ class IConfig { * $value - value of meta variable * $sharing - boolean (default false); if true the meta information is propagated with the item * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered. - * If the meta information is added after delivery and you wish it to be shared, it may be necessary to - * alter the item edited timestamp and invoke the delivery process on the updated item. The edited + * If the meta information is added after delivery and you wish it to be shared, it may be necessary to + * alter the item edited timestamp and invoke the delivery process on the updated item. The edited * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end. */ - + static public function Set(&$item, $family, $key, $value, $sharing = false) { @@ -162,4 +162,4 @@ class IConfig { } -}
\ No newline at end of file +} diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index 0d383c697..5f183192d 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -328,7 +328,7 @@ class Libsync { $remote_channel = $arr['channel']; $remote_channel['channel_id'] = $channel['channel_id']; - if (array_key_exists('channel_pageflags', $arr['channel']) && intval($arr['channel']['channel_pageflags'])) { + if (array_key_exists('channel_pageflags', $arr['channel'])) { // Several pageflags are site-specific and cannot be sync'd. // Only allow those bits which are shareable from the remote and then diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 093670338..032fae3fc 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -1219,17 +1219,13 @@ class Libzot { return; } - $r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_deleted = 0 order by hubloc_id desc", - dbesc($AS->actor['id']) - ); + $r = Activity::get_actor_hublocs($AS->actor['id']); if (! $r) { // Author is unknown to this site. Perform channel discovery and try again. $z = discover_by_webbie($AS->actor['id']); if ($z) { - $r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_deleted = 0 order by hubloc_id desc", - dbesc($AS->actor['id']) - ); + $r = Activity::get_actor_hublocs($AS->actor['id']); } } diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index cf877ed92..14c9500ff 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -503,7 +503,10 @@ class ThreadItem { 'thread_level' => $thread_level, 'settings' => $settings, 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : ''), - 'contact_id' => (($contact) ? $contact['abook_id'] : '') + 'contact_id' => (($contact) ? $contact['abook_id'] : ''), + 'moderate' => ($item['item_blocked'] == ITEM_MODERATED), + 'moderate_approve' => t('Approve'), + 'moderate_delete' => t('Delete') ); |