Merge branch 'dev' of /home/macgirvin/roadhouse into dev

This commit is contained in:
nobody 2021-02-21 15:43:43 -08:00
commit 385a6742ed
17 changed files with 355 additions and 274 deletions

View file

@ -29,14 +29,14 @@ class Content_importer {
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
if(! $x['success']) {
logger('no API response',LOGGER_DEBUG);

View file

@ -28,13 +28,13 @@ class File_importer {
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/file/export?f=&file_id=' . $attach_id,
'X-API-Request' => $hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id,
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/file/export?f=&file_id=' . $attach_id,
'(request-target)' => 'get /api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id,
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),true,'sha512');
$x = z_fetch_url($hz_server . '/api/z/1.0/file/export?f=&file_id=' . $attach_id,false,$redirects,[ 'headers' => $headers ]);
$x = z_fetch_url($hz_server . '/api/z/1.0/file/export?f=&zap_compat=1&file_id=' . $attach_id,false,$redirects,[ 'headers' => $headers ]);
if(! $x['success']) {
logger('no API response',LOGGER_DEBUG);

View file

@ -93,7 +93,7 @@ class Activity {
}
$headers = [
'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'Accept' => 'application/activity+json, application/x-zot-activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'Host' => $m['host'],
'Date' => datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'),
'(request-target)' => 'get ' . get_request_string($url)
@ -1281,6 +1281,9 @@ class Activity {
'width' => 300,
];
$ret['url'] = $p['xchan_url'];
if ($p['channel_location']) {
$ret['location'] = [ 'type' => 'Place', 'name' => $p['channel_location'] ];
}
if ($activitypub && get_config('system','activitypub', ACTIVITYPUB_ENABLED)) {
@ -2428,6 +2431,20 @@ class Activity {
$s['app'] = escape_tags($generator['name']);
}
$location = $act->get_property_obj('location');
if (is_array($location) && array_key_exists('type',$location) && $location['type'] === 'Place') {
if (array_key_exists('name',$location)) {
$s['location'] = escape_tags($location['name']);
}
if (array_key_exists('content',$location)) {
$s['location'] = html2plain(html2plain(purify_html($location['content']),256));
}
if (array_key_exists('latitude',$location) && array_key_exists('longitude',$location)) {
$s['coord'] = escape_tags($location['latitude']) . ' ' . escape_tags($location['longitude']);
}
}
if (! $response_activity) {
$a = self::decode_taxonomy($act->obj);
if ($a) {

View file

@ -463,7 +463,8 @@ class ActivityStreams {
$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"'
'application/ld+json;profile="http://www.w3.org/ns/activitystreams"',
'application/x-zot-activity+json'
]);
return(($x) ? true : false);

View file

@ -79,7 +79,7 @@ class MastAPI {
$ret = [];
$ret['uri'] = App::get_hostname();
$ret['uri'] = z_root();
$ret['title'] = System::get_site_name();
$ret['description'] = bbcode(get_config('system','siteinfo'), [ 'export' => true ] );
$ret['email'] = get_config('system','admin_email');

View file

@ -14,6 +14,93 @@ class Activity extends Controller {
function init() {
if (ActivityStreams::is_as_request()) {
$item_id = argv(1);
if (! $item_id) {
return;
}
$ob_authorise = false;
$item_uid = 0;
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
$t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'",
dbesc($item_id)
);
if ($t) {
foreach ($t as $token) {
if ($token['v'] === $bear) {
$ob_authorize = true;
$item_uid = $token['uid'];
break;
}
}
}
}
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
and item.item_delayed = 0 and item.item_blocked = 0 ";
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
// Give ocap tokens priority
if ($ob_authorize) {
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
}
else {
$sql_extra = item_permissions_sql(0);
}
$r = q("select * from item where uuid = '%s' $item_normal $sql_extra limit 1",
dbesc($item_id)
);
if (! $r) {
$r = q("select * from item where uuid = '%s' $item_normal limit 1",
dbesc($item_id)
);
if($r) {
http_status_exit(403, 'Forbidden');
}
http_status_exit(404, 'Not found');
}
xchan_query($r,true);
$items = fetch_post_tags($r,false);
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id);
}
}
$channel = channelx_by_n($items[0]['uid']);
as_return_and_die(ZlibActivity::encode_activity($items[0],true),$channel);
}
if (Libzot::is_zot_request()) {
$item_id = argv(1);
@ -171,92 +258,8 @@ class Activity extends Controller {
killme();
}
if (ActivityStreams::is_as_request()) {
$item_id = argv(1);
if (! $item_id) {
return;
}
$ob_authorise = false;
$item_uid = 0;
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
$t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'",
dbesc($item_id)
);
if ($t) {
foreach ($t as $token) {
if ($token['v'] === $bear) {
$ob_authorize = true;
$item_uid = $token['uid'];
break;
}
}
}
}
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
and item.item_delayed = 0 and item.item_blocked = 0 ";
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
// Give ocap tokens priority
if ($ob_authorize) {
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
}
else {
$sql_extra = item_permissions_sql(0);
}
$r = q("select * from item where uuid = '%s' $item_normal $sql_extra limit 1",
dbesc($item_id)
);
if (! $r) {
$r = q("select * from item where uuid = '%s' $item_normal limit 1",
dbesc($item_id)
);
if($r) {
http_status_exit(403, 'Forbidden');
}
http_status_exit(404, 'Not found');
}
xchan_query($r,true);
$items = fetch_post_tags($r,false);
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id);
}
}
$channel = channelx_by_n($items[0]['uid']);
as_return_and_die(ZlibActivity::encode_activity($items[0],true),$channel);
}
goaway(z_root() . '/item/' . argv(1));
}

