<?php
/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
+ * @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
namespace Friendica\Util;
-use Friendica\Core\Cache\Duration;
+use Friendica\Core\Cache\Enum\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
*/
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();
if ($recursion > 5) {
Logger::error('jsonld bomb detected at: ' . $url);
- exit();
+ System::exit();
}
$result = DI::cache()->get('documentLoader:' . $url);
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
- 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;
- }
-
- return $json;
- }
-
/**
* Normalises a given JSON array
*
*/
public static function normalize($json)
{
- $json = self::removeSecurityLink($json);
-
jsonld_set_document_loader('Friendica\Util\JsonLD::documentLoader');
$jsonobj = json_decode(json_encode($json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
*/
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);
-
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'],
'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id'],
'litepub' => (object)['@id' => 'http://litepub.social/ns#', '@type' => '@id'],
'sc' => (object)['@id' => 'http://schema.org#', '@type' => '@id'],
- 'pt' => (object)['@id' => 'https://joinpeertube.org/ns#', '@type' => '@id']];
+ 'pt' => (object)['@id' => 'https://joinpeertube.org/ns#', '@type' => '@id'],
+ 'mobilizon' => (object)['@id' => 'https://joinmobilizon.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'][] = 'https://w3id.org/security/v1';
+ }
// Trying to avoid memory problems with large content fields
if (!empty($json['object']['source']['content'])) {
}
catch (Exception $e) {
$compacted = false;
- Logger::error('compacting error', ['line' => $e->getLine(), 'message' => $e->getMessage(),'callstack' => System::callstack(20)]);
+ Logger::notice('compacting error', ['line' => $e->getLine(), 'exception' => $e]);
}
$json = json_decode(json_encode($compacted, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), true);
}
// If it isn't an array yet, make it to one
- if (!is_int(key($array[$element]))) {
+ if (!is_array($array[$element]) || !is_int(key($array[$element]))) {
$array[$element] = [$array[$element]];
}