function import_mail($channel, $mails, $sync = false) { if ($channel && $mails) { foreach ($mails as $mail) { if (array_key_exists('flags', $mail) && in_array('deleted', $mail['flags'])) { q("delete from mail where mid = '%s' and uid = %d limit 1", dbesc($mail['message_id']), intval($channel['channel_id'])); continue; } if (array_key_exists('flags', $mail) && in_array('recalled', $mail['flags'])) { q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d limit 1", dbesc($mail['message_id']), intval($channel['channel_id'])); continue; } $m = get_mail_elements($mail); if (!$m) { continue; } $m['aid'] = $channel['channel_account_id']; $m['uid'] = $channel['channel_id']; $mail_id = mail_store($m); if ($sync && $mail_id) { Zotlabs\Daemon\Master::Summon(array('Notifier', 'single_mail', $mail_id)); } } } }
/** * @brief Process incoming array of messages. * * Process an incoming array of messages which were obtained via pickup, and * import, update, delete as directed. * * The message types handled here are 'activity' (e.g. posts), 'mail' , * 'profile', 'location' and 'channel_sync'. * * @param array $arr * 'pickup' structure returned from remote site * @param string $sender_url * the url specified by the sender in the initial communication. * We will verify the sender and url in each returned message structure and * also verify that all the messages returned match the site url that we are * currently processing. * * @returns array * suitable for logging remotely, enumerating the processing results of each message/recipient combination * * [0] => \e string $channel_hash * * [1] => \e string $delivery_status * * [2] => \e string $address */ function zot_import($arr, $sender_url) { $data = json_decode($arr['body'], true); if (!$data) { logger('zot_import: empty body'); return array(); } if (array_key_exists('iv', $data)) { $data = json_decode(crypto_unencapsulate($data, get_config('system', 'prvkey')), true); } if (!$data['success']) { if ($data['message']) { logger('remote pickup failed: ' . $data['message']); } return false; } $incoming = $data['pickup']; $return = array(); if (is_array($incoming)) { foreach ($incoming as $i) { if (!is_array($i)) { logger('incoming is not an array'); continue; } $result = null; if (array_key_exists('iv', $i['notify'])) { $i['notify'] = json_decode(crypto_unencapsulate($i['notify'], get_config('system', 'prvkey')), true); } logger('zot_import: notify: ' . print_r($i['notify'], true), LOGGER_DATA); $hub = zot_gethub($i['notify']['sender']); if (!$hub || $hub['hubloc_url'] != $sender_url) { logger('zot_import: potential forgery: wrong site for sender: ' . $sender_url . ' != ' . print_r($i['notify'], true)); continue; } $message_request = array_key_exists('message_id', $i['notify']) ? true : false; if ($message_request) { logger('processing message request'); } $i['notify']['sender']['hash'] = make_xchan_hash($i['notify']['sender']['guid'], $i['notify']['sender']['guid_sig']); $deliveries = null; if (array_key_exists('message', $i) && array_key_exists('type', $i['message']) && $i['message']['type'] === 'rating') { // rating messages are processed only by directory servers logger('Rating received: ' . print_r($arr, true), LOGGER_DATA); $result = process_rating_delivery($i['notify']['sender'], $i['message']); continue; } if (array_key_exists('recipients', $i['notify']) && count($i['notify']['recipients'])) { logger('specific recipients'); $recip_arr = array(); foreach ($i['notify']['recipients'] as $recip) { if (is_array($recip)) { $recip_arr[] = make_xchan_hash($recip['guid'], $recip['guid_sig']); } } $r = false; if ($recip_arr) { stringify_array_elms($recip_arr); $recips = implode(',', $recip_arr); $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) \n\t\t\t\t\t\tand channel_removed = 0 "); } if (!$r) { logger('recips: no recipients on this site'); continue; } // It's a specifically targetted post. If we were sent a public_scope hint (likely), // get rid of it so that it doesn't get stored and cause trouble. if ($i && is_array($i) && array_key_exists('message', $i) && is_array($i['message']) && $i['message']['type'] === 'activity' && array_key_exists('public_scope', $i['message'])) { unset($i['message']['public_scope']); } $deliveries = $r; // We found somebody on this site that's in the recipient list. } else { if ($i['message'] && array_key_exists('flags', $i['message']) && in_array('private', $i['message']['flags']) && $i['message']['type'] === 'activity') { if (array_key_exists('public_scope', $i['message']) && $i['message']['public_scope'] === 'public') { // This should not happen but until we can stop it... logger('private message was delivered with no recipients.'); continue; } } logger('public post'); // Public post. look for any site members who are or may be accepting posts from this sender // and who are allowed to see them based on the sender's permissions $deliveries = allowed_public_recips($i); if ($i['message'] && array_key_exists('type', $i['message']) && $i['message']['type'] === 'location') { $sys = get_sys_channel(); $deliveries = array(array('hash' => $sys['xchan_hash'])); } // if the scope is anything but 'public' we're going to store it as private regardless // of the private flag on the post. if ($i['message'] && array_key_exists('public_scope', $i['message']) && $i['message']['public_scope'] !== 'public') { if (!array_key_exists('flags', $i['message'])) { $i['message']['flags'] = array(); } if (!in_array('private', $i['message']['flags'])) { $i['message']['flags'][] = 'private'; } } } // Go through the hash array and remove duplicates. array_unique() won't do this because the array is more than one level. $no_dups = array(); if ($deliveries) { foreach ($deliveries as $d) { if (!in_array($d['hash'], $no_dups)) { $no_dups[] = $d['hash']; } } if ($no_dups) { $deliveries = array(); foreach ($no_dups as $n) { $deliveries[] = array('hash' => $n); } } } if (!$deliveries) { logger('zot_import: no deliveries on this site'); continue; } if ($i['message']) { if ($i['message']['type'] === 'activity') { $arr = get_item_elements($i['message']); $v = validate_item_elements($i['message'], $arr); if (!$v['success']) { logger('Activity rejected: ' . $v['message'] . ' ' . print_r($i['message'], true)); continue; } logger('Activity received: ' . print_r($arr, true), LOGGER_DATA); logger('Activity recipients: ' . print_r($deliveries, true), LOGGER_DATA); $relay = array_key_exists('flags', $i['message']) && in_array('relay', $i['message']['flags']) ? true : false; $result = process_delivery($i['notify']['sender'], $arr, $deliveries, $relay, false, $message_request); } elseif ($i['message']['type'] === 'mail') { $arr = get_mail_elements($i['message']); logger('Mail received: ' . print_r($arr, true), LOGGER_DATA); logger('Mail recipients: ' . print_r($deliveries, true), LOGGER_DATA); $result = process_mail_delivery($i['notify']['sender'], $arr, $deliveries); } elseif ($i['message']['type'] === 'profile') { $arr = get_profile_elements($i['message']); logger('Profile received: ' . print_r($arr, true), LOGGER_DATA); logger('Profile recipients: ' . print_r($deliveries, true), LOGGER_DATA); $result = process_profile_delivery($i['notify']['sender'], $arr, $deliveries); } elseif ($i['message']['type'] === 'channel_sync') { // $arr = get_channelsync_elements($i['message']); $arr = $i['message']; logger('Channel sync received: ' . print_r($arr, true), LOGGER_DATA); logger('Channel sync recipients: ' . print_r($deliveries, true), LOGGER_DATA); $result = process_channel_sync_delivery($i['notify']['sender'], $arr, $deliveries); } elseif ($i['message']['type'] === 'location') { $arr = $i['message']; logger('Location message received: ' . print_r($arr, true), LOGGER_DATA); logger('Location message recipients: ' . print_r($deliveries, true), LOGGER_DATA); $result = process_location_delivery($i['notify']['sender'], $arr, $deliveries); } } if ($result) { $return = array_merge($return, $result); } } } return $return; }
function import_mail($channel, $mails) { if ($channel && $mails) { foreach ($mails as $mail) { if (array_key_exists('flags', $mail) && in_array('deleted', $mail['flags'])) { q("delete from mail where mid = '%s' and uid = %d limit 1", dbesc($mail['message_id']), intval($channel['channel_id'])); continue; } if (array_key_exists('flags', $mail) && in_array('recalled', $mail['flags'])) { q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d limit 1", dbesc($mail['message_id']), intval($channel['channel_id'])); continue; } $m = get_mail_elements($mail); if (!$m) { continue; } $m['aid'] = $channel['channel_account_id']; $m['uid'] = $channel['channel_id']; mail_store($m); } } }