View file

@ -75,36 +75,6 @@ class Channel extends Controller {
]);
// handle zot6 channel discovery
if(Libzot::is_zot_request()) {
$sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6');
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer'] ]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($sigdata['signer'])
);
if($s && $s[0]['hubloc_sitekey'] && $s[0]['site_crypto']) {
$data = json_encode(Crypto::encapsulate($data,$s[0]['hubloc_sitekey'],Libzot::best_algorithm($s[0]['site_crypto'])));
}
}
else {
$data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'] ]));
}
$headers = [
'Content-Type' => 'application/x-zot+json',
'Digest' => HTTPSig::generate_digest_header($data),
'(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']
];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
HTTPSig::set_headers($h);
echo $data;
killme();
}
// An ActivityStreams actor record is more or less required for ActivityStreams compliance
// unless the actor object is inlined into every activity/object. This implies that it
@ -151,6 +121,38 @@ class Channel extends Controller {
as_return_and_die(Activity::encode_person($channel,true,true),$channel);
}
// handle zot6 channel discovery
if(Libzot::is_zot_request()) {
$sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6');
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer'] ]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($sigdata['signer'])
);
if($s && $s[0]['hubloc_sitekey'] && $s[0]['site_crypto']) {
$data = json_encode(Crypto::encapsulate($data,$s[0]['hubloc_sitekey'],Libzot::best_algorithm($s[0]['site_crypto'])));
}
}
else {
$data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'] ]));
}
$headers = [
'Content-Type' => 'application/x-zot+json',
'Digest' => HTTPSig::generate_digest_header($data),
'(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']
];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
HTTPSig::set_headers($h);
echo $data;
killme();
}
// Run Libprofile::load() here to make sure the theme is set before
// we start loading content

View file

