}
$relay = [
- "subscribe" => $subscribe,
- "scope" => $scope,
- "tags" => $taglist
+ 'subscribe' => $subscribe,
+ 'scope' => $scope,
+ 'tags' => $taglist,
+ 'protocols' => ['diaspora' => System::baseUrl() . '/receive/public',
+ 'dfrn' => System::baseUrl() . '/dfrn_notify']
];
header('Content-type: application/json; charset=utf-8');
$contact = Contact::getDetailsByAddr($msg['author'], 0);
if (!$contact) {
logger('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact not found');
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
}
// We now have some contact, so we fetch it
// This should never fail
if (!DBM::is_result($importer)) {
logger('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact not found');
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
}
logger('Importing post from ' . $msg['author'] . ' with the public envelope.', LOGGER_DEBUG);
$cid = Contact::getIdForURL($msg['author']);
if (!$cid) {
logger('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact not found');
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
}
}
// This should never fail
if (!DBM::is_result($importer)) {
logger('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact not found');
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
}
// Set the user id. This is important if this is a public contact
$old_fields = dba::selectFirst('contact', $fieldnames, $condition);
+ // When the contact doesn't exist, the value "true" will trigger an insert
+ if (!$old_fields) {
+ $old_fields = true;
+ }
+
dba::update('contact', $fields, $condition, $old_fields);
}
}
Contact::markForArchival($contact);
return -22;
}
+ $pubkey = $fcontact['pubkey'];
+ } else {
+ $pubkey = '';
}
- $envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch);
+ $envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch);
// Create the endpoint for public posts. This is some WIP and should later be added to the probing
if ($public_batch && empty($contact["batch"])) {
*/
private static function getRelayContact($server_url)
{
- $batch = $server_url . '/receive/public';
-
$fields = ['batch', 'id', 'name', 'network', 'archive', 'blocked'];
// Fetch the relay contact
- $condition = ['uid' => 0, 'network' => NETWORK_DIASPORA, 'batch' => $batch,
+ $condition = ['uid' => 0, 'nurl' => normalise_link($server_url),
'contact-type' => ACCOUNT_TYPE_RELAY];
$contact = dba::selectFirst('contact', $fields, $condition);
- // If there is nothing found, we check if there is some unmarked relay
- // This code segment can be removed before the release 2018-05
- if (!DBM::is_result($contact)) {
- $condition = ['uid' => 0, 'network' => NETWORK_DIASPORA, 'batch' => $batch,
- 'name' => 'relay', 'nick' => 'relay', 'url' => $server_url];
- $contact = dba::selectFirst('contact', $fields, $condition);
-
- if (DBM::is_result($contact)) {
- // Mark the relay account as a relay account
- $fields = ['contact-type' => ACCOUNT_TYPE_RELAY];
- dba::update('contact', $fields, ['id' => $contact['id']]);
- }
- }
if (DBM::is_result($contact)) {
if ($contact['archive'] || $contact['blocked']) {
return false;
}
return $contact;
} else {
- $fields = ['uid' => 0, 'created' => DateTimeFormat::utcNow(),
- 'name' => 'relay', 'nick' => 'relay',
- 'url' => $server_url, 'nurl' => normalise_link($server_url),
- 'batch' => $batch, 'network' => NETWORK_DIASPORA,
- 'rel' => CONTACT_IS_FOLLOWER, 'blocked' => false,
- 'contact-type' => ACCOUNT_TYPE_RELAY,
- 'pending' => false, 'writable' => true];
- dba::insert('contact', $fields);
-
- $fields = ['batch', 'id', 'name', 'network'];
+ self::setRelayContact($server_url);
+
$contact = dba::selectFirst('contact', $fields, $condition);
if (DBM::is_result($contact)) {
return $contact;
}
-
}
// It should never happen that we arrive here
return [];
}
+ /**
+ * @brief Update or insert a relay contact
+ *
+ * @param string $server_url The url of the server
+ * @param array $network_fields Optional network specific fields
+ */
+ public static function setRelayContact($server_url, $network_fields = [])
+ {
+ $fields = ['created' => DateTimeFormat::utcNow(),
+ 'name' => 'relay', 'nick' => 'relay',
+ 'url' => $server_url, 'network' => NETWORK_DIASPORA,
+ 'batch' => $server_url . '/receive/public',
+ 'rel' => CONTACT_IS_FOLLOWER, 'blocked' => false,
+ 'pending' => false, 'writable' => true];
+
+ $fields = array_merge($fields, $network_fields);
+
+ $condition = ['uid' => 0, 'nurl' => normalise_link($server_url),
+ 'contact-type' => ACCOUNT_TYPE_RELAY];
+
+ if (dba::exists('contact', $condition)) {
+ unset($fields['created']);
+ }
+
+ dba::update('contact', $fields, $condition, true);
+ }
+
/**
* @brief Return a list of participating contacts for a thread
*
use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
+use Friendica\Protocol\Diaspora;
use dba;
use DOMDocument;
use DOMXPath;
dba::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag]);
}
}
+
+ // Create or update the relay contact
+ $fields = [];
+ if (isset($data->protocols)) {
+ if (isset($data->protocols->diaspora)) {
+ $fields['network'] = NETWORK_DIASPORA;
+ $fields['batch'] = $data->protocols->diaspora;
+ }
+ if (isset($data->protocols->dfrn)) {
+ $fields['network'] = NETWORK_DFRN;
+ $fields['batch'] = $data->protocols->dfrn;
+ }
+ }
+ Diaspora::setRelayContact($server_url, $fields);
}
/**
*/
private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup)
{
- logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . $contact['addr']);
+ logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . (empty($contact['addr']) ? $contact['url'] : $contact['addr']));
if ($cmd == self::MAIL) {
$item = $target_item;
// We don't have a relationship with contacts on a public post.
// Se we transmit with the new method and via Diaspora as a fallback
- if ($items[0]['uid'] == 0) {
+ if (($items[0]['uid'] == 0) || ($contact['uid'] == 0)) {
// Transmit in public if it's a relay post
$public_dfrn = ($contact['contact-type'] == ACCOUNT_TYPE_RELAY);
$deliver_status = DFRN::transmit($owner, $contact, $atom, $public_dfrn);
+
+ // We never spool failed relay deliveries
+ if ($public_dfrn) {
+ logger('Relay delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status);
+ return;
+ }
+
if (($deliver_status < 200) || ($deliver_status > 299)) {
// Transmit via Diaspora if not possible via Friendica
self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);