streams/Zotlabs/Lib/Libsync.php

1179 lines
34 KiB
PHP
Raw Normal View History

2018-06-05 01:40:11 +00:00
<?php
namespace Zotlabs\Lib;
2018-08-28 01:58:47 +00:00
use App;
2018-06-05 01:40:11 +00:00
use Zotlabs\Lib\Libzot;
2018-07-03 05:43:41 +00:00
use Zotlabs\Lib\Queue;
2019-10-13 22:49:50 +00:00
use Zotlabs\Lib\Connect;
2019-10-21 01:14:52 +00:00
use Zotlabs\Lib\DReport;
use Zotlabs\Daemon\Run;
2018-06-05 01:40:11 +00:00
class Libsync {
/**
* @brief Builds and sends a sync packet.
*
* Send a zot packet to all hubs where this channel is duplicated, refreshing
* such things as personal settings, channel permissions, address book updates, etc.
*
2019-10-21 01:14:52 +00:00
* By default, sync the channel and any pconfig changes which were made in the current process
* AccessLists (aka privacy groups) will also be included if $groups_changed is true.
* To include other data sources, provide them as $packet.
*
2018-06-05 01:40:11 +00:00
* @param int $uid (optional) default 0
* @param array $packet (optional) default null
* @param boolean $groups_changed (optional) default false
*/
2018-06-05 01:40:11 +00:00
static function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
2019-10-21 01:14:52 +00:00
//logger('build_sync_packet');
2018-06-05 01:40:11 +00:00
$keychange = (($packet && array_key_exists('keychange',$packet)) ? true : false);
2019-10-21 01:14:52 +00:00
if ($keychange) {
2018-06-05 01:40:11 +00:00
logger('keychange sync');
}
2019-10-21 01:14:52 +00:00
if (! $uid) {
2018-06-05 01:40:11 +00:00
$uid = local_channel();
2019-10-21 01:14:52 +00:00
}
if (! $uid) {
2018-06-05 01:40:11 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2018-08-28 02:13:55 +00:00
$channel = channelx_by_n($uid);
2019-10-21 01:14:52 +00:00
if (! $channel) {
2018-06-05 01:40:11 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
// don't provide these in the export
unset($channel['channel_active']);
unset($channel['channel_password']);
unset($channel['channel_salt']);
2019-10-21 01:14:52 +00:00
$h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url
where hubloc_hash = '%s' and hubloc_network = 'zot6' and hubloc_deleted = 0",
2018-06-05 01:40:11 +00:00
dbesc(($keychange) ? $packet['keychange']['old_hash'] : $channel['channel_hash'])
);
2019-10-21 01:14:52 +00:00
if (! $h) {
2018-06-05 01:40:11 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
$synchubs = [];
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
foreach ($h as $x) {
if ($x['hubloc_host'] == App::get_hostname()) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
$y = q("select site_dead from site where site_url = '%s' limit 1",
dbesc($x['hubloc_url'])
);
2019-10-21 01:14:52 +00:00
if ((! $y) || ($y[0]['site_dead'] == 0)) {
2018-06-05 01:40:11 +00:00
$synchubs[] = $x;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
2019-10-21 01:14:52 +00:00
if (! $synchubs) {
2018-06-05 01:40:11 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
$env_recips = [ $channel['channel_hash'] ];
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if ($packet) {
2018-06-05 01:40:11 +00:00
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
2019-10-21 01:14:52 +00:00
}
$info = (($packet) ? $packet : [] );
2018-07-30 06:12:05 +00:00
$info['type'] = 'sync';
2018-06-05 01:40:11 +00:00
$info['encoding'] = 'red'; // note: not zot, this packet is very platform specific
$info['relocate'] = ['channel_address' => $channel['channel_address'], 'url' => z_root() ];
2019-10-21 01:14:52 +00:00
if (array_key_exists($uid, App::$config) && array_key_exists('transient', App::$config[$uid])) {
2018-08-28 01:58:47 +00:00
$settings = App::$config[$uid]['transient'];
2019-10-21 01:14:52 +00:00
if ($settings) {
2018-06-05 01:40:11 +00:00
$info['config'] = $settings;
}
}
2019-10-21 01:14:52 +00:00
if ($channel) {
$info['channel'] = [];
foreach ($channel as $k => $v) {
2018-06-05 01:40:11 +00:00
// filter out any joined tables like xchan
2019-10-21 01:14:52 +00:00
if (strpos($k,'channel_') !== 0) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
// don't pass these elements, they should not be synchronised
2019-10-21 01:14:52 +00:00
$disallowed = [ 'channel_id','channel_account_id','channel_primary','channel_address',
'channel_deleted','channel_removed','channel_system' ];
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (! $keychange) {
2018-06-05 01:40:11 +00:00
$disallowed[] = 'channel_prvkey';
}
2019-10-21 01:14:52 +00:00
if (in_array($k,$disallowed)) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
$info['channel'][$k] = $v;
}
}
2019-10-21 01:14:52 +00:00
if ($groups_changed) {
2020-07-22 01:16:27 +00:00
$r = q("select hash as collection, visible, deleted, gname as name from pgrp where uid = %d and rule = '' ",
2018-06-05 01:40:11 +00:00
intval($uid)
);
2019-10-21 01:14:52 +00:00
if ($r) {
2018-06-05 01:40:11 +00:00
$info['collections'] = $r;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
$r = q("select pgrp.hash as collection, pgrp_member.xchan as member from pgrp left join pgrp_member on pgrp.id = pgrp_member.gid
2020-07-22 01:16:27 +00:00
where pgrp_member.uid = %d and pgrp.rule = '' ",
2018-06-05 01:40:11 +00:00
intval($uid)
);
2019-10-21 01:14:52 +00:00
if ($r) {
2018-06-05 01:40:11 +00:00
$info['collection_members'] = $r;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
2019-10-21 01:14:52 +00:00
$interval = get_config('system','delivery_interval', 2);
2018-06-05 01:40:11 +00:00
logger('Packet: ' . print_r($info,true), LOGGER_DATA, LOG_DEBUG);
$total = count($synchubs);
2019-10-21 01:14:52 +00:00
foreach ($synchubs as $hub) {
2018-06-05 01:40:11 +00:00
$hash = random_string();
2018-07-30 06:12:05 +00:00
$n = Libzot::build_packet($channel,'sync',$env_recips,json_encode($info),'red',$hub['hubloc_sitekey'],$hub['site_crypto']);
2019-10-21 01:14:52 +00:00
Queue::insert([
2018-06-05 01:40:11 +00:00
'hash' => $hash,
'account_id' => $channel['channel_account_id'],
'channel_id' => $channel['channel_id'],
'posturl' => $hub['hubloc_callback'],
'notify' => $n,
'msg' => EMPTY_STR
2019-10-21 01:14:52 +00:00
]);
2018-06-05 01:40:11 +00:00
$x = q("select count(outq_hash) as total from outq where outq_delivered = 0");
2019-10-21 01:14:52 +00:00
if (intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',3000))) {
2018-06-05 01:40:11 +00:00
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
2018-07-03 05:43:41 +00:00
Queue::update($hash);
2018-06-05 01:40:11 +00:00
continue;
}
Run::Summon([ 'Deliver', $hash ]);
2018-06-05 01:40:11 +00:00
$total = $total - 1;
2019-10-21 01:14:52 +00:00
if ($interval && $total) {
2018-06-05 01:40:11 +00:00
@time_sleep_until(microtime(true) + (float) $interval);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
}
2018-08-28 01:58:47 +00:00
static function build_link_packet($uid = 0, $packet = null) {
2019-10-21 01:14:52 +00:00
// logger('build_link_packet');
2018-08-28 01:58:47 +00:00
2019-10-21 01:14:52 +00:00
if (! $uid) {
2018-08-28 01:58:47 +00:00
$uid = local_channel();
2019-10-21 01:14:52 +00:00
}
if (! $uid) {
2018-08-28 01:58:47 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
2018-08-28 02:12:00 +00:00
$channel = channelx_by_n($uid);
2019-10-21 01:14:52 +00:00
if (! $channel) {
2018-08-28 01:58:47 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
$l = q("select link from linkid where ident = '%s' and sigtype = 2",
dbesc($channel['channel_hash'])
);
2019-10-21 01:14:52 +00:00
if (! $l) {
2018-08-28 01:58:47 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
$hashes = ids_to_querystr($l,'link',true);
2018-09-24 00:03:10 +00:00
$h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash in (" . protect_sprintf($hashes) . ") and hubloc_network = 'zot6' and hubloc_deleted = 0");
2018-08-28 01:58:47 +00:00
2019-10-21 01:14:52 +00:00
if (! $h) {
2018-08-28 01:58:47 +00:00
return;
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
2019-10-21 01:14:52 +00:00
$interval = get_config('system','delivery_interval',2);
2018-08-28 01:58:47 +00:00
2019-10-21 01:14:52 +00:00
foreach ($h as $x) {
if ($x['hubloc_host'] == App::get_hostname()) {
2018-08-28 01:58:47 +00:00
continue;
}
$y = q("select site_dead from site where site_url = '%s' limit 1",
dbesc($x['hubloc_url'])
);
2019-10-21 01:14:52 +00:00
if (($y) && (intval($y[0]['site_dead']) == 1)) {
2018-08-28 01:58:47 +00:00
$continue;
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
$env_recips = [ $x['hubloc_hash'] ];
2019-10-21 01:14:52 +00:00
if ($packet) {
2018-08-28 01:58:47 +00:00
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
$info = (($packet) ? $packet : []);
$info['type'] = 'sync';
$info['encoding'] = 'red'; // note: not zot, this packet is very platform specific
logger('Packet: ' . print_r($info,true), LOGGER_DATA, LOG_DEBUG);
$hash = random_string();
$n = Libzot::build_packet($channel,'sync',$env_recips,json_encode($info),'red',$x['hubloc_sitekey'],$x['site_crypto']);
Queue::insert([
'hash' => $hash,
'account_id' => $channel['channel_account_id'],
'channel_id' => $channel['channel_id'],
'posturl' => $x['hubloc_callback'],
'notify' => $n,
'msg' => EMPTY_STR
]);
$y = q("select count(outq_hash) as total from outq where outq_delivered = 0");
2019-10-21 01:14:52 +00:00
if (intval($y[0]['total']) > intval(get_config('system','force_queue_threshold',3000))) {
2018-08-28 01:58:47 +00:00
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
Queue::update($hash);
continue;
}
Run::Summon([ 'Deliver', $hash ]);
2018-08-28 01:58:47 +00:00
2019-10-21 01:14:52 +00:00
if ($interval && count($h) > 1) {
2018-08-28 01:58:47 +00:00
@time_sleep_until(microtime(true) + (float) $interval);
2019-10-21 01:14:52 +00:00
}
2018-08-28 01:58:47 +00:00
}
}
2018-06-05 01:40:11 +00:00
/**
* @brief
*
* @param array $sender
* @param array $arr
* @param array $deliveries
* @return array
*/
static function process_channel_sync_delivery($sender, $arr, $deliveries) {
require_once('include/import.php');
$result = [];
$keychange = ((array_key_exists('keychange',$arr)) ? true : false);
foreach ($deliveries as $d) {
2018-08-28 01:58:47 +00:00
$linked_channel = false;
2018-06-05 01:40:11 +00:00
$r = q("select * from channel where channel_hash = '%s' limit 1",
2018-07-30 05:13:43 +00:00
dbesc($sender)
2018-06-05 01:40:11 +00:00
);
2019-10-21 01:14:52 +00:00
$DR = new DReport(z_root(),$sender,$d,'sync');
2018-07-30 05:13:43 +00:00
2019-10-21 01:14:52 +00:00
if (! $r) {
2018-08-28 01:58:47 +00:00
$l = q("select ident from linkid where link = '%s' and sigtype = 2 limit 1",
dbesc($sender)
);
2019-10-21 01:14:52 +00:00
if ($l) {
2018-08-28 01:58:47 +00:00
$linked_channel = true;
$r = q("select * from channel where channel_hash = '%s' limit 1",
dbesc($l[0]['ident'])
);
}
}
2018-06-05 01:40:11 +00:00
if (! $r) {
2018-07-30 05:13:43 +00:00
$DR->update('recipient not found');
$result[] = $DR->get();
2018-06-05 01:40:11 +00:00
continue;
}
$channel = $r[0];
2018-07-30 06:49:37 +00:00
$DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>');
2018-06-05 01:40:11 +00:00
$max_friends = service_class_fetch($channel['channel_id'],'total_channels');
$max_feeds = account_service_class_fetch($channel['channel_account_id'],'total_feeds');
2019-10-21 01:14:52 +00:00
if ($channel['channel_hash'] != $sender && (! $linked_channel)) {
2018-07-30 05:13:43 +00:00
logger('Possible forgery. Sender ' . $sender . ' is not ' . $channel['channel_hash']);
$DR->update('channel mismatch');
$result[] = $DR->get();
2018-06-05 01:40:11 +00:00
continue;
}
2019-10-21 01:14:52 +00:00
if ($keychange) {
self::keychange($channel,$arr);
2018-06-05 01:40:11 +00:00
continue;
}
// if the clone is active, so are we
2019-10-21 01:14:52 +00:00
if (substr($channel['channel_active'],0,10) !== substr(datetime_convert(),0,10)) {
2018-06-05 01:40:11 +00:00
q("UPDATE channel set channel_active = '%s' where channel_id = %d",
dbesc(datetime_convert()),
intval($channel['channel_id'])
);
}
2019-10-21 01:14:52 +00:00
if (array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) {
foreach ($arr['config'] as $cat => $k) {
foreach ($arr['config'][$cat] as $k => $v) {
2018-06-05 01:40:11 +00:00
set_pconfig($channel['channel_id'],$cat,$k,$v);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
}
2019-10-21 01:14:52 +00:00
if (array_key_exists('xign',$arr) && $arr['xign']) {
sync_xign($channel,$arr['xign']);
2019-10-21 01:14:52 +00:00
}
2020-03-19 23:56:48 +00:00
if (array_key_exists('block',$arr) && $arr['block']) {
sync_block($channel,$arr['block']);
}
2019-10-21 01:14:52 +00:00
if (array_key_exists('obj',$arr) && $arr['obj']) {
2018-06-05 01:40:11 +00:00
sync_objs($channel,$arr['obj']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('likes',$arr) && $arr['likes']) {
2018-06-05 01:40:11 +00:00
import_likes($channel,$arr['likes']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('app',$arr) && $arr['app']) {
2018-06-05 01:40:11 +00:00
sync_apps($channel,$arr['app']);
2019-10-21 01:14:52 +00:00
}
if (array_key_exists('sysapp',$arr) && $arr['sysapp']) {
sync_sysapps($channel,$arr['sysapp']);
}
if (array_key_exists('chatroom',$arr) && $arr['chatroom']) {
2018-06-05 01:40:11 +00:00
sync_chatrooms($channel,$arr['chatroom']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('conv',$arr) && $arr['conv']) {
2018-06-05 01:40:11 +00:00
import_conv($channel,$arr['conv']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('mail',$arr) && $arr['mail']) {
2018-06-05 01:40:11 +00:00
sync_mail($channel,$arr['mail']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('event',$arr) && $arr['event']) {
2018-06-05 01:40:11 +00:00
sync_events($channel,$arr['event']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('event_item',$arr) && $arr['event_item']) {
2018-06-05 01:40:11 +00:00
sync_items($channel,$arr['event_item'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null));
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('item',$arr) && $arr['item']) {
2018-06-05 01:40:11 +00:00
sync_items($channel,$arr['item'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null));
2019-10-21 01:14:52 +00:00
}
if (array_key_exists('menu',$arr) && $arr['menu']) {
2018-06-05 01:40:11 +00:00
sync_menus($channel,$arr['menu']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('file',$arr) && $arr['file']) {
2018-06-05 01:40:11 +00:00
sync_files($channel,$arr['file']);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if (array_key_exists('wiki',$arr) && $arr['wiki']) {
2018-06-05 01:40:11 +00:00
sync_items($channel,$arr['wiki'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null));
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) {
$remote_channel = $arr['channel'];
$remote_channel['channel_id'] = $channel['channel_id'];
2019-10-21 01:14:52 +00:00
if (array_key_exists('channel_pageflags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) {
2018-06-05 01:40:11 +00:00
2018-07-05 03:09:55 +00:00
// Several pageflags are site-specific and cannot be sync'd.
// Only allow those bits which are shareable from the remote and then
// logically OR with the local flags
$arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN|PAGE_AUTOCONNECT|PAGE_APPLICATION|PAGE_PREMIUM|PAGE_ADULT);
$arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] | $channel['channel_pageflags'];
2018-06-05 01:40:11 +00:00
}
2019-06-14 06:36:16 +00:00
$columns = db_columns('channel');
2018-06-05 01:40:11 +00:00
$disallowed = [
'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey',
'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted',
'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook',
'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
'channel_a_delegate', 'channel_moved'
2018-06-05 01:40:11 +00:00
];
foreach($arr['channel'] as $k => $v) {
2019-06-14 06:36:16 +00:00
if (in_array($k,$disallowed)) {
continue;
}
if (! in_array($k,$columns)) {
2018-06-05 01:40:11 +00:00
continue;
}
2019-06-14 06:36:16 +00:00
$r = dbq("UPDATE channel set " . dbesc($k) . " = '" . dbesc($v)
. "' where channel_id = " . intval($channel['channel_id']) );
2018-06-05 01:40:11 +00:00
}
}
2019-10-21 01:14:52 +00:00
if (array_key_exists('abook',$arr) && is_array($arr['abook']) && count($arr['abook'])) {
2018-09-12 05:21:31 +00:00
2018-06-05 01:40:11 +00:00
$total_friends = 0;
$total_feeds = 0;
$r = q("select abook_id, abook_feed from abook where abook_channel = %d",
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
if ($r) {
2018-06-05 01:40:11 +00:00
// don't count yourself
$total_friends = ((count($r) > 0) ? count($r) - 1 : 0);
2019-10-21 01:14:52 +00:00
foreach ($r as $rr) {
if (intval($rr['abook_feed'])) {
2018-06-05 01:40:11 +00:00
$total_feeds ++;
2019-10-21 01:14:52 +00:00
}
}
2018-06-05 01:40:11 +00:00
}
2019-10-21 01:14:52 +00:00
$disallowed = [ 'abook_id', 'abook_account', 'abook_channel', 'abook_rating', 'abook_rating_text', 'abook_not_here' ];
2018-06-05 01:40:11 +00:00
2018-09-12 05:21:31 +00:00
$fields = db_columns('abook');
2018-07-30 06:49:37 +00:00
2019-10-21 01:14:52 +00:00
foreach ($arr['abook'] as $abook) {
2018-06-05 01:40:11 +00:00
$abconfig = null;
2019-10-21 01:14:52 +00:00
if (array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) {
2018-06-05 01:40:11 +00:00
$abconfig = $abook['abconfig'];
}
2019-10-21 01:14:52 +00:00
$clean = [];
if ($abook['abook_xchan'] && $abook['entry_deleted']) {
2018-06-05 01:40:11 +00:00
logger('Removing abook entry for ' . $abook['abook_xchan']);
$r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
dbesc($abook['abook_xchan']),
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
if ($r) {
2018-06-05 01:40:11 +00:00
contact_remove($channel['channel_id'],$r[0]['abook_id']);
2019-10-21 01:14:52 +00:00
if ($total_friends) {
2018-06-05 01:40:11 +00:00
$total_friends --;
2019-10-21 01:14:52 +00:00
}
if (intval($r[0]['abook_feed'])) {
2018-06-05 01:40:11 +00:00
$total_feeds --;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
continue;
}
// Perform discovery if the referenced xchan hasn't ever been seen on this hub.
// This relies on the undocumented behaviour that red sites send xchan info with the abook
// and import_author_xchan will look them up on all federated networks
2019-10-21 01:14:52 +00:00
if ($abook['abook_xchan'] && $abook['xchan_addr']) {
2018-06-05 01:47:36 +00:00
$h = Libzot::get_hublocs($abook['abook_xchan']);
2019-10-21 01:14:52 +00:00
if (! $h) {
2018-06-05 01:40:11 +00:00
$xhash = import_author_xchan(encode_item_xchan($abook));
2019-10-21 01:14:52 +00:00
if (! $xhash) {
2018-06-05 01:40:11 +00:00
logger('Import of ' . $abook['xchan_addr'] . ' failed.');
continue;
}
}
}
2019-10-21 01:14:52 +00:00
foreach ($abook as $k => $v) {
if (in_array($k,$disallowed) || (strpos($k,'abook') !== 0)) {
2018-07-30 06:49:37 +00:00
continue;
}
2019-10-21 01:14:52 +00:00
if (! in_array($k,$fields)) {
2018-06-05 01:40:11 +00:00
continue;
2018-07-30 06:49:37 +00:00
}
2018-06-05 01:40:11 +00:00
$clean[$k] = $v;
}
2019-10-21 01:14:52 +00:00
if (! array_key_exists('abook_xchan',$clean)) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-13 22:49:50 +00:00
$reconnect = false;
2019-10-21 01:14:52 +00:00
if (array_key_exists('abook_instance',$clean) && $clean['abook_instance'] && strpos($clean['abook_instance'],z_root()) === false) {
2018-06-05 01:40:11 +00:00
$clean['abook_not_here'] = 1;
2019-10-13 22:49:50 +00:00
if (! ($abook['abook_pending'] || $abook['abook_blocked'])) {
$reconnect = true;
}
2018-06-05 01:40:11 +00:00
}
$r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($clean['abook_xchan']),
intval($channel['channel_id'])
);
// make sure we have an abook entry for this xchan on this system
2019-10-21 01:14:52 +00:00
if (! $r) {
if ($max_friends !== false && $total_friends > $max_friends) {
2018-06-05 01:40:11 +00:00
logger('total_channels service class limit exceeded');
continue;
}
2019-10-21 01:14:52 +00:00
if ($max_feeds !== false && intval($clean['abook_feed']) && $total_feeds > $max_feeds) {
2018-06-05 01:40:11 +00:00
logger('total_feeds service class limit exceeded');
continue;
}
abook_store_lowlevel(
[
'abook_xchan' => $clean['abook_xchan'],
'abook_account' => $channel['channel_account_id'],
'abook_channel' => $channel['channel_id']
]
);
$total_friends ++;
2019-10-21 01:14:52 +00:00
if (intval($clean['abook_feed'])) {
2018-06-05 01:40:11 +00:00
$total_feeds ++;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
2019-10-21 01:14:52 +00:00
if (count($clean)) {
foreach ($clean as $k => $v) {
if ($k == 'abook_dob') {
2018-06-05 01:40:11 +00:00
$v = dbescdate($v);
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
$r = dbq("UPDATE abook set " . dbesc($k) . " = '" . dbesc($v)
. "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id']));
2018-09-12 05:21:31 +00:00
2018-06-05 01:40:11 +00:00
}
}
// This will set abconfig vars if the sender is using old-style fixed permissions
// using the raw abook record as passed to us. New-style permissions will fall through
// and be set using abconfig
2018-07-30 05:13:43 +00:00
// translate_abook_perms_inbound($channel,$abook);
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if ($abconfig) {
2018-06-05 01:40:11 +00:00
/// @fixme does not handle sync of del_abconfig
2019-10-21 01:14:52 +00:00
foreach ($abconfig as $abc) {
2018-06-05 01:40:11 +00:00
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
}
}
2019-10-13 22:49:50 +00:00
if ($reconnect) {
Connect::connect($channel,$abook['abook_xchan']);
}
2018-06-05 01:40:11 +00:00
}
}
// sync collections (privacy groups) oh joy...
2019-10-21 01:14:52 +00:00
if (array_key_exists('collections',$arr) && is_array($arr['collections']) && count($arr['collections'])) {
2020-07-22 01:16:27 +00:00
$x = q("select * from pgrp where uid = %d and rule = ''",
2018-06-05 01:40:11 +00:00
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
foreach ($arr['collections'] as $cl) {
2018-06-05 01:40:11 +00:00
$found = false;
2019-10-21 01:14:52 +00:00
if ($x) {
foreach ($x as $y) {
if ($cl['collection'] == $y['hash']) {
2018-06-05 01:40:11 +00:00
$found = true;
break;
}
}
2019-10-21 01:14:52 +00:00
if ($found) {
if (($y['gname'] != $cl['name'])
2018-06-05 01:40:11 +00:00
|| ($y['visible'] != $cl['visible'])
|| ($y['deleted'] != $cl['deleted'])) {
2018-09-26 00:47:43 +00:00
q("update pgrp set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d",
2018-06-05 01:40:11 +00:00
dbesc($cl['name']),
intval($cl['visible']),
intval($cl['deleted']),
dbesc($cl['collection']),
intval($channel['channel_id'])
);
}
2019-10-21 01:14:52 +00:00
if (intval($cl['deleted']) && (! intval($y['deleted']))) {
2018-09-26 00:47:43 +00:00
q("delete from pgrp_member where gid = %d",
2018-06-05 01:40:11 +00:00
intval($y['id'])
);
}
}
}
2019-10-21 01:14:52 +00:00
if (! $found) {
2020-07-22 01:16:27 +00:00
$r = q("INSERT INTO pgrp ( hash, uid, visible, deleted, gname, rule )
VALUES( '%s', %d, %d, %d, '%s', '' ) ",
2018-06-05 01:40:11 +00:00
dbesc($cl['collection']),
intval($channel['channel_id']),
intval($cl['visible']),
intval($cl['deleted']),
dbesc($cl['name'])
);
}
// now look for any collections locally which weren't in the list we just received.
// They need to be removed by marking deleted and removing the members.
// This shouldn't happen except for clones created before this function was written.
2019-10-21 01:14:52 +00:00
if ($x) {
2018-06-05 01:40:11 +00:00
$found_local = false;
2019-10-21 01:14:52 +00:00
foreach ($x as $y) {
foreach ($arr['collections'] as $cl) {
if ($cl['collection'] == $y['hash']) {
2018-06-05 01:40:11 +00:00
$found_local = true;
break;
}
}
2019-10-21 01:14:52 +00:00
if (! $found_local) {
2018-09-26 00:47:43 +00:00
q("delete from pgrp_member where gid = %d",
2018-06-05 01:40:11 +00:00
intval($y['id'])
);
2018-09-26 00:47:43 +00:00
q("update pgrp set deleted = 1 where id = %d and uid = %d",
2018-06-05 01:40:11 +00:00
intval($y['id']),
intval($channel['channel_id'])
);
}
}
}
}
// reload the group list with any updates
2018-09-26 00:47:43 +00:00
$x = q("select * from pgrp where uid = %d",
2018-06-05 01:40:11 +00:00
intval($channel['channel_id'])
);
// now sync the members
2019-10-21 01:14:52 +00:00
if (array_key_exists('collection_members', $arr)
2018-06-05 01:40:11 +00:00
&& is_array($arr['collection_members'])
&& count($arr['collection_members'])) {
// first sort into groups keyed by the group hash
$members = array();
2019-10-21 01:14:52 +00:00
foreach ($arr['collection_members'] as $cm) {
if (! array_key_exists($cm['collection'],$members)) {
$members[$cm['collection']] = [];
}
2018-06-05 01:40:11 +00:00
$members[$cm['collection']][] = $cm['member'];
}
// our group list is already synchronised
2019-10-21 01:14:52 +00:00
if ($x) {
foreach ($x as $y) {
2018-06-05 01:40:11 +00:00
// for each group, loop on members list we just received
2019-10-21 01:14:52 +00:00
if (isset($y['hash']) && isset($members[$y['hash']])) {
foreach ($members[$y['hash']] as $member) {
2018-06-05 01:40:11 +00:00
$found = false;
2018-09-26 00:47:43 +00:00
$z = q("select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1",
2018-06-05 01:40:11 +00:00
intval($y['id']),
intval($channel['channel_id']),
dbesc($member)
);
2019-10-21 01:14:52 +00:00
if ($z) {
2018-06-05 01:40:11 +00:00
$found = true;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
// if somebody is in the group that wasn't before - add them
2019-10-21 01:14:52 +00:00
if (! $found) {
2018-09-26 00:47:43 +00:00
q("INSERT INTO pgrp_member (uid, gid, xchan)
2018-06-05 01:40:11 +00:00
VALUES( %d, %d, '%s' ) ",
intval($channel['channel_id']),
intval($y['id']),
dbesc($member)
);
}
}
}
// now retrieve a list of members we have on this site
2018-09-26 00:47:43 +00:00
$m = q("select xchan from pgrp_member where gid = %d and uid = %d",
2018-06-05 01:40:11 +00:00
intval($y['id']),
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
if ($m) {
foreach ($m as $mm) {
2018-06-05 01:40:11 +00:00
// if the local existing member isn't in the list we just received - remove them
2019-10-21 01:14:52 +00:00
if (! in_array($mm['xchan'],$members[$y['hash']])) {
2018-09-26 00:47:43 +00:00
q("delete from pgrp_member where xchan = '%s' and gid = %d and uid = %d",
2018-06-05 01:40:11 +00:00
dbesc($mm['xchan']),
intval($y['id']),
intval($channel['channel_id'])
);
}
}
}
}
}
}
}
2019-10-21 01:14:52 +00:00
if (array_key_exists('profile',$arr) && is_array($arr['profile']) && count($arr['profile'])) {
2018-06-05 01:40:11 +00:00
$disallowed = array('id','aid','uid','guid');
2019-10-21 01:14:52 +00:00
foreach ($arr['profile'] as $profile) {
2018-06-05 01:40:11 +00:00
$x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1",
dbesc($profile['profile_guid']),
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
if (! $x) {
2018-06-05 01:40:11 +00:00
profile_store_lowlevel(
[
'aid' => $channel['channel_account_id'],
'uid' => $channel['channel_id'],
'profile_guid' => $profile['profile_guid'],
]
);
$x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1",
dbesc($profile['profile_guid']),
intval($channel['channel_id'])
);
2019-10-21 01:14:52 +00:00
if (! $x) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
}
2019-10-21 01:14:52 +00:00
$clean = [];
foreach ($profile as $k => $v) {
if (in_array($k,$disallowed)) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if ($profile['is_default'] && in_array($k,['photo','thumb'])) {
2018-06-05 01:40:11 +00:00
continue;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
2019-10-21 01:14:52 +00:00
if ($k === 'name') {
2018-06-05 01:40:11 +00:00
$clean['fullname'] = $v;
2019-10-21 01:14:52 +00:00
}
elseif ($k === 'with') {
2018-06-05 01:40:11 +00:00
$clean['partner'] = $v;
2019-10-21 01:14:52 +00:00
}
elseif ($k === 'work') {
2018-06-05 01:40:11 +00:00
$clean['employment'] = $v;
2019-10-21 01:14:52 +00:00
}
elseif (array_key_exists($k,$x[0])) {
2018-06-05 01:40:11 +00:00
$clean[$k] = $v;
2019-10-21 01:14:52 +00:00
}
2018-06-05 01:40:11 +00:00
/**
* @TODO
* We also need to import local photos if a custom photo is selected
*/
2019-10-21 01:14:52 +00:00
if ((strpos($profile['thumb'],'/photo/profile/l/') !== false) || intval($profile['is_default'])) {
2018-06-05 01:40:11 +00:00
$profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id'];
$profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id'];
}
else {
$profile['photo'] = z_root() . '/photo/' . basename($profile['photo']);
$profile['thumb'] = z_root() . '/photo/' . basename($profile['thumb']);
}
}
2019-10-21 01:14:52 +00:00
if (count($clean)) {
foreach ($clean as $k => $v) {
2018-06-05 01:40:11 +00:00
$r = dbq("UPDATE profile set " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v)
. "' where profile_guid = '" . dbesc($profile['profile_guid'])
. "' and uid = " . intval($channel['channel_id']));
}
}
}
}
2019-10-21 01:14:52 +00:00
$addon = [ 'channel' => $channel, 'data' => $arr ];
2018-06-05 01:40:11 +00:00
/**
* @hooks process_channel_sync_delivery
* Called when accepting delivery of a 'sync packet' containing structure and table updates from a channel clone.
* * \e array \b channel
* * \e array \b data
*/
call_hooks('process_channel_sync_delivery', $addon);
2019-10-21 01:14:52 +00:00
$DR = new DReport(z_root(),$d,$d,'sync','channel sync delivered');
2018-06-05 01:40:11 +00:00
2018-07-30 06:49:37 +00:00
$DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>');
2018-06-05 01:40:11 +00:00
$result[] = $DR->get();
}
return $result;
}
2018-07-04 06:24:36 +00:00
/**
* @brief Synchronises locations.
*
* @param array $sender
* @param array $arr
* @param boolean $absolute (optional) default false
* @return array
*/
static function sync_locations($sender, $arr, $absolute = false) {
$ret = array();
if($arr['locations']) {
$x = q("select * from xchan where xchan_hash = '%s'",
dbesc($sender['hash'])
);
if ($x) {
$xchan = array_shift($x);
}
2018-07-04 06:24:36 +00:00
if ($absolute) {
Libzot::check_location_move($sender['hash'],$arr['locations']);
}
2018-07-04 06:24:36 +00:00
$xisting = q("select * from hubloc where hubloc_hash = '%s'",
dbesc($sender['hash'])
);
// See if a primary is specified
$has_primary = false;
foreach($arr['locations'] as $location) {
if($location['primary']) {
$has_primary = true;
break;
}
}
// Ensure that they have one primary hub
if(! $has_primary)
$arr['locations'][0]['primary'] = true;
foreach($arr['locations'] as $location) {
if(! Libzot::verify($location['url'],$location['url_sig'],$sender['public_key'])) {
2018-07-04 06:24:36 +00:00
logger('Unable to verify site signature for ' . $location['url']);
$ret['message'] .= sprintf( t('Unable to verify site signature for %s'), $location['url']) . EOL;
continue;
}
for($x = 0; $x < count($xisting); $x ++) {
if(($xisting[$x]['hubloc_url'] === $location['url'])
&& ($xisting[$x]['hubloc_sitekey'] === $location['sitekey'])) {
$xisting[$x]['updated'] = true;
}
}
if(! $location['sitekey']) {
logger('Empty hubloc sitekey. ' . print_r($location,true));
continue;
}
// match as many fields as possible in case anything at all changed.
$r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_id_url = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_site_id = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' ",
dbesc($sender['hash']),
dbesc($sender['id']),
dbesc($sender['id_sig']),
dbesc($location['id_url']),
dbesc($location['url']),
dbesc($location['url_sig']),
dbesc($location['site_id']),
dbesc($location['host']),
dbesc($location['address']),
dbesc($location['callback']),
dbesc($location['sitekey'])
);
if($r) {
logger('Hub exists: ' . $location['url'], LOGGER_DEBUG);
// update connection timestamp if this is the site we're talking to
// This only happens when called from import_xchan
$current_site = false;
$t = datetime_convert('UTC','UTC','now - 15 minutes');
if(array_key_exists('site',$arr) && $location['url'] == $arr['site']['url']) {
q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_connected < '%s'",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($r[0]['hubloc_id']),
dbesc($t)
);
$current_site = true;
}
2019-04-12 03:26:38 +00:00
if($current_site && (intval($r[0]['hubloc_error']) || intval($r[0]['hubloc_deleted']))) {
q("update hubloc set hubloc_error = 0, hubloc_deleted = 0 where hubloc_id = %d",
2018-07-04 06:24:36 +00:00
intval($r[0]['hubloc_id'])
);
if(intval($r[0]['hubloc_orphancheck'])) {
q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d",
intval($r[0]['hubloc_id'])
);
}
q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'",
dbesc($sender['hash'])
);
}
// Remove pure duplicates
if(count($r) > 1) {
for($h = 1; $h < count($r); $h ++) {
q("delete from hubloc where hubloc_id = %d",
intval($r[$h]['hubloc_id'])
);
$what .= 'duplicate_hubloc_removed ';
$changed = true;
}
}
if(intval($r[0]['hubloc_primary']) && (! $location['primary'])) {
$m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
$r[0]['hubloc_primary'] = intval($location['primary']);
hubloc_change_primary($r[0]);
$what .= 'primary_hub ';
$changed = true;
}
elseif((! intval($r[0]['hubloc_primary'])) && ($location['primary'])) {
$m = q("update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
// make sure hubloc_change_primary() has current data
$r[0]['hubloc_primary'] = intval($location['primary']);
hubloc_change_primary($r[0]);
$what .= 'primary_hub ';
$changed = true;
}
elseif($absolute) {
// Absolute sync - make sure the current primary is correctly reflected in the xchan
$pr = hubloc_change_primary($r[0]);
if($pr) {
$what .= 'xchan_primary ';
$changed = true;
}
}
elseif(intval($r[0]['hubloc_primary']) && $xchan && $xchan['xchan_url'] !== $r[0]['hubloc_id_url']) {
$pr = hubloc_change_primary($r[0]);
if($pr) {
$what .= 'xchan_primary ';
$changed = true;
}
}
2018-07-04 06:24:36 +00:00
if(intval($r[0]['hubloc_deleted']) && (! intval($location['deleted']))) {
$n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
$what .= 'undelete_hub ';
$changed = true;
}
elseif((! intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) {
logger('deleting hubloc: ' . $r[0]['hubloc_addr']);
$n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
$what .= 'delete_hub ';
$changed = true;
}
continue;
}
// Existing hubs are dealt with. Now let's process any new ones.
// New hub claiming to be primary. Make it so by removing any existing primaries.
if(intval($location['primary'])) {
$r = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1",
dbesc(datetime_convert()),
dbesc($sender['hash'])
);
}
logger('New hub: ' . $location['url']);
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $sender['id'],
'hubloc_guid_sig' => $sender['id_sig'],
'hubloc_id_url' => $location['id_url'],
'hubloc_hash' => $sender['hash'],
'hubloc_addr' => $location['address'],
'hubloc_network' => 'zot6',
'hubloc_primary' => intval($location['primary']),
'hubloc_url' => $location['url'],
'hubloc_url_sig' => $location['url_sig'],
2018-07-25 03:21:01 +00:00
'hubloc_site_id' => Libzot::make_xchan_hash($location['url'],$location['sitekey']),
2018-07-04 06:24:36 +00:00
'hubloc_host' => $location['host'],
'hubloc_callback' => $location['callback'],
'hubloc_sitekey' => $location['sitekey'],
'hubloc_updated' => datetime_convert(),
'hubloc_connected' => datetime_convert()
]
);
$what .= 'newhub ';
$changed = true;
if($location['primary']) {
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s' limit 1",
dbesc($location['address']),
dbesc($location['sitekey'])
);
if($r)
hubloc_change_primary($r[0]);
}
}
// get rid of any hubs we have for this channel which weren't reported.
if($absolute && $xisting) {
foreach($xisting as $x) {
if(! array_key_exists('updated',$x)) {
logger('Deleting unreferenced hub location ' . $x['hubloc_addr']);
$r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($x['hubloc_id'])
);
$what .= 'removed_hub ';
$changed = true;
}
}
}
}
else {
logger('No locations to sync!');
}
$ret['change_message'] = $what;
$ret['changed'] = $changed;
return $ret;
}
static function keychange($channel,$arr) {
2018-07-06 05:27:44 +00:00
// verify the keychange operation
if(! Libzot::verify($arr['channel']['channel_pubkey'],$arr['keychange']['new_sig'],$channel['channel_prvkey'])) {
logger('sync keychange: verification failed');
return;
}
2018-07-06 05:27:44 +00:00
$sig = Libzot::sign($channel['channel_guid'],$arr['channel']['channel_prvkey']);
$hash = Libzot::make_xchan_hash($channel['channel_guid'],$arr['channel']['channel_pubkey']);
2018-07-06 05:27:44 +00:00
$r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s',
channel_hash = '%s' where channel_id = %d",
dbesc($arr['channel']['channel_prvkey']),
dbesc($arr['channel']['channel_pubkey']),
dbesc($sig),
dbesc($hash),
intval($channel['channel_id'])
);
if(! $r) {
logger('keychange sync: channel update failed');
return;
}
2018-07-06 05:27:44 +00:00
$r = q("select * from channel where channel_id = %d",
intval($channel['channel_id'])
);
2018-07-06 05:27:44 +00:00
if(! $r) {
logger('keychange sync: channel retrieve failed');
return;
}
2018-07-06 05:27:44 +00:00
$channel = $r[0];
2018-07-06 05:27:44 +00:00
$h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($arr['keychange']['old_hash']),
dbesc(z_root())
);
2018-07-06 05:27:44 +00:00
if($h) {
foreach($h as $hv) {
$hv['hubloc_guid_sig'] = $sig;
$hv['hubloc_hash'] = $hash;
$hv['hubloc_url_sig'] = Libzot::sign(z_root(),$channel['channel_prvkey']);
hubloc_store_lowlevel($hv);
}
}
2018-07-06 05:27:44 +00:00
$x = q("select * from xchan where xchan_hash = '%s' ",
dbesc($arr['keychange']['old_hash'])
);
2018-07-06 05:27:44 +00:00
$check = q("select * from xchan where xchan_hash = '%s'",
dbesc($hash)
);
2018-07-06 05:27:44 +00:00
if(($x) && (! $check)) {
$oldxchan = $x[0];
foreach($x as $xv) {
$xv['xchan_guid_sig'] = $sig;
$xv['xchan_hash'] = $hash;
$xv['xchan_pubkey'] = $channel['channel_pubkey'];
xchan_store_lowlevel($xv);
$newxchan = $xv;
}
}
2018-07-06 05:27:44 +00:00
$a = q("select * from abook where abook_xchan = '%s' and abook_self = 1",
dbesc($arr['keychange']['old_hash'])
);
2018-07-06 05:27:44 +00:00
if($a) {
q("update abook set abook_xchan = '%s' where abook_id = %d",
dbesc($hash),
intval($a[0]['abook_id'])
);
}
2018-07-04 06:24:36 +00:00
2018-07-06 05:27:44 +00:00
xchan_change_key($oldxchan,$newxchan,$arr['keychange']);
}
2018-07-04 06:24:36 +00:00
2018-06-05 01:40:11 +00:00
}