[ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', z_root() . ZOT_APSCHEMA_REV ]], [ 'id' => z_root() . '/follow/' . $r[0]['abook_id'], 'type' => 'Follow', 'actor' => $actor, 'object' => $r[0]['xchan_url'] ]); $headers = []; $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; $x['signature'] = LDSignatures::sign($x,$chan); $ret = json_encode($x, JSON_UNESCAPED_SLASHES); $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); $headers['Digest'] = HTTPSig::generate_digest_header($ret); $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; $h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan)); HTTPSig::set_headers($h); echo $ret; killme(); } $uid = local_channel(); if (! $uid) { return; } $url = notags(trim(punify($_REQUEST['url']))); $return_url = $_SESSION['return_url']; $confirm = intval($_REQUEST['confirm']); $interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1); $channel = App::get_channel(); $result = Connect::connect($channel,$url); if ($result['success'] == false) { if ((strpos($url,'http') === 0) || strpos($url,'bear:') === 0 || strpos($url,'x-zot:') === 0) { $n = Activity::fetch($url); if ($n) { // set client flag to convert objects to implied activities $a = new ActivityStreams($n,null,true); if ($a->type === 'Announce' && is_array($a->obj) && array_key_exists('object',$a->obj) && array_key_exists('actor',$a->obj)) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity',LOGGER_DEBUG); $a = new ActivityStreams($a->obj,null,true); } if ($a->is_valid()) { if (is_array($a->actor) && array_key_exists('id',$a->actor)) { Activity::actor_store($a->actor['id'],$a->actor); } // ActivityPub sourced items are cacheable $item = Activity::decode_note($a,true); if ($item) { Activity::store($channel,get_observer_hash(),$a,$item,false); } } } } $r = q("select * from item where mid = '%s' and uid = %d", dbesc($url), intval($uid) ); if ($r) { if ($interactive) { goaway(z_root() . '/display/' . gen_link_id($url)); } else { $result['success'] = true; json_return_and_die($result); } } if ($result['message']) { notice($result['message']); } if ($interactive) { goaway($return_url); } else { json_return_and_die($result); } } info( t('Connection added.') . EOL); $clone = array(); foreach ($result['abook'] as $k => $v) { if (strpos($k,'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); if ($abconfig) { $clone['abconfig'] = $abconfig; } Libsync::build_sync_packet(0, [ 'abook' => [ $clone ] ], true); $can_view_stream = their_perms_contains($channel['channel_id'],$clone['abook_xchan'],'view_stream'); // If we can view their stream, pull in some posts if (($can_view_stream) || ($result['abook']['xchan_network'] === 'rss')) { Run::Summon([ 'Onepoll', $result['abook']['abook_id'] ]); } if ($interactive) { goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?follow=1'); } else { json_return_and_die([ 'success' => true ]); } } function get() { if (! local_channel()) { return login(); } } }