diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index abbef6540..573e929bf 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -193,7 +193,7 @@ class Cron { $restart = true; $generation = intval($argv[2]); if(! $generation) - killme(); + return; } reload_plugins(); diff --git a/Zotlabs/Daemon/CurlAuth.php b/Zotlabs/Daemon/CurlAuth.php index be12bc779..de41382e3 100644 --- a/Zotlabs/Daemon/CurlAuth.php +++ b/Zotlabs/Daemon/CurlAuth.php @@ -13,7 +13,7 @@ class CurlAuth { static public function run($argc,$argv) { if($argc != 2) - killme(); + return; \App::$session->start(); @@ -50,6 +50,6 @@ class CurlAuth { file_put_contents($c,$x); - killme(); + return; } -} \ No newline at end of file +} diff --git a/Zotlabs/Daemon/Delxitems.php b/Zotlabs/Daemon/Delxitems.php index be49f5784..db4dd392d 100644 --- a/Zotlabs/Daemon/Delxitems.php +++ b/Zotlabs/Daemon/Delxitems.php @@ -13,11 +13,11 @@ class Delxitems { cli_startup(); if($argc != 3) { - killme(); + return; } remove_abook_items($argv[1],$argv[2]); - killme(); + return; } } diff --git a/Zotlabs/Daemon/Master.php b/Zotlabs/Daemon/Master.php index 580df97db..7114c7273 100644 --- a/Zotlabs/Daemon/Master.php +++ b/Zotlabs/Daemon/Master.php @@ -10,7 +10,7 @@ if(array_search( __file__ , get_included_files()) === 0) { if($argc) Master::Release($argc,$argv); - killme(); + return; } diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index abb86e6b8..b3bdf2c47 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -99,68 +99,6 @@ class Onepoll { if(! $responded) return; - if($contact['xchan_connurl']) { - $fetch_feed = true; - $x = null; - - // They haven't given us permission to see their stream - - $can_view_stream = their_perms_contains($importer_uid,$contact['abook_xchan'],'view_stream'); - - if(! $can_view_stream) - $fetch_feed = false; - - // we haven't given them permission to send us their stream - - $can_send_stream = ((strpos(get_abconfig($importer_uid,$contact['abook_xchan'],'system','my_perms',EMPTY_STR),'send_stream') !== false) ? true : false); - - if(! $can_send_stream) - $fetch_feed = false; - - if($fetch_feed) { - - if(strpos($contact['xchan_connurl'],z_root()) === 0) { - // local channel - save a network fetch - $c = channelx_by_hash($contact['xchan_hash']); - if($c) { - $x = [ - 'success' => true, - 'body' => json_encode( [ - 'success' => true, - 'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], [ 'mindate' => $last_update ]) - ]) - ]; - } - } - else { - // remote fetch - - $feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']); - $feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . \App::get_hostname(); - $recurse = 0; - $x = z_fetch_url($feedurl, false, $recurse, [ 'session' => true ]); - } - - logger('feed_update: ' . print_r($x,true), LOGGER_DATA); - } - - if(($x) && ($x['success'])) { - $total = 0; - logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl); - - $j = json_decode($x['body'],true); - if($j['success'] && $j['messages']) { - foreach($j['messages'] as $message) { - $results = Libzot::process_delivery($contact['xchan_hash'], null, get_item_elements($message), [ $importer['xchan_hash'] ], false); - logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA); - $total ++; - } - logger("onepoll: $total messages processed"); - } - } - } - - // update the poco details for this connection if($contact['xchan_connurl']) { diff --git a/Zotlabs/Daemon/Poller.php b/Zotlabs/Daemon/Poller.php index 9270874c9..4e60d75a5 100644 --- a/Zotlabs/Daemon/Poller.php +++ b/Zotlabs/Daemon/Poller.php @@ -47,7 +47,7 @@ class Poller { $restart = true; $generation = intval($argv[2]); if(! $generation) - killme(); + return; } if(($argc > 1) && intval($argv[1])) { diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index c1dff1644..3b83699af 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -54,12 +54,31 @@ class Activity { } else { $m = parse_url($url); + + // handle bearcaps + if ($m['scheme'] === 'bear' && $m['query']) { + $params = explode('&',$m['query']); + if ($params) { + foreach ($params as $p) { + if (substr($p,0,2) === 'u=') { + $url = substr($p,2); + } + if (substr($p,0,2) === 't=') { + $token = substr($p,2); + } + } + } + } + $headers = [ 'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"', 'Host' => $m['host'], '(request-target)' => 'get ' . get_request_string($url), 'Date' => datetime_convert('UTC','UTC','now','D, d M Y H:i:s') . ' UTC' ]; + if (isset($token)) { + $headers['Authorization'] = 'Bearer ' . $token; + } $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false); $x = z_fetch_url($url, true, $redirects, [ 'headers' => $h ] ); } @@ -892,7 +911,12 @@ class Activity { } } - $ret['id'] = ((strpos($p['xchan_hash'],'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); + if ($c) { + $ret['id'] = channel_url($c); + } + else { + $ret['id'] = ((strpos($p['xchan_hash'],'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); + } if ($p['xchan_addr'] && strpos($p['xchan_addr'],'@')) $ret['preferredUsername'] = substr($p['xchan_addr'],0,strpos($p['xchan_addr'],'@')); $ret['name'] = $p['xchan_name']; @@ -905,19 +929,7 @@ class Activity { 'height' => 300, 'width' => 300, ]; - $ret['url'] = [ - [ - 'type' => 'Link', - 'mediaType' => 'text/html', - 'href' => $p['xchan_url'] - ], - [ - 'type' => 'Link', - 'mediaType' => 'text/x-zot+json', - 'href' => $p['xchan_url'] - ] - ]; - + $ret['url'] = $p['xchan_url']; if ($activitypub) { @@ -970,7 +982,7 @@ class Activity { $ret['outbox'] = z_root() . '/nullbox'; } $ret['publicKey'] = [ - 'id' => $p['xchan_url'] . '/public_key_pem', + 'id' => $p['xchan_url'], 'owner' => $p['xchan_url'], 'publicKeyPem' => $p['xchan_pubkey'] ]; diff --git a/Zotlabs/Lib/Libprofile.php b/Zotlabs/Lib/Libprofile.php index dcae3b228..73ea5cabc 100644 --- a/Zotlabs/Lib/Libprofile.php +++ b/Zotlabs/Lib/Libprofile.php @@ -61,11 +61,19 @@ class Libprofile { if ($profile) { $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile - LEFT JOIN channel ON profile.uid = channel.channel_id - WHERE channel.channel_address = '%s' AND profile.profile_guid = '%s' LIMIT 1", - dbesc($nickname), - dbesc($profile) + LEFT JOIN channel ON profile.uid = channel.channel_id + WHERE channel.channel_address = '%s' AND profile.profile_guid = '%s' LIMIT 1", + dbesc($nickname), + dbesc($profile) ); + if (! $p) { + $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + LEFT JOIN channel ON profile.uid = channel.channel_id + WHERE channel.channel_address = '%s' AND profile.id = %d LIMIT 1", + dbesc($nickname), + intval($profile) + ); + } } if (! $p) { diff --git a/Zotlabs/Lib/Libzotdir.php b/Zotlabs/Lib/Libzotdir.php index 974680357..fffbecb19 100644 --- a/Zotlabs/Lib/Libzotdir.php +++ b/Zotlabs/Lib/Libzotdir.php @@ -108,7 +108,7 @@ class Libzotdir { if($ret === false) { $ret = get_config('directory', $setting); if($ret === false) { - $default = (in_array($setting,['globaldir','safemode']) ? 1 : 0); + $ret = (in_array($setting,['globaldir','safemode']) ? 1 : 0); } } diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 65b58465f..5b9177924 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -96,6 +96,8 @@ class Dav extends Controller { $auth = new \Zotlabs\Storage\BasicAuth(); + $auth->observer = get_observer_hash(); + $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . ' ' . 'WebDAV'); $rootDirectory = new \Zotlabs\Storage\Directory('/', $auth); diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 51854edbd..e800aec5c 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -5,6 +5,7 @@ use App; use Zotlabs\Web\Controller; use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Libprofile; +use Zotlabs\Daemon\Master; use Sabre\VObject\Reader; @@ -77,7 +78,7 @@ class Profiles extends Controller { [ 'aid' => intval(get_account_id()), 'uid' => intval(local_channel()), - 'profile_guid' => random_string(), + 'profile_guid' => new_uuid(), 'profile_name' => $name, 'fullname' => $r1[0]['fullname'], 'photo' => $r1[0]['photo'], @@ -108,18 +109,18 @@ class Profiles extends Controller { $name = t('Profile-') . ($num_profiles + 1); $r1 = q("SELECT * FROM profile WHERE uid = %d AND id = %d LIMIT 1", intval(local_channel()), - intval(\App::$argv[2]) + intval(argv(2)) ); if(! count($r1)) { notice( t('Profile unavailable to clone.') . EOL); - \App::$error = 404; + App::$error = 404; return; } unset($r1[0]['id']); $r1[0]['is_default'] = 0; $r1[0]['publish'] = 0; - $r1[0]['profile_name'] = dbesc($name); - $r1[0]['profile_guid'] = dbesc(random_string()); + $r1[0]['profile_name'] = $name; + $r1[0]['profile_guid'] = new_uuid(); create_table_from_array('profile', $r1[0]); @@ -163,12 +164,7 @@ class Profiles extends Controller { echo json_encode($r1[0]); killme(); } - - - - - // Run Libprofile::load() here to make sure the theme is set before - // we start loading content + if(((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(),'multi_profiles')) { if(feature_enabled(local_channel(),'multi_profiles')) $id = argv(1); @@ -191,7 +187,7 @@ class Profiles extends Controller { $chan = App::get_channel(); - Libprofile::load($chan['channel_address'],$r[0]['id']); + Libprofile::load($chan['channel_address'],$r[0]['profile_guid']); } } @@ -323,7 +319,7 @@ class Profiles extends Controller { $orig_vcard = null; - $channel = \App::get_channel(); + $channel = App::get_channel(); $default_vcard_cat = ((defined('DEFAULT_VCARD_CAT')) ? DEFAULT_VCARD_CAT : 'HOME'); @@ -594,15 +590,15 @@ class Profiles extends Controller { if($r) info( t('Profile updated.') . EOL); - $r = q("select * from profile where id = %d and uid = %d limit 1", + $sync = q("select * from profile where id = %d and uid = %d limit 1", intval(argv(1)), intval(local_channel()) ); - if($r) { - Libsync::build_sync_packet(local_channel(),array('profile' => $r)); + if($sync) { + Libsync::build_sync_packet(local_channel(),array('profile' => $sync)); } - $channel = \App::get_channel(); + $channel = App::get_channel(); if($namechanged && $is_default) { $r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'", @@ -617,9 +613,8 @@ class Profiles extends Controller { } if($is_default) { - // reload the info for the sidebar widget - why does this not work? - Libprofile::load($channel['channel_address']); - \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); + Master::Summon(array('Directory',local_channel())); + goaway(z_root() . '/profiles/' . $sync[0]['id']); } } } diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 1f0bf994f..b26148e3e 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -41,6 +41,7 @@ class Zotfeed extends \Zotlabs\Web\Controller { logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG); + $result['project'] = 'Zap'; $result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate)); $result['success'] = true; json_return_and_die($result); diff --git a/Zotlabs/Storage/BasicAuth.php b/Zotlabs/Storage/BasicAuth.php index a5c01fbb7..851d022d4 100644 --- a/Zotlabs/Storage/BasicAuth.php +++ b/Zotlabs/Storage/BasicAuth.php @@ -164,10 +164,13 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic { */ function check(RequestInterface $request, ResponseInterface $response) { - if(local_channel()) { + if (local_channel()) { $this->setAuthenticated(\App::get_channel()); return [ true, $this->principalPrefix . $this->channel_name ]; } + elseif (remote_channel()) { + return [ true, $this->principalPrefix . $this->observer ]; + } $auth = new \Sabre\HTTP\Auth\Basic( $this->realm, diff --git a/boot.php b/boot.php index 8c3f628a6..cc150bc70 100755 --- a/boot.php +++ b/boot.php @@ -22,6 +22,9 @@ require_once('vendor/autoload.php'); if (file_exists('addon/vendor/autoload.php')) { require_once('addon/vendor/autoload.php'); } +if (file_exists('addon/version.php')) { + require_once('addon/version.php'); +} require_once('include/config.php'); require_once('include/network.php'); @@ -45,7 +48,7 @@ require_once('include/items.php'); -define ( 'STD_VERSION', '19.8.14' ); +define ( 'STD_VERSION', '19.8.26' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1234 ); diff --git a/include/channel.php b/include/channel.php index f13859b24..1d55d7554 100644 --- a/include/channel.php +++ b/include/channel.php @@ -395,7 +395,7 @@ function create_identity($arr) { ); if($role_permissions) { - $myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : array()); + $myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : [] ); } else { $x = PermissionRoles::role_perms('social'); diff --git a/include/import.php b/include/import.php index edd35d1aa..d8f4415a2 100644 --- a/include/import.php +++ b/include/import.php @@ -1309,9 +1309,9 @@ function sync_files($channel, $files) { logger('sync_files duplicate check: attach_by_hash() returned ' . print_r($x,true), LOGGER_DEBUG); if ($x['success']) { - $orig_attach = $x[0]; + $orig_attach = $x['data']; $attach_exists = true; - $attach_id = $x[0]['id']; + $attach_id = $orig_attach['id']; } $newfname = 'store/' . $channel['channel_address'] . '/' . get_attach_binname($att['content']); diff --git a/include/network.php b/include/network.php index cc99ff4ca..b6fc32f7d 100644 --- a/include/network.php +++ b/include/network.php @@ -1684,6 +1684,7 @@ function get_site_info() { 'site_name' => (($site_name) ? $site_name : ''), 'version' => $version, 'version_tag' => $tag, + 'addon_version' => defined('ADDON_VERSION') ? ADDON_VERSION : 'unknown', 'server_role' => System::get_server_role(), 'commit' => $commit, 'plugins' => $visible_plugins, diff --git a/include/text.php b/include/text.php index ef32a9bc9..f23c82082 100644 --- a/include/text.php +++ b/include/text.php @@ -964,7 +964,11 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) { * @return string */ function linkify($s, $me = false) { - $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/u", (($me) ? ' $1' : ' $1'), $s); + $rel = 'nofollow noopener'; + if ($me) { + $rel .= ' me'; + } + $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\@\~\#\'\%\$\!\+\,\@]*)/u", '$1', $s); $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$s); return($s); @@ -1505,21 +1509,35 @@ function prepare_body(&$item,$attach = false,$opts = false) { $is_photo = ((($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) ? true : false); - if($is_photo && ! $censored) { + if ($is_photo && ! $censored) { $object = json_decode($item['obj'],true); + $ptr = null; + + if (array_key_exists('url',$object) && is_array($object['url'])) { + if (array_key_exists(0,$object['url'])) { + foreach ($object['url'] as $link) { + if(array_key_exists('width',$link) && $link['width'] >= 640 && $link['width'] <= 1024) { + $ptr = $link; + } + } + if (! $ptr) { + $ptr = $object['url'][0]; + } + } + else { + $ptr = $object['url']; + } - if(array_key_exists('url',$object) && is_array($object['url']) && array_key_exists(0,$object['url'])) { // if original photo width is > 640px make it a cover photo - if(array_key_exists('width',$object['url'][0]) && $object['url'][0]['width'] > 640) { - $scale = ((($object['url'][1]['width'] == 1024) || ($object['url'][1]['height'] == 1024)) ? 1 : 0); - $photo = ''; + if ($ptr) { + if (array_key_exists('width',$ptr) && $ptr['width'] > 640) { + $photo = ''; + } + else { + $item['body'] = '[zmg]' . $ptr['href'] . '[/zmg]' . "\n\n" . $item['body']; + } } - // if original photo width is <= 640px prepend it to item body - elseif(array_key_exists('width',$object['url'][0]) && $object['url'][0]['width'] <= 640) { - $item['body'] = '[zmg]' . $object['url'][0]['href'] . '[/zmg]' . "\n\n" . $item['body']; - } - } } diff --git a/util/zotsh/zotsh.py b/util/zotsh/zotsh.py index 9c7efd8cd..89865fcbe 100755 --- a/util/zotsh/zotsh.py +++ b/util/zotsh/zotsh.py @@ -6,6 +6,7 @@ import requests from requests.auth import HTTPBasicAuth import easywebdav import easywebdav.__version__ as easywebdavversion +import base64 __version__= "0.0.2" @@ -88,7 +89,7 @@ class ZotSH(object): def do(self, command, *args): if not command in self.commands: - raise CommandNotFound("Unknow command '%s'" % command) + raise CommandNotFound("Unknown command '%s'" % command) cmd = getattr(self, "cmd_%s"%command, None) if cmd is None: @@ -153,35 +154,17 @@ class ZotSH(object): session_remote = self.get_host_session(newhost) session_home = self.get_host_session(SERVER) - # call /magic on SERVER - - # FixMe: Written in an earlier era - # This needs to be reworked completely for OpenWebAuth - + bnewhost = newhost + 'dav' + bnewhost = bnewhost.encode('hex') + r = session_home.get( SERVER + "magic", - params={'dest': newhost}, - allow_redirects=False, + params={'bdest': bnewhost, 'owa': 1}, + allow_redirects=True, verify=VERIFY_SSL ) - if not 'location' in r.headers: - raise Exception("Cannot start magic auth to '%s'" % newhostname) - auth_url = r.headers['location'] - - - # call auth_url with "test" param - # FixMe: no longer exists, see above - - r = session_remote.get( - auth_url, - params={'test': 1 }, - verify=VERIFY_SSL ) - - if r.json()['success']: - self.hostname = newhostname - self.session = session_remote - else: - raise Exception("Cannot magic auth to '%s'" % newhostname) + self.hostname = newhostname + self.session = session_remote def cmd_pwd(self, *args): diff --git a/view/js/main.js b/view/js/main.js index 0886964fe..49541c341 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -107,7 +107,7 @@ $(document).ready(function() { if (event.ctrlKey) { totStopped = true; } - $('#pause').html('pause'); + $('#pause').html(''); } else { unpause(); } diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index fb40fc2a2..aafb0d9f2 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -805,7 +805,7 @@ div.jGrowl div.info { } #jGrowl.top-right { top: 4.5rem; - right: 15px; + left: 150px; } div.jGrowl div.jGrowl-notification {