From 6f2fcd2859fe57446f39b44ad5ccac76839be57a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 16 May 2021 16:41:07 +0000 Subject: [PATCH 1/9] Don't use compacted data when parsing accounts --- src/Model/APContact.php | 76 ++++++++++++++++++------------------ src/Protocol/ActivityPub.php | 2 +- src/Util/JsonLD.php | 19 ++++++++- 3 files changed, 55 insertions(+), 42 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index cc84df4a54..44773bf7e7 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -165,11 +165,10 @@ class APContact return $fetched_contact; } - $compacted = JsonLD::compact($data); - if (empty($compacted['@id'])) { + if (empty($data['id'])) { return $fetched_contact; } - + // Detect multiple fast repeating request to the same address // See https://github.com/friendica/friendica/issues/9303 $cachekey = 'apcontact:getByURL:' . $url; @@ -180,40 +179,39 @@ class APContact DI::cache()->set($cachekey, System::callstack(20), Duration::FIVE_MINUTES); } - $apcontact['url'] = $compacted['@id']; - $apcontact['uuid'] = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value'); - $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type')); - $apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id'); - $apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id'); - $apcontact['inbox'] = JsonLD::fetchElement($compacted, 'ldp:inbox', '@id'); + $apcontact['url'] = $data['id']; + $apcontact['uuid'] = JsonLD::fetchElement($data, 'diaspora:guid'); + $apcontact['type'] = JsonLD::fetchElement($data, 'type'); + $apcontact['following'] = JsonLD::fetchElement($data, 'following'); + $apcontact['followers'] = JsonLD::fetchElement($data, 'followers'); + $apcontact['inbox'] = JsonLD::fetchElement($data, 'inbox'); self::unarchiveInbox($apcontact['inbox'], false); - - $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id'); + $apcontact['outbox'] = JsonLD::fetchElement($data, 'outbox'); $apcontact['sharedinbox'] = ''; - if (!empty($compacted['as:endpoints'])) { - $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id'); + if (!empty($data['endpoints'])) { + $apcontact['sharedinbox'] = JsonLD::fetchElement($data['endpoints'], 'sharedInbox'); self::unarchiveInbox($apcontact['sharedinbox'], true); } - $apcontact['nick'] = JsonLD::fetchElement($compacted, 'as:preferredUsername', '@value') ?? ''; - $apcontact['name'] = JsonLD::fetchElement($compacted, 'as:name', '@value'); + $apcontact['nick'] = JsonLD::fetchElement($data, 'preferredUsername') ?? ''; + $apcontact['name'] = JsonLD::fetchElement($data, 'name'); if (empty($apcontact['name'])) { $apcontact['name'] = $apcontact['nick']; } - $apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($compacted, 'as:summary', '@value')); + $apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($data, 'summary')); - $apcontact['photo'] = JsonLD::fetchElement($compacted, 'as:icon', '@id'); - if (is_array($apcontact['photo']) || !empty($compacted['as:icon']['as:url']['@id'])) { - $apcontact['photo'] = JsonLD::fetchElement($compacted['as:icon'], 'as:url', '@id'); + $apcontact['photo'] = JsonLD::fetchElement($data, 'icon'); + if (is_array($apcontact['photo']) || !empty($data['icon']['url'])) { + $apcontact['photo'] = JsonLD::fetchElement($data['icon'], 'url'); } if (empty($apcontact['alias'])) { - $apcontact['alias'] = JsonLD::fetchElement($compacted, 'as:url', '@id'); + $apcontact['alias'] = JsonLD::fetchElement($data, 'url'); if (is_array($apcontact['alias'])) { - $apcontact['alias'] = JsonLD::fetchElement($compacted['as:url'], 'as:href', '@id'); + $apcontact['alias'] = JsonLD::fetchElement($data['url'], 'href'); } } @@ -243,43 +241,43 @@ class APContact } $apcontact['pubkey'] = null; - if (!empty($compacted['w3id:publicKey'])) { - $apcontact['pubkey'] = trim(JsonLD::fetchElement($compacted['w3id:publicKey'], 'w3id:publicKeyPem', '@value')); + if (!empty($data['publicKey'])) { + $apcontact['pubkey'] = trim(JsonLD::fetchElement($data['publicKey'], 'publicKeyPem')); if (strstr($apcontact['pubkey'], 'RSA ')) { $apcontact['pubkey'] = Crypto::rsaToPem($apcontact['pubkey']); } } - $apcontact['manually-approve'] = (int)JsonLD::fetchElement($compacted, 'as:manuallyApprovesFollowers'); + $apcontact['manually-approve'] = (int)JsonLD::fetchElement($data, 'manuallyApprovesFollowers'); - if (!empty($compacted['as:generator'])) { - $apcontact['baseurl'] = JsonLD::fetchElement($compacted['as:generator'], 'as:url', '@id'); - $apcontact['generator'] = JsonLD::fetchElement($compacted['as:generator'], 'as:name', '@value'); + if (!empty($data['generator'])) { + $apcontact['baseurl'] = JsonLD::fetchElement($data['generator'], 'url'); + $apcontact['generator'] = JsonLD::fetchElement($data['generator'], 'name'); } if (!empty($apcontact['following'])) { - $data = ActivityPub::fetchContent($apcontact['following']); - if (!empty($data)) { - if (!empty($data['totalItems'])) { - $apcontact['following_count'] = $data['totalItems']; + $content = ActivityPub::fetchContent($apcontact['following']); + if (!empty($content)) { + if (!empty($content['totalItems'])) { + $apcontact['following_count'] = $content['totalItems']; } } } if (!empty($apcontact['followers'])) { - $data = ActivityPub::fetchContent($apcontact['followers']); - if (!empty($data)) { - if (!empty($data['totalItems'])) { - $apcontact['followers_count'] = $data['totalItems']; + $content = ActivityPub::fetchContent($apcontact['followers']); + if (!empty($content)) { + if (!empty($content['totalItems'])) { + $apcontact['followers_count'] = $content['totalItems']; } } } if (!empty($apcontact['outbox'])) { - $data = ActivityPub::fetchContent($apcontact['outbox']); - if (!empty($data)) { - if (!empty($data['totalItems'])) { - $apcontact['statuses_count'] = $data['totalItems']; + $content = ActivityPub::fetchContent($apcontact['outbox']); + if (!empty($content)) { + if (!empty($content['totalItems'])) { + $apcontact['statuses_count'] = $content['totalItems']; } } } diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index c42dad2eb3..0b4810627d 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -60,7 +60,7 @@ use Friendica\Util\JsonLD; class ActivityPub { const PUBLIC_COLLECTION = 'https://www.w3.org/ns/activitystreams#Public'; - const CONTEXT = ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', + const CONTEXT = ['https://www.w3.org/ns/activitystreams', ['vcard' => 'http://www.w3.org/2006/vcard/ns#', 'dfrn' => 'http://purl.org/macgirvin/dfrn/1.0/', 'diaspora' => 'https://diasporafoundation.org/ns/', diff --git a/src/Util/JsonLD.php b/src/Util/JsonLD.php index 50396474a6..7692cefc2f 100644 --- a/src/Util/JsonLD.php +++ b/src/Util/JsonLD.php @@ -24,6 +24,7 @@ namespace Friendica\Util; use Friendica\Core\Cache\Duration; use Friendica\Core\Logger; use Exception; +use Friendica\Core\System; use Friendica\DI; /** @@ -67,6 +68,20 @@ class JsonLD return $data; } + public static function removeSecurityLink(array $json) + { + if (!is_array($json['@context'])) { + return $json; + } + + if (($key = array_search('https://w3id.org/security/v1', $json['@context'])) !== false) { + unset($json['@context'][$key]); + $json['@context'] = array_values(array_filter($json['@context'])); + } + + return $json; + } + public static function fixContext(array $json) { // Preparation for adding possibly missing content to the context @@ -111,7 +126,7 @@ class JsonLD */ public static function normalize($json) { - $json = self::fixContext($json); + $json = self::removeSecurityLink($json); jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader'); @@ -177,7 +192,7 @@ class JsonLD } catch (Exception $e) { $compacted = false; - Logger::error('compacting error'); + Logger::error('compacting error', ['callstack' => System::callstack(20)]); // Sooner or later we should log some details as well - but currently this leads to memory issues // Logger::log('compacting error:' . substr(print_r($e, true), 0, 10000), Logger::DEBUG); } From 4b4218f5162e11d1502bf49a12e6411e779a54df Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 16 May 2021 19:31:10 +0000 Subject: [PATCH 2/9] Compact using a predefined context to fix content from Pleroma --- src/Util/JsonLD.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Util/JsonLD.php b/src/Util/JsonLD.php index 7692cefc2f..ee5e0aea97 100644 --- a/src/Util/JsonLD.php +++ b/src/Util/JsonLD.php @@ -26,6 +26,7 @@ use Friendica\Core\Logger; use Exception; use Friendica\Core\System; use Friendica\DI; +use Friendica\Protocol\ActivityPub; /** * This class contain methods to work with JsonLD data @@ -161,6 +162,26 @@ class JsonLD * @throws Exception */ public static function compact($json) + { + $context = $json['@context'] ?? []; + $json['@context'] = ActivityPub::CONTEXT; + + $compacted = self::internalCompact($json); + if (empty($compacted)) { + Logger::info('Failed to compact with our context'); + $json['@context'] = $context; + $compacted = self::internalCompact($json); + if (empty($compacted)) { + Logger::info('Failed to compact with original context'); + } else { + Logger::info('Successful compacted with original context'); + } + } + + return $compacted; + } + + private static function internalCompact($json) { $json = self::fixContext($json); @@ -192,9 +213,7 @@ class JsonLD } catch (Exception $e) { $compacted = false; - Logger::error('compacting error', ['callstack' => System::callstack(20)]); - // Sooner or later we should log some details as well - but currently this leads to memory issues - // Logger::log('compacting error:' . substr(print_r($e, true), 0, 10000), Logger::DEBUG); + Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage(),'callstack' => System::callstack(20)]); } $json = json_decode(json_encode($compacted, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), true); From a44cf44708316d9c450fb0ffa53adf63081817e6 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 16 May 2021 16:10:22 -0400 Subject: [PATCH 3/9] Remove duplicated conditions, improve variables names in Model\APContact --- src/Model/APContact.php | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 44773bf7e7..8a1b3213d5 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -256,29 +256,23 @@ class APContact } if (!empty($apcontact['following'])) { - $content = ActivityPub::fetchContent($apcontact['following']); - if (!empty($content)) { - if (!empty($content['totalItems'])) { - $apcontact['following_count'] = $content['totalItems']; - } + $following = ActivityPub::fetchContent($apcontact['following']); + if (!empty($following['totalItems'])) { + $apcontact['following_count'] = $following['totalItems']; } } if (!empty($apcontact['followers'])) { - $content = ActivityPub::fetchContent($apcontact['followers']); - if (!empty($content)) { - if (!empty($content['totalItems'])) { - $apcontact['followers_count'] = $content['totalItems']; - } + $followers = ActivityPub::fetchContent($apcontact['followers']); + if (!empty($followers['totalItems'])) { + $apcontact['followers_count'] = $followers['totalItems']; } } if (!empty($apcontact['outbox'])) { - $content = ActivityPub::fetchContent($apcontact['outbox']); - if (!empty($content)) { - if (!empty($content['totalItems'])) { - $apcontact['statuses_count'] = $content['totalItems']; - } + $outbox = ActivityPub::fetchContent($apcontact['outbox']); + if (!empty($outbox['totalItems'])) { + $apcontact['statuses_count'] = $outbox['totalItems']; } } From c21d991208c0ed454e41b851d726d195bbc2077f Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 16 May 2021 20:58:11 +0000 Subject: [PATCH 4/9] Use local copy of the w3id security context --- src/Util/JsonLD.php | 77 +++++++++++------------------------- src/Util/LDSignature.php | 2 +- static/w3id-security-v1.json | 49 +++++++++++++++++++++++ 3 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 static/w3id-security-v1.json diff --git a/src/Util/JsonLD.php b/src/Util/JsonLD.php index ee5e0aea97..c20d4846bf 100644 --- a/src/Util/JsonLD.php +++ b/src/Util/JsonLD.php @@ -69,49 +69,14 @@ class JsonLD return $data; } - public static function removeSecurityLink(array $json) + private static function replaceSecurityLink(array $json) { if (!is_array($json['@context'])) { return $json; } if (($key = array_search('https://w3id.org/security/v1', $json['@context'])) !== false) { - unset($json['@context'][$key]); - $json['@context'] = array_values(array_filter($json['@context'])); - } - - return $json; - } - - public static function fixContext(array $json) - { - // Preparation for adding possibly missing content to the context - if (!empty($json['@context']) && is_string($json['@context'])) { - $json['@context'] = [$json['@context']]; - } - - if (($key = array_search('https://w3id.org/security/v1', $json['@context'])) !== false) { - unset($json['@context'][$key]); - $json['@context'] = array_values(array_filter($json['@context'])); - } - - $last_entry = count($json['@context']) - 1; - - $additional = [ - 'w3id' => 'https://w3id.org/security#', - 'signature' => 'w3id:signature', - 'RsaSignature2017' => 'w3id:RsaSignature2017', - 'created' => 'w3id:created', - 'creator' => 'w3id:creator', - 'nonce' => 'w3id:nonce', - 'signatureValue' => 'w3id:signatureValue', - 'publicKey' => 'w3id:publicKey', - 'publicKeyPem' => 'w3id:publicKeyPem']; - - if (is_array($json['@context'][$last_entry])) { - $json['@context'][$last_entry] = array_merge($json['@context'][$last_entry], $additional); - } else { - $json['@context'][] = $additional; + $json['@context'][$key] = DI::baseUrl() . '/static/w3id-security-v1.json'; } return $json; @@ -127,7 +92,7 @@ class JsonLD */ public static function normalize($json) { - $json = self::removeSecurityLink($json); + $json = self::replaceSecurityLink($json); jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader'); @@ -163,32 +128,23 @@ class JsonLD */ public static function compact($json) { - $context = $json['@context'] ?? []; - $json['@context'] = ActivityPub::CONTEXT; - - $compacted = self::internalCompact($json); + $compacted = self::internalCompact($json, false); if (empty($compacted)) { - Logger::info('Failed to compact with our context'); - $json['@context'] = $context; - $compacted = self::internalCompact($json); - if (empty($compacted)) { - Logger::info('Failed to compact with original context'); - } else { - Logger::info('Successful compacted with original context'); - } + $json['@context'] = ActivityPub::CONTEXT; + $compacted = self::internalCompact($json, true); } return $compacted; } - private static function internalCompact($json) + private static function internalCompact($json, bool $error_log) { - $json = self::fixContext($json); + $json = self::replaceSecurityLink($json); jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader'); $context = (object)['as' => 'https://www.w3.org/ns/activitystreams#', - 'w3id' => (object)['@id' => 'https://w3id.org/security#', '@type' => '@id'], + 'w3id' => 'https://w3id.org/security#', 'ldp' => (object)['@id' => 'http://www.w3.org/ns/ldp#', '@type' => '@id'], 'vcard' => (object)['@id' => 'http://www.w3.org/2006/vcard/ns#', '@type' => '@id'], 'dfrn' => (object)['@id' => 'http://purl.org/macgirvin/dfrn/1.0/', '@type' => '@id'], @@ -200,6 +156,17 @@ class JsonLD 'sc' => (object)['@id' => 'http://schema.org#', '@type' => '@id'], 'pt' => (object)['@id' => 'https://joinpeertube.org/ns#', '@type' => '@id']]; + // Preparation for adding possibly missing content to the context + if (!empty($json['@context']) && is_string($json['@context'])) { + $json['@context'] = [$json['@context']]; + } + + // Workaround for servers with missing context + // See issue https://github.com/nextcloud/social/issues/330 + if (!empty($json['@context']) && is_array($json['@context'])) { + $json['@context'][] = DI::baseUrl() . '/static/w3id-security-v1.json'; + } + // Trying to avoid memory problems with large content fields if (!empty($json['object']['source']['content'])) { $content = $json['object']['source']['content']; @@ -213,7 +180,9 @@ class JsonLD } catch (Exception $e) { $compacted = false; - Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage(),'callstack' => System::callstack(20)]); + if ($error_log) { + Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage(),'callstack' => System::callstack(20)]); + } } $json = json_decode(json_encode($compacted, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), true); diff --git a/src/Util/LDSignature.php b/src/Util/LDSignature.php index dcbb9ccae3..f51756633c 100644 --- a/src/Util/LDSignature.php +++ b/src/Util/LDSignature.php @@ -57,7 +57,7 @@ class LDSignature $dhash = self::hash(self::signableData($data)); $x = Crypto::rsaVerify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey); - Logger::log('LD-verify: ' . intval($x)); + Logger::notice('LD-verify', ['verified' => (int)$x, 'actor' => $profile['url']]); if (empty($x)) { return false; diff --git a/static/w3id-security-v1.json b/static/w3id-security-v1.json new file mode 100644 index 0000000000..765650d348 --- /dev/null +++ b/static/w3id-security-v1.json @@ -0,0 +1,49 @@ +{ + "@context": { + "id": "@id", + "type": "@type", + + "dc": "http://purl.org/dc/terms/", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", + "Ed25519Signature2018": "sec:Ed25519Signature2018", + "EncryptedMessage": "sec:EncryptedMessage", + "GraphSignature2012": "sec:GraphSignature2012", + "LinkedDataSignature2015": "sec:LinkedDataSignature2015", + "LinkedDataSignature2016": "sec:LinkedDataSignature2016", + "CryptographicKey": "sec:Key", + + "authenticationTag": "sec:authenticationTag", + "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", + "cipherAlgorithm": "sec:cipherAlgorithm", + "cipherData": "sec:cipherData", + "cipherKey": "sec:cipherKey", + "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, + "creator": {"@id": "dc:creator", "@type": "@id"}, + "digestAlgorithm": "sec:digestAlgorithm", + "digestValue": "sec:digestValue", + "domain": "sec:domain", + "encryptionKey": "sec:encryptionKey", + "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "initializationVector": "sec:initializationVector", + "iterationCount": "sec:iterationCount", + "nonce": "sec:nonce", + "normalizationAlgorithm": "sec:normalizationAlgorithm", + "owner": {"@id": "sec:owner", "@type": "@id"}, + "password": "sec:password", + "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, + "privateKeyPem": "sec:privateKeyPem", + "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, + "publicKeyBase58": "sec:publicKeyBase58", + "publicKeyPem": "sec:publicKeyPem", + "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, + "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, + "salt": "sec:salt", + "signature": "sec:signature", + "signatureAlgorithm": "sec:signingAlgorithm", + "signatureValue": "sec:signatureValue" + } + } \ No newline at end of file From ce6b4c27ea162f40798943a0d1b765e0dfb0c89e Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 17 May 2021 05:51:14 +0000 Subject: [PATCH 5/9] Use locally stored original w3c documents --- src/Util/JsonLD.php | 51 ++--- static/activitystreams.jsonld | 379 ++++++++++++++++++++++++++++++++++ static/identity-v1.jsonld | 88 ++++++++ static/security-v1.jsonld | 50 +++++ static/w3id-security-v1.json | 49 ----- 5 files changed, 534 insertions(+), 83 deletions(-) create mode 100644 static/activitystreams.jsonld create mode 100644 static/identity-v1.jsonld create mode 100644 static/security-v1.jsonld delete mode 100644 static/w3id-security-v1.json diff --git a/src/Util/JsonLD.php b/src/Util/JsonLD.php index c20d4846bf..fa169c0046 100644 --- a/src/Util/JsonLD.php +++ b/src/Util/JsonLD.php @@ -24,9 +24,7 @@ namespace Friendica\Util; use Friendica\Core\Cache\Duration; use Friendica\Core\Logger; use Exception; -use Friendica\Core\System; use Friendica\DI; -use Friendica\Protocol\ActivityPub; /** * This class contain methods to work with JsonLD data @@ -43,6 +41,21 @@ class JsonLD */ public static function documentLoader($url) { + switch ($url) { + case 'https://w3id.org/security/v1': + $url = DI::baseUrl() . '/static/security-v1.jsonld'; + break; + case 'https://w3id.org/identity/v1': + $url = DI::baseUrl() . '/static/identity-v1.jsonld'; + break; + case 'https://www.w3.org/ns/activitystreams': + $url = DI::baseUrl() . '/static/activitystreams.jsonld'; + break; + default: + Logger::info('Got url', ['url' =>$url]); + break; + } + $recursion = 0; $x = debug_backtrace(); @@ -69,19 +82,6 @@ class JsonLD return $data; } - private static function replaceSecurityLink(array $json) - { - if (!is_array($json['@context'])) { - return $json; - } - - if (($key = array_search('https://w3id.org/security/v1', $json['@context'])) !== false) { - $json['@context'][$key] = DI::baseUrl() . '/static/w3id-security-v1.json'; - } - - return $json; - } - /** * Normalises a given JSON array * @@ -92,8 +92,6 @@ class JsonLD */ public static function normalize($json) { - $json = self::replaceSecurityLink($json); - jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader'); $jsonobj = json_decode(json_encode($json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); @@ -128,19 +126,6 @@ class JsonLD */ public static function compact($json) { - $compacted = self::internalCompact($json, false); - if (empty($compacted)) { - $json['@context'] = ActivityPub::CONTEXT; - $compacted = self::internalCompact($json, true); - } - - return $compacted; - } - - private static function internalCompact($json, bool $error_log) - { - $json = self::replaceSecurityLink($json); - jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader'); $context = (object)['as' => 'https://www.w3.org/ns/activitystreams#', @@ -164,7 +149,7 @@ class JsonLD // Workaround for servers with missing context // See issue https://github.com/nextcloud/social/issues/330 if (!empty($json['@context']) && is_array($json['@context'])) { - $json['@context'][] = DI::baseUrl() . '/static/w3id-security-v1.json'; + $json['@context'][] = 'https://w3id.org/security/v1'; } // Trying to avoid memory problems with large content fields @@ -180,9 +165,7 @@ class JsonLD } catch (Exception $e) { $compacted = false; - if ($error_log) { - Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage(),'callstack' => System::callstack(20)]); - } + Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage()]); } $json = json_decode(json_encode($compacted, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), true); diff --git a/static/activitystreams.jsonld b/static/activitystreams.jsonld new file mode 100644 index 0000000000..037026ca4d --- /dev/null +++ b/static/activitystreams.jsonld @@ -0,0 +1,379 @@ +{ + "@context": { + "@vocab": "_:", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "as": "https://www.w3.org/ns/activitystreams#", + "ldp": "http://www.w3.org/ns/ldp#", + "vcard": "http://www.w3.org/2006/vcard/ns#", + "id": "@id", + "type": "@type", + "Accept": "as:Accept", + "Activity": "as:Activity", + "IntransitiveActivity": "as:IntransitiveActivity", + "Add": "as:Add", + "Announce": "as:Announce", + "Application": "as:Application", + "Arrive": "as:Arrive", + "Article": "as:Article", + "Audio": "as:Audio", + "Block": "as:Block", + "Collection": "as:Collection", + "CollectionPage": "as:CollectionPage", + "Relationship": "as:Relationship", + "Create": "as:Create", + "Delete": "as:Delete", + "Dislike": "as:Dislike", + "Document": "as:Document", + "Event": "as:Event", + "Follow": "as:Follow", + "Flag": "as:Flag", + "Group": "as:Group", + "Ignore": "as:Ignore", + "Image": "as:Image", + "Invite": "as:Invite", + "Join": "as:Join", + "Leave": "as:Leave", + "Like": "as:Like", + "Link": "as:Link", + "Mention": "as:Mention", + "Note": "as:Note", + "Object": "as:Object", + "Offer": "as:Offer", + "OrderedCollection": "as:OrderedCollection", + "OrderedCollectionPage": "as:OrderedCollectionPage", + "Organization": "as:Organization", + "Page": "as:Page", + "Person": "as:Person", + "Place": "as:Place", + "Profile": "as:Profile", + "Question": "as:Question", + "Reject": "as:Reject", + "Remove": "as:Remove", + "Service": "as:Service", + "TentativeAccept": "as:TentativeAccept", + "TentativeReject": "as:TentativeReject", + "Tombstone": "as:Tombstone", + "Undo": "as:Undo", + "Update": "as:Update", + "Video": "as:Video", + "View": "as:View", + "Listen": "as:Listen", + "Read": "as:Read", + "Move": "as:Move", + "Travel": "as:Travel", + "IsFollowing": "as:IsFollowing", + "IsFollowedBy": "as:IsFollowedBy", + "IsContact": "as:IsContact", + "IsMember": "as:IsMember", + "subject": { + "@id": "as:subject", + "@type": "@id" + }, + "relationship": { + "@id": "as:relationship", + "@type": "@id" + }, + "actor": { + "@id": "as:actor", + "@type": "@id" + }, + "attributedTo": { + "@id": "as:attributedTo", + "@type": "@id" + }, + "attachment": { + "@id": "as:attachment", + "@type": "@id" + }, + "bcc": { + "@id": "as:bcc", + "@type": "@id" + }, + "bto": { + "@id": "as:bto", + "@type": "@id" + }, + "cc": { + "@id": "as:cc", + "@type": "@id" + }, + "context": { + "@id": "as:context", + "@type": "@id" + }, + "current": { + "@id": "as:current", + "@type": "@id" + }, + "first": { + "@id": "as:first", + "@type": "@id" + }, + "generator": { + "@id": "as:generator", + "@type": "@id" + }, + "icon": { + "@id": "as:icon", + "@type": "@id" + }, + "image": { + "@id": "as:image", + "@type": "@id" + }, + "inReplyTo": { + "@id": "as:inReplyTo", + "@type": "@id" + }, + "items": { + "@id": "as:items", + "@type": "@id" + }, + "instrument": { + "@id": "as:instrument", + "@type": "@id" + }, + "orderedItems": { + "@id": "as:items", + "@type": "@id", + "@container": "@list" + }, + "last": { + "@id": "as:last", + "@type": "@id" + }, + "location": { + "@id": "as:location", + "@type": "@id" + }, + "next": { + "@id": "as:next", + "@type": "@id" + }, + "object": { + "@id": "as:object", + "@type": "@id" + }, + "oneOf": { + "@id": "as:oneOf", + "@type": "@id" + }, + "anyOf": { + "@id": "as:anyOf", + "@type": "@id" + }, + "closed": { + "@id": "as:closed", + "@type": "xsd:dateTime" + }, + "origin": { + "@id": "as:origin", + "@type": "@id" + }, + "accuracy": { + "@id": "as:accuracy", + "@type": "xsd:float" + }, + "prev": { + "@id": "as:prev", + "@type": "@id" + }, + "preview": { + "@id": "as:preview", + "@type": "@id" + }, + "replies": { + "@id": "as:replies", + "@type": "@id" + }, + "result": { + "@id": "as:result", + "@type": "@id" + }, + "audience": { + "@id": "as:audience", + "@type": "@id" + }, + "partOf": { + "@id": "as:partOf", + "@type": "@id" + }, + "tag": { + "@id": "as:tag", + "@type": "@id" + }, + "target": { + "@id": "as:target", + "@type": "@id" + }, + "to": { + "@id": "as:to", + "@type": "@id" + }, + "url": { + "@id": "as:url", + "@type": "@id" + }, + "altitude": { + "@id": "as:altitude", + "@type": "xsd:float" + }, + "content": "as:content", + "contentMap": { + "@id": "as:content", + "@container": "@language" + }, + "name": "as:name", + "nameMap": { + "@id": "as:name", + "@container": "@language" + }, + "duration": { + "@id": "as:duration", + "@type": "xsd:duration" + }, + "endTime": { + "@id": "as:endTime", + "@type": "xsd:dateTime" + }, + "height": { + "@id": "as:height", + "@type": "xsd:nonNegativeInteger" + }, + "href": { + "@id": "as:href", + "@type": "@id" + }, + "hreflang": "as:hreflang", + "latitude": { + "@id": "as:latitude", + "@type": "xsd:float" + }, + "longitude": { + "@id": "as:longitude", + "@type": "xsd:float" + }, + "mediaType": "as:mediaType", + "published": { + "@id": "as:published", + "@type": "xsd:dateTime" + }, + "radius": { + "@id": "as:radius", + "@type": "xsd:float" + }, + "rel": "as:rel", + "startIndex": { + "@id": "as:startIndex", + "@type": "xsd:nonNegativeInteger" + }, + "startTime": { + "@id": "as:startTime", + "@type": "xsd:dateTime" + }, + "summary": "as:summary", + "summaryMap": { + "@id": "as:summary", + "@container": "@language" + }, + "totalItems": { + "@id": "as:totalItems", + "@type": "xsd:nonNegativeInteger" + }, + "units": "as:units", + "updated": { + "@id": "as:updated", + "@type": "xsd:dateTime" + }, + "width": { + "@id": "as:width", + "@type": "xsd:nonNegativeInteger" + }, + "describes": { + "@id": "as:describes", + "@type": "@id" + }, + "formerType": { + "@id": "as:formerType", + "@type": "@id" + }, + "deleted": { + "@id": "as:deleted", + "@type": "xsd:dateTime" + }, + "inbox": { + "@id": "ldp:inbox", + "@type": "@id" + }, + "outbox": { + "@id": "as:outbox", + "@type": "@id" + }, + "following": { + "@id": "as:following", + "@type": "@id" + }, + "followers": { + "@id": "as:followers", + "@type": "@id" + }, + "streams": { + "@id": "as:streams", + "@type": "@id" + }, + "preferredUsername": "as:preferredUsername", + "endpoints": { + "@id": "as:endpoints", + "@type": "@id" + }, + "uploadMedia": { + "@id": "as:uploadMedia", + "@type": "@id" + }, + "proxyUrl": { + "@id": "as:proxyUrl", + "@type": "@id" + }, + "liked": { + "@id": "as:liked", + "@type": "@id" + }, + "oauthAuthorizationEndpoint": { + "@id": "as:oauthAuthorizationEndpoint", + "@type": "@id" + }, + "oauthTokenEndpoint": { + "@id": "as:oauthTokenEndpoint", + "@type": "@id" + }, + "provideClientKey": { + "@id": "as:provideClientKey", + "@type": "@id" + }, + "signClientKey": { + "@id": "as:signClientKey", + "@type": "@id" + }, + "sharedInbox": { + "@id": "as:sharedInbox", + "@type": "@id" + }, + "Public": { + "@id": "as:Public", + "@type": "@id" + }, + "source": "as:source", + "likes": { + "@id": "as:likes", + "@type": "@id" + }, + "shares": { + "@id": "as:shares", + "@type": "@id" + }, + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + } + } +} diff --git a/static/identity-v1.jsonld b/static/identity-v1.jsonld new file mode 100644 index 0000000000..06e89083d8 --- /dev/null +++ b/static/identity-v1.jsonld @@ -0,0 +1,88 @@ +{ + "@context": { + "id": "@id", + "type": "@type", + + "cred": "https://w3id.org/credentials#", + "dc": "http://purl.org/dc/terms/", + "identity": "https://w3id.org/identity#", + "perm": "https://w3id.org/permissions#", + "ps": "https://w3id.org/payswarm#", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "sec": "https://w3id.org/security#", + "schema": "http://schema.org/", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "Group": "https://www.w3.org/ns/activitystreams#Group", + + "claim": {"@id": "cred:claim", "@type": "@id"}, + "credential": {"@id": "cred:credential", "@type": "@id"}, + "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, + "issuer": {"@id": "cred:issuer", "@type": "@id"}, + "recipient": {"@id": "cred:recipient", "@type": "@id"}, + "Credential": "cred:Credential", + "CryptographicKeyCredential": "cred:CryptographicKeyCredential", + + "about": {"@id": "schema:about", "@type": "@id"}, + "address": {"@id": "schema:address", "@type": "@id"}, + "addressCountry": "schema:addressCountry", + "addressLocality": "schema:addressLocality", + "addressRegion": "schema:addressRegion", + "comment": "rdfs:comment", + "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, + "creator": {"@id": "dc:creator", "@type": "@id"}, + "description": "schema:description", + "email": "schema:email", + "familyName": "schema:familyName", + "givenName": "schema:givenName", + "image": {"@id": "schema:image", "@type": "@id"}, + "label": "rdfs:label", + "name": "schema:name", + "postalCode": "schema:postalCode", + "streetAddress": "schema:streetAddress", + "title": "dc:title", + "url": {"@id": "schema:url", "@type": "@id"}, + "Person": "schema:Person", + "PostalAddress": "schema:PostalAddress", + "Organization": "schema:Organization", + + "identityService": {"@id": "identity:identityService", "@type": "@id"}, + "idp": {"@id": "identity:idp", "@type": "@id"}, + "Identity": "identity:Identity", + + "paymentProcessor": "ps:processor", + "preferences": {"@id": "ps:preferences", "@type": "@vocab"}, + + "cipherAlgorithm": "sec:cipherAlgorithm", + "cipherData": "sec:cipherData", + "cipherKey": "sec:cipherKey", + "digestAlgorithm": "sec:digestAlgorithm", + "digestValue": "sec:digestValue", + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "initializationVector": "sec:initializationVector", + "member": {"@id": "schema:member", "@type": "@id"}, + "memberOf": {"@id": "schema:memberOf", "@type": "@id"}, + "nonce": "sec:nonce", + "normalizationAlgorithm": "sec:normalizationAlgorithm", + "owner": {"@id": "sec:owner", "@type": "@id"}, + "password": "sec:password", + "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, + "privateKeyPem": "sec:privateKeyPem", + "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, + "publicKeyPem": "sec:publicKeyPem", + "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, + "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, + "signature": "sec:signature", + "signatureAlgorithm": "sec:signatureAlgorithm", + "signatureValue": "sec:signatureValue", + "CryptographicKey": "sec:Key", + "EncryptedMessage": "sec:EncryptedMessage", + "GraphSignature2012": "sec:GraphSignature2012", + "LinkedDataSignature2015": "sec:LinkedDataSignature2015", + + "accessControl": {"@id": "perm:accessControl", "@type": "@id"}, + "writePermission": {"@id": "perm:writePermission", "@type": "@id"} + } +} diff --git a/static/security-v1.jsonld b/static/security-v1.jsonld new file mode 100644 index 0000000000..7529505260 --- /dev/null +++ b/static/security-v1.jsonld @@ -0,0 +1,50 @@ +{ + "@context": { + "id": "@id", + "type": "@type", + + "dc": "http://purl.org/dc/terms/", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", + "Ed25519Signature2018": "sec:Ed25519Signature2018", + "EncryptedMessage": "sec:EncryptedMessage", + "GraphSignature2012": "sec:GraphSignature2012", + "LinkedDataSignature2015": "sec:LinkedDataSignature2015", + "LinkedDataSignature2016": "sec:LinkedDataSignature2016", + "CryptographicKey": "sec:Key", + + "authenticationTag": "sec:authenticationTag", + "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", + "cipherAlgorithm": "sec:cipherAlgorithm", + "cipherData": "sec:cipherData", + "cipherKey": "sec:cipherKey", + "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, + "creator": {"@id": "dc:creator", "@type": "@id"}, + "digestAlgorithm": "sec:digestAlgorithm", + "digestValue": "sec:digestValue", + "domain": "sec:domain", + "encryptionKey": "sec:encryptionKey", + "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "initializationVector": "sec:initializationVector", + "iterationCount": "sec:iterationCount", + "nonce": "sec:nonce", + "normalizationAlgorithm": "sec:normalizationAlgorithm", + "owner": {"@id": "sec:owner", "@type": "@id"}, + "password": "sec:password", + "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, + "privateKeyPem": "sec:privateKeyPem", + "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, + "publicKeyBase58": "sec:publicKeyBase58", + "publicKeyPem": "sec:publicKeyPem", + "publicKeyWif": "sec:publicKeyWif", + "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, + "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, + "salt": "sec:salt", + "signature": "sec:signature", + "signatureAlgorithm": "sec:signingAlgorithm", + "signatureValue": "sec:signatureValue" + } +} diff --git a/static/w3id-security-v1.json b/static/w3id-security-v1.json deleted file mode 100644 index 765650d348..0000000000 --- a/static/w3id-security-v1.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "@context": { - "id": "@id", - "type": "@type", - - "dc": "http://purl.org/dc/terms/", - "sec": "https://w3id.org/security#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - - "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", - "Ed25519Signature2018": "sec:Ed25519Signature2018", - "EncryptedMessage": "sec:EncryptedMessage", - "GraphSignature2012": "sec:GraphSignature2012", - "LinkedDataSignature2015": "sec:LinkedDataSignature2015", - "LinkedDataSignature2016": "sec:LinkedDataSignature2016", - "CryptographicKey": "sec:Key", - - "authenticationTag": "sec:authenticationTag", - "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", - "cipherAlgorithm": "sec:cipherAlgorithm", - "cipherData": "sec:cipherData", - "cipherKey": "sec:cipherKey", - "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, - "creator": {"@id": "dc:creator", "@type": "@id"}, - "digestAlgorithm": "sec:digestAlgorithm", - "digestValue": "sec:digestValue", - "domain": "sec:domain", - "encryptionKey": "sec:encryptionKey", - "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, - "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, - "initializationVector": "sec:initializationVector", - "iterationCount": "sec:iterationCount", - "nonce": "sec:nonce", - "normalizationAlgorithm": "sec:normalizationAlgorithm", - "owner": {"@id": "sec:owner", "@type": "@id"}, - "password": "sec:password", - "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, - "privateKeyPem": "sec:privateKeyPem", - "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, - "publicKeyBase58": "sec:publicKeyBase58", - "publicKeyPem": "sec:publicKeyPem", - "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, - "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, - "salt": "sec:salt", - "signature": "sec:signature", - "signatureAlgorithm": "sec:signingAlgorithm", - "signatureValue": "sec:signatureValue" - } - } \ No newline at end of file From cb7206d92f2576a712d17c58dfc5da8213548289 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 17 May 2021 05:59:41 +0000 Subject: [PATCH 6/9] Reverted yesterdays panic coding --- src/Model/APContact.php | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 8a1b3213d5..0d482ced78 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -165,10 +165,11 @@ class APContact return $fetched_contact; } - if (empty($data['id'])) { + $compacted = JsonLD::compact($data); + if (empty($compacted['@id'])) { return $fetched_contact; } - + // Detect multiple fast repeating request to the same address // See https://github.com/friendica/friendica/issues/9303 $cachekey = 'apcontact:getByURL:' . $url; @@ -179,39 +180,40 @@ class APContact DI::cache()->set($cachekey, System::callstack(20), Duration::FIVE_MINUTES); } - $apcontact['url'] = $data['id']; - $apcontact['uuid'] = JsonLD::fetchElement($data, 'diaspora:guid'); - $apcontact['type'] = JsonLD::fetchElement($data, 'type'); - $apcontact['following'] = JsonLD::fetchElement($data, 'following'); - $apcontact['followers'] = JsonLD::fetchElement($data, 'followers'); - $apcontact['inbox'] = JsonLD::fetchElement($data, 'inbox'); + $apcontact['url'] = $compacted['@id']; + $apcontact['uuid'] = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value'); + $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type')); + $apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id'); + $apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id'); + $apcontact['inbox'] = JsonLD::fetchElement($compacted, 'ldp:inbox', '@id'); self::unarchiveInbox($apcontact['inbox'], false); - $apcontact['outbox'] = JsonLD::fetchElement($data, 'outbox'); + + $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id'); $apcontact['sharedinbox'] = ''; - if (!empty($data['endpoints'])) { - $apcontact['sharedinbox'] = JsonLD::fetchElement($data['endpoints'], 'sharedInbox'); + if (!empty($compacted['as:endpoints'])) { + $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedbox', '@id'); self::unarchiveInbox($apcontact['sharedinbox'], true); } - $apcontact['nick'] = JsonLD::fetchElement($data, 'preferredUsername') ?? ''; - $apcontact['name'] = JsonLD::fetchElement($data, 'name'); + $apcontact['nick'] = JsonLD::fetchElement($compacted, 'as:preferredUsername', '@value') ?? ''; + $apcontact['name'] = JsonLD::fetchElement($compacted, 'as:name', '@value'); if (empty($apcontact['name'])) { $apcontact['name'] = $apcontact['nick']; } - $apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($data, 'summary')); + $apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($compacted, 'as:summary', '@value')); - $apcontact['photo'] = JsonLD::fetchElement($data, 'icon'); - if (is_array($apcontact['photo']) || !empty($data['icon']['url'])) { - $apcontact['photo'] = JsonLD::fetchElement($data['icon'], 'url'); + $apcontact['photo'] = JsonLD::fetchElement($compacted, 'as:icon', '@id'); + if (is_array($apcontact['photo']) || !empty($compacted['as:icon']['as:url']['@id'])) { + $apcontact['photo'] = JsonLD::fetchElement($compacted['as:icon'], 'as:url', '@id'); } if (empty($apcontact['alias'])) { - $apcontact['alias'] = JsonLD::fetchElement($data, 'url'); + $apcontact['alias'] = JsonLD::fetchElement($compacted, 'as:url', '@id'); if (is_array($apcontact['alias'])) { - $apcontact['alias'] = JsonLD::fetchElement($data['url'], 'href'); + $apcontact['alias'] = JsonLD::fetchElement($compacted['as:url'], 'as:href', '@id'); } } @@ -241,18 +243,18 @@ class APContact } $apcontact['pubkey'] = null; - if (!empty($data['publicKey'])) { - $apcontact['pubkey'] = trim(JsonLD::fetchElement($data['publicKey'], 'publicKeyPem')); + if (!empty($compacted['w3id:publicKey'])) { + $apcontact['pubkey'] = trim(JsonLD::fetchElement($compacted['w3id:publicKey'], 'w3id:publicKeyPem', '@value')); if (strstr($apcontact['pubkey'], 'RSA ')) { $apcontact['pubkey'] = Crypto::rsaToPem($apcontact['pubkey']); } } - $apcontact['manually-approve'] = (int)JsonLD::fetchElement($data, 'manuallyApprovesFollowers'); + $apcontact['manually-approve'] = (int)JsonLD::fetchElement($compacted, 'as:manuallyApprovesFollowers'); - if (!empty($data['generator'])) { - $apcontact['baseurl'] = JsonLD::fetchElement($data['generator'], 'url'); - $apcontact['generator'] = JsonLD::fetchElement($data['generator'], 'name'); + if (!empty($compacted['as:generator'])) { + $apcontact['baseurl'] = JsonLD::fetchElement($compacted['as:generator'], 'as:url', '@id'); + $apcontact['generator'] = JsonLD::fetchElement($compacted['as:generator'], 'as:name', '@value'); } if (!empty($apcontact['following'])) { From 2e6cf056c1da8964f9b012b2050e34619b2ae68a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 17 May 2021 06:01:47 +0000 Subject: [PATCH 7/9] Whitespace removed --- src/Model/APContact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 0d482ced78..d945c5e4ed 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -327,7 +327,7 @@ class APContact if (empty($apcontact['subscribe'])) { $apcontact['subscribe'] = null; - } + } if (!empty($apcontact['baseurl']) && empty($fetched_contact['gsid'])) { $apcontact['gsid'] = GServer::getID($apcontact['baseurl']); From 48d703d278d6c9f1f7c63a4efef01e61c634f77e Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 17 May 2021 06:03:14 +0000 Subject: [PATCH 8/9] Fiy missing "in" --- src/Model/APContact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index d945c5e4ed..7a63e413ca 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -192,7 +192,7 @@ class APContact $apcontact['sharedinbox'] = ''; if (!empty($compacted['as:endpoints'])) { - $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedbox', '@id'); + $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id'); self::unarchiveInbox($apcontact['sharedinbox'], true); } From d46db31475333219bd2f9b2f48b9cff0c7ec4ab2 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 17 May 2021 06:04:48 +0000 Subject: [PATCH 9/9] Reverted context --- src/Protocol/ActivityPub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index 0b4810627d..c42dad2eb3 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -60,7 +60,7 @@ use Friendica\Util\JsonLD; class ActivityPub { const PUBLIC_COLLECTION = 'https://www.w3.org/ns/activitystreams#Public'; - const CONTEXT = ['https://www.w3.org/ns/activitystreams', + const CONTEXT = ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', ['vcard' => 'http://www.w3.org/2006/vcard/ns#', 'dfrn' => 'http://purl.org/macgirvin/dfrn/1.0/', 'diaspora' => 'https://diasporafoundation.org/ns/',