aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs/Lib')
-rw-r--r--Zotlabs/Lib/ActivityStreams.php191
-rw-r--r--Zotlabs/Lib/JSalmon.php50
-rw-r--r--Zotlabs/Lib/Libzot.php74
-rw-r--r--Zotlabs/Lib/Zotfinger.php23
4 files changed, 270 insertions, 68 deletions
diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php
index 37e717f58..a322637fd 100644
--- a/Zotlabs/Lib/ActivityStreams.php
+++ b/Zotlabs/Lib/ActivityStreams.php
@@ -7,22 +7,25 @@ namespace Zotlabs\Lib;
*
* Parses an ActivityStream JSON string.
*/
+
class ActivityStreams {
- public $raw = null;
- public $data;
- public $valid = false;
- public $id = '';
- public $type = '';
- public $actor = null;
- public $obj = null;
- public $tgt = null;
- public $origin = null;
- public $owner = null;
- public $signer = null;
- public $ldsig = null;
- public $sigok = false;
- public $recips = null;
+ public $raw = null;
+ public $data = null;
+ public $valid = false;
+ public $deleted = false;
+ public $id = '';
+ public $parent_id = '';
+ public $type = '';
+ public $actor = null;
+ public $obj = null;
+ public $tgt = null;
+ public $origin = null;
+ public $owner = null;
+ public $signer = null;
+ public $ldsig = null;
+ public $sigok = false;
+ public $recips = null;
public $raw_recips = null;
/**
@@ -35,16 +38,49 @@ class ActivityStreams {
function __construct($string) {
$this->raw = $string;
- $this->data = json_decode($string, true);
+
+ if(is_array($string)) {
+ $this->data = $string;
+ }
+ else {
+ $this->data = json_decode($string, true);
+ }
if($this->data) {
+
+ // verify and unpack JSalmon signature if present
+
+ if(is_array($this->data) && array_key_exists('signed',$this->data)) {
+ $ret = JSalmon::verify($this->data);
+ $tmp = JSalmon::unpack($this->data['data']);
+ if($ret && $ret['success']) {
+ if($ret['signer']) {
+ $saved = json_encode($this->data,JSON_UNESCAPED_SLASHES);
+ $this->data = $tmp;
+ $this->data['signer'] = $ret['signer'];
+ $this->data['signed_data'] = $saved;
+ if($ret['hubloc']) {
+ $this->data['hubloc'] = $ret['hubloc'];
+ }
+ }
+ }
+ }
+
$this->valid = true;
+
+ if(array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) {
+ if($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
+ $this->deleted = $this->data['actor'];
+ $this->valid = false;
+ }
+ }
+
}
if($this->is_valid()) {
$this->id = $this->get_property_obj('id');
$this->type = $this->get_primary_type();
- $this->actor = $this->get_compound_property('actor');
+ $this->actor = $this->get_actor('actor','','');
$this->obj = $this->get_compound_property('object');
$this->tgt = $this->get_compound_property('target');
$this->origin = $this->get_compound_property('origin');
@@ -53,14 +89,31 @@ class ActivityStreams {
$this->ldsig = $this->get_compound_property('signature');
if($this->ldsig) {
$this->signer = $this->get_compound_property('creator',$this->ldsig);
- if($this->signer && $this->signer['publicKey'] && $this->signer['publicKey']['publicKeyPem']) {
- $this->sigok = \Zotlabs\Lib\LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
+ if($this->signer && is_array($this->signer) && array_key_exists('publicKey',$this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
+ $this->sigok = LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
}
}
- if(($this->type === 'Note') && (! $this->obj)) {
+ if(! $this->obj) {
$this->obj = $this->data;
$this->type = 'Create';
+ if(! $this->actor) {
+ $this->actor = $this->get_actor('attributedTo',$this->obj);
+ }
+ }
+
+ if($this->obj && is_array($this->obj) && $this->obj['actor'])
+ $this->obj['actor'] = $this->get_actor('actor',$this->obj);
+ if($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
+ $this->tgt['actor'] = $this->get_actor('actor',$this->tgt);
+
+ $this->parent_id = $this->get_property_obj('inReplyTo');
+
+ if((! $this->parent_id) && is_array($this->obj)) {
+ $this->parent_id = $this->obj['inReplyTo'];
+ }
+ if((! $this->parent_id) && is_array($this->obj)) {
+ $this->parent_id = $this->obj['id'];
}
}
}
@@ -190,44 +243,122 @@ class ActivityStreams {
$base = (($base) ? $base : $this->data);
$propname = (($prefix) ? $prefix . ':' : '') . $property;
+ if(! is_array($base)) {
+ btlogger('not an array: ' . print_r($base,true));
+ return null;
+ }
+
return ((array_key_exists($propname, $base)) ? $base[$propname] : null);
}
+
/**
* @brief Fetches a property from an URL.
*
* @param string $url
* @return NULL|mixed
*/
+
function fetch_property($url) {
+ return self::fetch($url);
+ }
+
+ static function fetch($url) {
$redirects = 0;
if(! check_siteallowed($url)) {
logger('blacklisted: ' . $url);
return null;
}
-
+ logger('fetch: ' . $url, LOGGER_DEBUG);
$x = z_fetch_url($url, true, $redirects,
- ['headers' => [ 'Accept: application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ]]);
- if($x['success'])
+ [ 'headers' => [ 'Accept: application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ]]);
+ if($x['success']) {
+ $y = json_decode($x['body'],true);
+ logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
return json_decode($x['body'], true);
+ }
+ else {
+ logger('fetch failed: ' . $url);
+ }
+ return null;
+ }
+
+ static function is_an_actor($s) {
+ return(in_array($s,[ 'Application','Group','Service','Person','Service' ]));
+ }
+
+ /**
+ * @brief
+ *
+ * @param string $property
+ * @param array $base
+ * @param string $namespace (optional) default empty
+ * @return NULL|mixed
+ */
+
+ function get_actor($property,$base='',$namespace = '') {
+ $x = $this->get_property_obj($property, $base, $namespace);
+ if($this->is_url($x)) {
+
+ // SECURITY: If we have already stored the actor profile, re-generate it
+ // from cached data - don't refetch it from the network
+ $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
+ dbesc($x)
+ );
+ if($r) {
+ $y = Activity::encode_person($r[0]);
+ $y['cached'] = true;
+ return $y;
+ }
+ }
+ $actor = $this->get_compound_property($property,$base,$namespace,true);
+ if(is_array($actor) && self::is_an_actor($actor['type'])) {
+ if(array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) {
+ $actor = $this->fetch_property($actor['id']);
+ }
+ return $actor;
+ }
return null;
}
+
/**
* @brief
*
* @param string $property
* @param array $base
* @param string $namespace (optional) default empty
+ * @param boolean $first (optional) default false, if true and result is a sequential array return only the first element
* @return NULL|mixed
*/
- function get_compound_property($property, $base = '', $namespace = '') {
+ function get_compound_property($property, $base = '', $namespace = '', $first = false) {
$x = $this->get_property_obj($property, $base, $namespace);
if($this->is_url($x)) {
$x = $this->fetch_property($x);
}
+ // verify and unpack JSalmon signature if present
+
+ if(is_array($x) && array_key_exists('signed',$x)) {
+ $ret = JSalmon::verify($x);
+ $tmp = JSalmon::unpack($x['data']);
+ if($ret && $ret['success']) {
+ if($ret['signer']) {
+ $saved = json_encode($x,JSON_UNESCAPED_SLASHES);
+ $x = $tmp;
+ $x['signer'] = $ret['signer'];
+ $x['signed_data'] = $saved;
+ if($ret['hubloc']) {
+ $x['hubloc'] = $ret['hubloc'];
+ }
+ }
+ }
+ }
+ if($first && is_array($x) && array_key_exists(0,$x)) {
+ return $x[0];
+ }
+
return $x;
}
@@ -273,4 +404,18 @@ class ActivityStreams {
return $x;
}
+
+ static function is_as_request() {
+
+ $x = getBestSupportedMimeType([
+ 'application/ld+json;profile="https://www.w3.org/ns/activitystreams"',
+ 'application/activity+json',
+ 'application/ld+json;profile="http://www.w3.org/ns/activitystreams"'
+ ]);
+
+ return(($x) ? true : false);
+
+ }
+
+
} \ No newline at end of file
diff --git a/Zotlabs/Lib/JSalmon.php b/Zotlabs/Lib/JSalmon.php
index 43d5f9d09..f35bf6235 100644
--- a/Zotlabs/Lib/JSalmon.php
+++ b/Zotlabs/Lib/JSalmon.php
@@ -2,15 +2,13 @@
namespace Zotlabs\Lib;
+use Zotlabs\Zot6\HTTPSig;
class JSalmon {
- static function sign($data,$key_id,$key) {
+ static function sign($data,$key_id,$key,$data_type = 'application/x-zot+json') {
- $arr = $data;
- $data = json_encode($data,JSON_UNESCAPED_SLASHES);
- $data = base64url_encode($data, false); // do not strip padding
- $data_type = 'application/x-zot+json';
+ $data = base64url_encode(json_encode($data,true),true); // strip padding
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
@@ -18,9 +16,9 @@ class JSalmon {
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
- $precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
+ $precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
- $signature = base64url_encode(rsa_sign($data . $precomputed, $key), false);
+ $signature = base64url_encode(rsa_sign($data . $precomputed, $key), true);
return ([
'signed' => true,
@@ -30,9 +28,45 @@ class JSalmon {
'alg' => $algorithm,
'sigs' => [
'value' => $signature,
- 'key_id' => base64url_encode($key_id)
+ 'key_id' => base64url_encode($key_id, true)
]
]);
}
+
+ static function verify($x) {
+
+ logger('verify');
+ $ret = [ 'results' => [] ];
+
+ if(! is_array($x)) {
+ return $false;
+ }
+ if(! ( array_key_exists('signed',$x) && $x['signed'])) {
+ return $false;
+ }
+
+ $signed_data = preg_replace('/\s+/','',$x['data']) . '.'
+ . base64url_encode($x['data_type'],true) . '.'
+ . base64url_encode($x['encoding'],true) . '.'
+ . base64url_encode($x['alg'],true);
+
+ $key = HTTPSig::get_key(EMPTY_STR,base64url_decode($x['sigs']['key_id']));
+ logger('key: ' . print_r($key,true));
+ if($key['portable_id'] && $key['public_key']) {
+ if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
+ logger('verified');
+ $ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ];
+ }
+ }
+
+ return $ret;
+
+ }
+
+ static function unpack($data) {
+ return json_decode(base64url_decode($data),true);
+ }
+
+
} \ No newline at end of file
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 3d18df051..23703a040 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -109,7 +109,7 @@ class Libzot {
$data = [
'type' => $type,
'encoding' => $encoding,
- 'sender' => $channel['channel_hash'],
+ 'sender' => $channel['channel_portable_id'],
'site_id' => self::make_xchan_hash(z_root(), get_config('system','pubkey')),
'version' => System::get_zot_revision(),
];
@@ -324,14 +324,19 @@ class Libzot {
logger('zot-info: ' . print_r($record,true), LOGGER_DATA, LOG_DEBUG);
$x = self::import_xchan($record['data'], (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
-logger('1');
+
if(! $x['success'])
return false;
-logger('2');
+
if($channel && $record['data']['permissions']) {
-logger('3');
- $old_read_stream_perm = their_perms_contains($channel['channel_id'],$x['hash'],'view_stream');
- set_abconfig($channel['channel_id'],$x['hash'],'system','their_perms',$record['data']['permissions']);
+ $permissions = explode(',',$record['data']['permissions']);
+ if($permissions && is_array($permissions)) {
+ $old_read_stream_perm = get_abconfig($channel['channel_id'],$x['hash'],'their_perms','view_stream');
+
+ foreach($permissions as $k => $v) {
+ set_abconfig($channel['channel_id'],$x['hash'],'their_perms',$k,$v);
+ }
+ }
if(array_key_exists('profile',$record['data']) && array_key_exists('next_birthday',$record['data']['profile'])) {
$next_birthday = datetime_convert('UTC','UTC',$record['data']['profile']['next_birthday']);
@@ -380,14 +385,16 @@ logger('4');
else {
$p = Permissions::connect_perms($channel['channel_id']);
- $my_perms = Permissions::serialise($p['perms']);
+ $my_perms = $p['perms'];
$automatic = $p['automatic'];
// new connection
if($my_perms) {
- set_abconfig($channel['channel_id'],$x['hash'],'system','my_perms',$my_perms);
+ foreach($my_perms as $k => $v) {
+ set_abconfig($channel['channel_id'],$x['hash'],'my_perms',$k,$v);
+ }
}
$closeness = get_pconfig($channel['channel_id'],'system','new_abook_closeness');
@@ -410,7 +417,7 @@ logger('4');
if($y) {
logger("New introduction received for {$channel['channel_name']}");
- $new_perms = get_all_perms($channel['channel_id'],$x['hash']);
+ $new_perms = get_all_perms($channel['channel_id'],$x['hash'],false);
// Send a clone sync packet and a permissions update if permissions have changed
@@ -426,7 +433,7 @@ logger('4');
[
'type' => NOTIFY_INTRO,
'from_xchan' => $x['hash'],
- 'to_xchan' => $channel['channel_hash'],
+ 'to_xchan' => $channel['channel_portable_id'],
'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']
]
);
@@ -777,7 +784,7 @@ logger('4');
// see if this is a channel clone that's hosted locally - which we treat different from other xchans/connections
- $local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1",
+ $local = q("select channel_account_id, channel_id from channel where channel_portable_id = '%s' limit 1",
dbesc($xchan_hash)
);
if($local) {
@@ -1130,7 +1137,7 @@ logger('4');
if($recip_arr) {
stringify_array_elms($recip_arr,true);
$recips = implode(',',$recip_arr);
- $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) and channel_removed = 0 ");
+ $r = q("select channel_portable_id as hash from channel where channel_portable_id in ( " . $recips . " ) and channel_removed = 0 ");
}
if(! $r) {
@@ -1304,12 +1311,12 @@ logger('4');
$r = [];
- $c = q("select channel_id, channel_hash from channel where channel_removed = 0");
+ $c = q("select channel_id, channel_portable_id from channel where channel_removed = 0");
if($c) {
foreach($c as $cc) {
if(perm_is_allowed($cc['channel_id'],$msg['sender'],$perm)) {
- $r[] = $cc['channel_hash'];
+ $r[] = $cc['channel_portable_id'];
}
}
}
@@ -1317,7 +1324,7 @@ logger('4');
if($include_sys) {
$sys = get_sys_channel();
if($sys)
- $r[] = $sys['channel_hash'];
+ $r[] = $sys['channel_portable_id'];
}
@@ -1333,7 +1340,7 @@ logger('4');
if($tag['type'] === 'Mention' && (strpos($tag['href'],z_root()) !== false)) {
$address = basename($tag['href']);
if($address) {
- $z = q("select channel_hash as hash from channel where channel_address = '%s'
+ $z = q("select channel_portable_id as hash from channel where channel_address = '%s'
and channel_removed = 0 limit 1",
dbesc($address)
);
@@ -1354,7 +1361,7 @@ logger('4');
$thread_parent = self::find_parent($msg,$act);
if($thread_parent) {
- $z = q("select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ",
+ $z = q("select channel_portable_id as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ",
dbesc($thread_parent),
dbesc($thread_parent)
);
@@ -1428,7 +1435,7 @@ logger('4');
* access checks.
*/
- if($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && $arr['mid'] === $arr['parent_mid']) {
+ if($sender === $channel['channel_portable_id'] && $arr['author_xchan'] === $channel['channel_portable_id'] && $arr['mid'] === $arr['parent_mid']) {
$DR->update('self delivery ignored');
$result[] = $DR->get();
continue;
@@ -1710,7 +1717,7 @@ logger('4');
$stored = (($item_result && $item_result['item']) ? $item_result['item'] : false);
if((is_array($stored)) && ($stored['id'] != $stored['parent'])
- && ($stored['author_xchan'] === $channel['channel_hash'])) {
+ && ($stored['author_xchan'] === $channel['channel_hash'] || $stored['author_xchan'] === $channel['channel_portable_id'])) {
retain_item($stored['item']['parent']);
}
@@ -1810,9 +1817,9 @@ logger('4');
}
logger('FOF Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG);
- logger('FOF Activity recipient: ' . $channel['channel_hash'], LOGGER_DATA, LOG_DEBUG);
+ logger('FOF Activity recipient: ' . $channel['channel_portable_id'], LOGGER_DATA, LOG_DEBUG);
- $result = self::process_delivery($arr['owner_xchan'],$arr, [ $channel['channel_hash'] ],false,false,true);
+ $result = self::process_delivery($arr['owner_xchan'],$arr, [ $channel['channel_portable_id'] ],false,false,true);
if ($result) {
$ret = array_merge($ret, $result);
}
@@ -2048,7 +2055,7 @@ logger('4');
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
- $r = q("select * from channel where channel_hash = '%s' limit 1",
+ $r = q("select * from channel where channel_portable_id = '%s' limit 1",
dbesc($d['hash'])
);
@@ -2203,7 +2210,7 @@ logger('4');
$loc = $locations[0];
- $r = q("select * from channel where channel_hash = '%s' limit 1",
+ $r = q("select * from channel where channel_portable_id = '%s' limit 1",
dbesc($sender_hash)
);
@@ -2211,7 +2218,7 @@ logger('4');
return;
if($loc['url'] !== z_root()) {
- $x = q("update channel set channel_moved = '%s' where channel_hash = '%s' limit 1",
+ $x = q("update channel set channel_moved = '%s' where channel_portable_id = '%s' limit 1",
dbesc($loc['url']),
dbesc($sender_hash)
);
@@ -2247,7 +2254,7 @@ logger('4');
static function encode_locations($channel) {
$ret = [];
- $x = self::get_hublocs($channel['channel_hash']);
+ $x = self::get_hublocs($channel['channel_portable_id']);
if($x && count($x)) {
foreach($x as $hub) {
@@ -2558,6 +2565,9 @@ logger('4');
static function zotinfo($arr) {
+ logger('arr: ' . print_r($arr,true));
+
+
$ret = [];
$zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : '');
@@ -2594,13 +2604,13 @@ logger('4');
$r = null;
if(strlen($zhash)) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
- where channel_hash = '%s' limit 1",
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
+ where channel_portable_id = '%s' limit 1",
dbesc($zhash)
);
}
elseif(strlen($zguid) && strlen($zguid_sig)) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($zguid),
dbesc($zguid_sig)
@@ -2608,7 +2618,7 @@ logger('4');
}
elseif(strlen($zaddr)) {
if(strpos($zaddr,'[system]') === false) { /* normal address lookup */
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1",
dbesc($zaddr),
dbesc($zaddr)
@@ -2628,10 +2638,10 @@ logger('4');
*
*/
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
where channel_system = 1 order by channel_id limit 1");
if(! $r) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
where channel_removed = 0 order by channel_id limit 1");
}
}
@@ -2775,7 +2785,7 @@ logger('4');
if(! $ret['follow_url'])
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
- $permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);
+ $permissions = get_all_perms($e['channel_id'],$ztarget_hash,false,false);
if($ztarget_hash) {
$permissions['connected'] = false;
diff --git a/Zotlabs/Lib/Zotfinger.php b/Zotlabs/Lib/Zotfinger.php
index 537e440d4..d094fdc8d 100644
--- a/Zotlabs/Lib/Zotfinger.php
+++ b/Zotlabs/Lib/Zotfinger.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Lib;
-use Zotlabs\Web\HTTPSig;
+use Zotlabs\Zot6\HTTPSig;
class Zotfinger {
@@ -12,10 +12,19 @@ class Zotfinger {
return false;
}
- if($channel) {
+ $m = parse_url($resource);
+
+ $data = json_encode([ 'zot_token' => random_string() ]);
+
+ if($channel && $m) {
+
$headers = [
- 'Accept' => 'application/x-zot+json',
- 'X-Zot-Token' => random_string(),
+ 'Accept' => 'application/x-zot+json',
+ 'Content-Type' => 'application/x-zot+json',
+ 'X-Zot-Token' => random_string(),
+ 'Digest' => HTTPSig::generate_digest_header($data),
+ 'Host' => $m['host'],
+ '(request-target)' => 'post ' . get_request_string($resource)
];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
}
@@ -27,7 +36,9 @@ class Zotfinger {
$redirects = 0;
- $x = z_fetch_url($resource,false,$redirects, [ 'headers' => $h ] );
+ $x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] );
+
+ logger('fetch: ' . print_r($x,true));
if($x['success']) {
@@ -39,6 +50,8 @@ class Zotfinger {
$result['data'] = json_decode(crypto_unencapsulate($result['data'],get_config('system','prvkey')),true);
}
+ logger('decrypted: ' . print_r($result,true));
+
return $result;
}