@ -89,7 +89,7 @@ class Import extends Controller {
return;
}
$api_path .= 'channel/export/basic?f=&channel=' . $channelname;
$api_path .= 'channel/export/basic?f=&zap_compat=1&channel=' . $channelname;
if ($import_posts) {
$api_path .= '&posts=1';
}
@ -498,27 +498,27 @@ class Import extends Controller {
if (is_array($data['chatroom'])) {
import_chatrooms($channel,$data['chatroom']);
}
if (is_array($data['conv'])) {
import_conv($channel,$data['conv']);
}
if (is_array($data['mail'])) {
import_mail($channel,$data['mail']);
}
// if (is_array($data['conv'])) {
// import_conv($channel,$data['conv']);
// }
// if (is_array($data['mail'])) {
// import_mail($channel,$data['mail']);
// }
if (is_array($data['event'])) {
import_events($channel,$data['event']);
}
if (is_array($data['event_item'])) {
import_items($channel,$data['event_item'],false,$relocate);
}
if (is_array($data['menu'])) {
import_menus($channel,$data['menu']);
}
if (is_array($data['wiki'])) {
import_items($channel,$data['wiki'],false,$relocate);
}
if (is_array($data['webpages'])) {
import_items($channel,$data['webpages'],false,$relocate);
}
// if (is_array($data['menu'])) {
// import_menus($channel,$data['menu']);
// }
// if (is_array($data['wiki'])) {
// import_items($channel,$data['wiki'],false,$relocate);
// }
// if (is_array($data['webpages'])) {
// import_items($channel,$data['webpages'],false,$relocate);
// }
$addon = array('channel' => $channel,'data' => $data);
call_hooks('import_channel',$addon);
@ -542,14 +542,14 @@ class Import extends Controller {
while (1) {
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
// logger('z_fetch: ' . print_r($x,true));
@ -577,14 +577,14 @@ class Import extends Controller {
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/files?f=&since=' . urlencode($since) . '&until=' . urlencode($until),
'X-API-Request' => $hz_server . '/api/z/1.0/files?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until),
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/files?f=&since=' . urlencode($since) . '&until=' . urlencode($until),
'(request-target)' => 'get /api/z/1.0/files?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until),
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
$x = z_fetch_url($hz_server . '/api/z/1.0/files?f=&since=' . urlencode($since) . '&until=' . urlencode($until),false,$redirects,[ 'headers' => $headers ]);
$x = z_fetch_url($hz_server . '/api/z/1.0/files?f=&zap_compat=1&since=' . urlencode($since) . '&until=' . urlencode($until),false,$redirects,[ 'headers' => $headers ]);
if (! $x['success']) {
logger('no API response');

View file

@ -58,7 +58,7 @@ class Import_items extends \Zotlabs\Web\Controller {
$servername = substr($old_address,strpos($old_address,'@')+1);
$scheme = 'https://';
$api_path = '/api/red/channel/export/items?f=&channel=' . $channelname . '&year=' . intval($year);
$api_path = '/api/red/channel/export/items?f=&zap_compat=1&channel=' . $channelname . '&year=' . intval($year);
$binary = false;
$redirects = 0;
$opts = array('http_auth' => $email . ':' . $password);
@ -86,13 +86,20 @@ class Import_items extends \Zotlabs\Web\Controller {
if(! is_array($data))
return;
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
$v1 = substr($data['compatibility']['database'],-4);
$v2 = substr(DB_UPDATE_VERSION,-4);
if($v2 > $v1) {
$t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 );
notice($t . EOL);
}
// if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
// $v1 = substr($data['compatibility']['database'],-4);
// $v2 = substr(DB_UPDATE_VERSION,-4);
// if($v2 > $v1) {
// $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 );
// notice($t . EOL);
// }
// }
$codebase = 'zap';
if ((! array_path_exists('compatibility/codebase',$data)) || $data['compatibility']['codebase'] !== $codebase) {
notice(t('Data export format is not compatible with this software'));
return;
}
$channel = \App::get_channel();

View file

@ -50,6 +50,101 @@ class Item extends Controller {
function init() {
if(ActivityStreams::is_as_request()) {
$item_id = argv(1);
if(! $item_id)
http_status_exit(404, 'Not found');
$portable_id = EMPTY_STR;
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
$i = null;
// do we have the item (at all)?
// add preferential bias to item owners (item_wall = 1)
$r = q("select * from item where mid = '%s' or uuid = '%s' $item_normal order by item_wall desc limit 1",
dbesc(z_root() . '/item/' . $item_id),
dbesc($item_id)
);
if (! $r) {
http_status_exit(404,'Not found');
}
// process an authenticated fetch
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ",
dbesc($r[0]['parent_mid']),
dbesc($portable_id)
);
}
elseif (Config::get('system','require_authenticated_fetch',false)) {
http_status_exit(403,'Permission denied');
}
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
// with a bias towards those items owned by channels on this site (item_wall = 1)
$sql_extra = item_permissions_sql(0);
if (! $i) {
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1",
dbesc($r[0]['parent_mid'])
);
}
if(! $i) {
http_status_exit(403,'Forbidden');
}
// If we get to this point we have determined we can access the original in $r (fetched much further above), so use it.
xchan_query($r,true);
$items = fetch_post_tags($r,false);
$chan = channelx_by_n($items[0]['uid']);
if (! $chan) {
http_status_exit(404, 'Not found');
}
if (! perm_is_allowed($chan['channel_id'],get_observer_hash(),'view_stream')) {
http_status_exit(403, 'Forbidden');
}
$i = Activity::encode_item($items[0],true);
if (! $i) {
http_status_exit(404, 'Not found');
}
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id);
}
}
as_return_and_die($i,$chan);
}
if(Libzot::is_zot_request()) {
$conversation = false;
@ -166,102 +261,6 @@ class Item extends Controller {
}
if(ActivityStreams::is_as_request()) {
$item_id = argv(1);
if(! $item_id)
http_status_exit(404, 'Not found');
$portable_id = EMPTY_STR;
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
$i = null;
// do we have the item (at all)?
// add preferential bias to item owners (item_wall = 1)
$r = q("select * from item where mid = '%s' or uuid = '%s' $item_normal order by item_wall desc limit 1",
dbesc(z_root() . '/item/' . $item_id),
dbesc($item_id)
);
if (! $r) {
http_status_exit(404,'Not found');
}
// process an authenticated fetch
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ",
dbesc($r[0]['parent_mid']),
dbesc($portable_id)
);
}
elseif (Config::get('system','require_authenticated_fetch',false)) {
http_status_exit(403,'Permission denied');
}
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
// with a bias towards those items owned by channels on this site (item_wall = 1)
$sql_extra = item_permissions_sql(0);
if (! $i) {
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1",
dbesc($r[0]['parent_mid'])
);
}
if(! $i) {
http_status_exit(403,'Forbidden');
}
// If we get to this point we have determined we can access the original in $r (fetched much further above), so use it.
xchan_query($r,true);
$items = fetch_post_tags($r,false);
$chan = channelx_by_n($items[0]['uid']);
if (! $chan) {
http_status_exit(404, 'Not found');
}
if (! perm_is_allowed($chan['channel_id'],get_observer_hash(),'view_stream')) {
http_status_exit(403, 'Forbidden');
}
$i = Activity::encode_item($items[0],true);
if (! $i) {
http_status_exit(404, 'Not found');
}
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id);
}
}
as_return_and_die($i,$chan);
}
// if it isn't a drop command and isn't a post method and wasn't handled already,
// the default action is a browser request for a persistent uri and this should return
// the text/html page of the item.

