use Friendica\Protocol\ActivityPub;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\HTTPSignature;
use Friendica\Util\JsonLD;
use Friendica\Util\Network;
$data = ActivityPub::fetchContent($url);
if (empty($data)) {
+ self::markForArchival($fetched_contact ?: []);
return $fetched_contact;
}
return $apcontact;
}
+ /**
+ * Mark the given AP Contact as "to archive"
+ *
+ * @param array $apcontact
+ * @return void
+ */
+ public static function markForArchival(array $apcontact)
+ {
+ if (!empty($apcontact['inbox'])) {
+ Logger::info('Set inbox status to failure', ['inbox' => $apcontact['inbox']]);
+ HTTPSignature::setInboxStatus($apcontact['inbox'], false);
+ }
+
+ if (!empty($apcontact['sharedinbox'])) {
+ // Check if there are any vital inboxes
+ $vital = DBA::exists('apcontact', ["`sharedinbox` = ? AnD `inbox` IN (SELECT `url` FROM `inbox-status` WHERE `success` > `failure`)",
+ $apcontact['sharedinbox']]);
+ if (!$vital) {
+ // If all known personal inboxes are failing then set their shared inbox to failure as well
+ Logger::info('Set shared inbox status to failure', ['sharedinbox' => $apcontact['sharedinbox']]);
+ HTTPSignature::setInboxStatus($apcontact['sharedinbox'], false, true);
+ }
+ }
+ }
+
+ /**
+ * Unmark the given AP Contact as "to archive"
+ *
+ * @param array $apcontact
+ * @return void
+ */
+ public static function unmarkForArchival(array $apcontact)
+ {
+ if (!empty($apcontact['inbox'])) {
+ Logger::info('Set inbox status to success', ['inbox' => $apcontact['inbox']]);
+ HTTPSignature::setInboxStatus($apcontact['inbox'], true);
+ }
+ if (!empty($apcontact['sharedinbox'])) {
+ Logger::info('Set shared inbox status to success', ['sharedinbox' => $apcontact['sharedinbox']]);
+ HTTPSignature::setInboxStatus($apcontact['sharedinbox'], true, true);
+ }
+ }
+
/**
* Unarchive inboxes
*
- * @param string $url inbox url
+ * @param string $url inbox url
+ * @param boolean $shared Shared Inbox
*/
private static function unarchiveInbox($url, $shared)
{
return;
}
- $now = DateTimeFormat::utcNow();
-
- $fields = ['archive' => false, 'success' => $now, 'shared' => $shared];
-
- if (!DBA::exists('inbox-status', ['url' => $url])) {
- $fields = array_merge($fields, ['url' => $url, 'created' => $now]);
- DBA::replace('inbox-status', $fields);
- } else {
- DBA::update('inbox-status', $fields, ['url' => $url]);
- }
+ HTTPSignature::setInboxStatus($url, true, $shared);
}
}
return;
}
+ APContact::unMarkForArchival($apcontact);
+
$http_signer = HTTPSignature::getSigner($body, $header);
if (empty($http_signer)) {
Logger::warning('Invalid HTTP signature, message will be discarded.');
$profile = APContact::getByURL($object_id);
if (!empty($profile['type'])) {
+ APContact::unMarkForArchival($profile);
return 'as:' . $profile['type'];
}
*
* @return boolean "true" if inbox is archived
*/
- private static function archivedInbox($url)
+ public static function archivedInbox($url)
{
return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]);
}
*
* @param string $url The URL of the inbox
* @param boolean $success Transmission status
+ * @param boolean $shared The inbox is a shared inbox
*/
- static private function setInboxStatus($url, $success)
+ static public function setInboxStatus($url, $success, $shared = false)
{
$now = DateTimeFormat::utcNow();
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
if (!DBA::isResult($status)) {
- DBA::insert('inbox-status', ['url' => $url, 'created' => $now]);
+ DBA::insert('inbox-status', ['url' => $url, 'created' => $now, 'shared' => $shared]);
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
}
*/
public static function execute($cmd, $target_id, $inbox, $uid)
{
- Logger::log('Invoked: ' . $cmd . ': ' . $target_id . ' to ' . $inbox, Logger::DEBUG);
+ if (ActivityPub\Transmitter::archivedInbox($inbox)) {
+ Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
+ if (in_array($cmd, [Delivery::POST])) {
+ $item = Item::selectFirst(['uri-id'], ['id' => $target_id]);
+ Post\DeliveryData::incrementQueueFailed($item['uri-id'] ?? 0);
+ }
+ return;
+ }
+
+ Logger::info('Invoked', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
$success = true;
return;
}
- // We don't deliver our items to blocked or pending contacts, and not to ourselves either
+ // We don't deliver our items to blocked, archived or pending contacts, and not to ourselves either
$contact = DBA::selectFirst('contact', [],
- ['id' => $contact_id, 'blocked' => false, 'pending' => false, 'self' => false]
+ ['id' => $contact_id, 'archive' => false, 'blocked' => false, 'pending' => false, 'self' => false]
);
if (!DBA::isResult($contact)) {
self::setFailedQueue($cmd, $target_item);
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1378);
+ define('DB_UPDATE_VERSION', 1379);
}
return [
"alias" => ["alias(190)"],
"followers" => ["followers(190)"],
"baseurl" => ["baseurl(190)"],
+ "sharedinbox" => ["sharedinbox(190)"],
"gsid" => ["gsid"]
]
],
"comment" => "photo storage",
"fields" => [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
- "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
+ "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid", "on delete" => "restrict"], "comment" => "Owner User id"],
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id", "on delete" => "restrict"], "comment" => "contact.id"],
"guid" => ["type" => "char(16)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this photo"],
"resource-id" => ["type" => "char(32)", "not null" => "1", "default" => "", "comment" => ""],