View file

@ -154,7 +154,7 @@ class Display {
}
$preload_images = get_pconfig(local_channel(),'system','preload_images', '1');
$preload_images = get_pconfig(local_channel(),'system','preload_images');
$user_scalable = get_pconfig(local_channel(),'system','user_scalable', '0');

View file

@ -16,7 +16,7 @@ use Zotlabs\Daemon\Run;
* @brief This file defines some global constants and includes the central App class.
*/
define ( 'STD_VERSION', '21.02.15' );
define ( 'STD_VERSION', '21.02.22' );
define ( 'ZOT_REVISION', '6.0' );
define ( 'DB_UPDATE_VERSION', 1247 );
@ -692,8 +692,8 @@ function startup() {
@set_time_limit(0);
if (function_exists ('ini_set')) {
// This has to be quite large to deal with embedded private photos
@ini_set('pcre.backtrack_limit', 500000);
// This has to be quite large
@ini_set('pcre.backtrack_limit', 5000000);
// Use cookies to store the session ID on the client side
@ini_set('session.use_only_cookies', 1);

View file

@ -269,6 +269,9 @@ function bb_parse_crypt($match) {
if ($matches[1] != "")
$hint = $matches[1];
preg_match("/hint=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
if ($matches[1] != "")
$hint = $matches[1];
preg_match("/hint=\\\"(.*?)\\\"/ism", $attributes, $matches);
if ($matches[1] != "")
$hint = $matches[1];
@ -284,6 +287,25 @@ function bb_parse_crypt($match) {
return $Text;
}
/**
* @brief Returns raw base64 encoded crypt content.
*
* @param array $match
* @return string
*/
function bb_parse_b64_crypt($match) {
if(empty($match[2]))
return;
$r .= '----- ENCRYPTED CONTENT -----' . PHP_EOL;
$r .= $match[2] . PHP_EOL;
$r .= '----- END ENCRYPTED CONTENT -----';
return $r;
}
function bb_parse_app($match) {
$app = Apps::app_decode($match[1]);
@ -1534,8 +1556,10 @@ function bbcode($Text, $options = []) {
$Text = preg_replace("/([^\]\='".'"'."\;\/])(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $Text);
}
if (strpos($Text,'[/share]') !== false) {
$count = 0;
while (strpos($Text,'[/share]') !== false && $count < 10) {
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text);
$count ++;
}
if (strpos($Text,'[/url]') !== false) {
@ -1848,7 +1872,10 @@ function bbcode($Text, $options = []) {
// crypt
if (strpos($Text,'[/crypt]') !== false) {
if (! $activitypub) {
if ($activitypub) {
$Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_b64_crypt', $Text);
}
else {
$Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text);
}
}

View file

@ -1124,6 +1124,8 @@ function channel_export_items_date($channel_id, $start, $finish) {
$ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()];
}
$ret['compatibility']['codebase'] = 'zap';
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type = '' order by created",
intval(ITEM_TYPE_POST),
intval($channel_id),
@ -1190,6 +1192,9 @@ function channel_export_items_page($channel_id, $start, $finish, $page = 0, $lim
$ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()];
}
$ret['compatibility']['codebase'] = 'zap';
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and resource_type = '' and created >= '%s' and created <= '%s' order by created limit %d offset %d",
intval(ITEM_TYPE_POST),
intval($channel_id),

View file

@ -233,6 +233,8 @@ function abook_toggle_flag($abook,$flag) {
function mark_orphan_hubsxchans() {
return;
$dirmode = intval(get_config('system','directory_mode'));
if ($dirmode == DIRECTORY_MODE_NORMAL) {
return;

View file

@ -169,6 +169,23 @@ function import_config($channel, $configs) {
}
load_pconfig($channel['channel_id']);
$permissions_role = get_pconfig($channel['channel_id'],'system','permissions_role');
if ($permissions_role === 'social_federation') {
// Convert Hubzilla's social_federation role to 'social' with relaxed comment permissions
set_pconfig($channel['channel_id'],'systems','permissions_role','social');
PermissionLimits::Set($channel['channel_id'],'post_comments', PERMS_AUTHED);
}
else {
// If the requested permissions_role doesn't exist on this system,
// convert it to 'social'
$role_permissions = PermissionRoles::role_perms($permissions_role);
if (! $role_permissions) {
set_pconfig($channel['channel_id'],'system','permissions_role','social');
}
}
}
}
@ -1440,8 +1457,14 @@ function sync_files($channel, $files) {
continue;
}
$columns = db_columns('attach');
$str = '';
foreach ($att as $k => $v) {
if (! in_array($k,$columns)) {
continue;
}
if ($str) {
$str .= ",";
}

View file

@ -2985,27 +2985,22 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
$arr['item_wall'] = 1;
$arr['item_thread_top'] = 1;
if (strpos($item['body'], "[/share]") !== false) {
$pos = strpos($item['body'], "[share");
$bb = substr($item['body'], $pos);
}
else {
$bb = "[share author='" . urlencode($item['author']['xchan_name']).
"' profile='" . $item['author']['xchan_url'] .
"' portable_id='" . $item['author']['xchan_hash'] .
"' avatar='" . $item['author']['xchan_photo_s'] .
"' link='" . $item['plink'] .
"' auth='" . (($item['author']['network'] === 'zot6') ? 'true' : 'false') .
"' posted='" . $item['created'] .
"' message_id='" . $item['mid'] .
"']";
if($item['title'])
$bb .= '[b]'.$item['title'].'[/b]'."\r\n";
$bb .= $item['body'];
$bb .= "[/share]";
$bb = "[share author='" . urlencode($item['author']['xchan_name']).
"' profile='" . $item['author']['xchan_url'] .
"' portable_id='" . $item['author']['xchan_hash'] .
"' avatar='" . $item['author']['xchan_photo_s'] .
"' link='" . $item['plink'] .
"' auth='" . (($item['author']['network'] === 'zot6') ? 'true' : 'false') .
"' posted='" . $item['created'] .
"' message_id='" . $item['mid'] .
"']";
if($item['title']) {
$bb .= '[b]' . $item['title'] . '[/b]' . "\r\n";
$arr['title'] = $item['title'];
}
$bb .= $item['body'];
$bb .= "[/share]";
// $mention = '@[zrl=' . $item['author']['xchan_url'] . ']' . $item['author']['xchan_name'] . '[/zrl]';
$arr['body'] = $bb;
$arr['term'] = $item['term'];