From 61eef68ff3709bc96c962f61f6971c771bc3b832 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 10 Nov 2019 08:55:35 +0000 Subject: =?UTF-8?q?=C3=83remove=20some=20old=20unused=20javascript=20libra?= =?UTF-8?q?ries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 971e7eef9c415a2ce82eb0cd22eaabee12ae719c) --- Zotlabs/Module/Cdav.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index e2855d2b6..af40689c1 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -910,8 +910,6 @@ class Cdav extends Controller { require_once 'vendor/autoload.php'; - head_add_css('cdav.css'); - if(!cdav_principal($principalUri)) { $this->activate($pdo, $channel); if(!cdav_principal($principalUri)) { -- cgit v1.2.3 From 158b8aea387098e62e83920a8425549c02f17bdf Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 10 Nov 2019 10:49:44 +0000 Subject: hopefully fix query for postgres (cherry picked from commit 9ad4c6528cc3ee4e34d2b5d77027a1c33cbadf5c) --- Zotlabs/Daemon/Cron.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index 7b951e7d4..8fa31e6ce 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -97,13 +97,16 @@ class Cron { // Clean expired photos from cache - $sql_interval = "'" . dbesc(datetime_convert()) . "' - INTERVAL " . db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY'); - $r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < $sql_interval", - intval(PHOTO_CACHE) + $r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s", + intval(PHOTO_CACHE), + db_utcnow(), + db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY') ); if($r) { - q("DELETE FROM photo WHERE photo_usage = %d AND expires < $sql_interval", - intval(PHOTO_CACHE) + q("DELETE FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s", + intval(PHOTO_CACHE), + db_utcnow(), + db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY') ); foreach($r as $rr) { $file = dbunescbin($rr['content']); -- cgit v1.2.3 From b033597ada02ef045bc9fbdb2237f81935b73e47 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 11 Nov 2019 21:30:38 +0100 Subject: sse notifications --- Zotlabs/Lib/Enotify.php | 136 +++++++++++- Zotlabs/Lib/ThreadItem.php | 5 +- Zotlabs/Module/Mail.php | 2 +- Zotlabs/Module/Sse.php | 108 ++++++++++ Zotlabs/Module/Sse_bs.php | 519 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 764 insertions(+), 6 deletions(-) create mode 100644 Zotlabs/Module/Sse.php create mode 100644 Zotlabs/Module/Sse_bs.php (limited to 'Zotlabs') diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index 92a488f67..de2bfba24 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -550,6 +550,11 @@ class Enotify { if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', ')) $msg = substr($msg,strpos($msg,', ')+1); + $datarray['id'] = $notify_id; + $datarray['msg'] = $msg; + + call_hooks('enotify_store_end', $datarray); + $r = q("update notify set msg = '%s' where id = %d and uid = %d", dbesc($msg), intval($notify_id), @@ -838,7 +843,7 @@ class Enotify { 'addr' => (($item[$who]['xchan_addr']) ? $item[$who]['xchan_addr'] : $item[$who]['xchan_url']), 'url' => $item[$who]['xchan_url'], 'photo' => $item[$who]['xchan_photo_s'], - 'when' => relative_date(($edit)? $item['edited'] : $item['created']), + 'when' => (($edit) ? datetime_convert('UTC', date_default_timezone_get(), $item['edited']) : datetime_convert('UTC', date_default_timezone_get(), $item['created'])), 'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'), 'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])), 'notify_id' => 'undefined', @@ -846,7 +851,7 @@ class Enotify { 'message' => strip_tags(bbcode($itemem_text)), // these are for the superblock addon 'hash' => $item[$who]['xchan_hash'], - 'uid' => local_channel(), + 'uid' => $item['uid'], 'display' => true ); @@ -858,4 +863,131 @@ class Enotify { return $x; } + static public function format_notify($tt) { + + $message = trim(strip_tags(bbcode($tt['msg']))); + + if(strpos($message, $tt['xname']) === 0) + $message = substr($message, strlen($tt['xname']) + 1); + + $mid = basename($tt['link']); + $mid = ((strpos($mid, 'b64.') === 0) ? @base64url_decode(substr($mid, 4)) : $mid); + + if(in_array($tt['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) { + // we need the thread parent + $r = q("select thr_parent from item where mid = '%s' and uid = %d limit 1", + dbesc($mid), + intval(local_channel()) + ); + $b64mid = ((strpos($r[0]['thr_parent'], 'b64.') === 0) ? $r[0]['thr_parent'] : 'b64.' . base64url_encode($r[0]['thr_parent'])); + } + else { + $b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid)); + } + + $x = [ + 'notify_link' => z_root() . '/notify/view/' . $tt['id'], + 'name' => $tt['xname'], + 'url' => $tt['url'], + 'photo' => $tt['photo'], + 'when' => datetime_convert('UTC', date_default_timezone_get(), $tt['created']), + 'hclass' => (($tt['seen']) ? 'notify-seen' : 'notify-unseen'), + 'b64mid' => (($tt['otype'] == 'item') ? $b64mid : 'undefined'), + 'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : 'undefined'), + 'message' => $message + ]; + + return $x; + + } + + static public function format_intros($rr) { + + $x = [ + 'notify_link' => z_root() . '/connections/ifpending', + 'name' => $rr['xchan_name'], + 'addr' => $rr['xchan_addr'], + 'url' => $rr['xchan_url'], + 'photo' => $rr['xchan_photo_s'], + 'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['abook_created']), + 'hclass' => ('notify-unseen'), + 'message' => t('added your channel') + ]; + + return $x; + + } + + static public function format_files($rr) { + + $x = [ + 'notify_link' => z_root() . '/sharedwithme', + 'name' => $rr['author']['xchan_name'], + 'addr' => $rr['author']['xchan_addr'], + 'url' => $rr['author']['xchan_url'], + 'photo' => $rr['author']['xchan_photo_s'], + 'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['created']), + 'hclass' => ('notify-unseen'), + 'message' => t('shared a file with you') + ]; + + return $x; + + } + + static public function format_mail($rr) { + + $x = [ + 'notify_link' => z_root() . '/mail/' . $rr['id'], + 'name' => $rr['xchan_name'], + 'addr' => $rr['xchan_addr'], + 'url' => $rr['xchan_url'], + 'photo' => $rr['xchan_photo_s'], + 'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['created']), + 'hclass' => (intval($rr['mail_seen']) ? 'notify-seen' : 'notify-unseen'), + 'message' => t('sent you a private message'), + ]; + + return $x; + + } + + static public function format_all_events($rr) { + + $bd_format = t('g A l F d') ; // 8 AM Friday January 18 + $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart']); + $today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false); + $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); + + $x = [ + 'notify_link' => z_root() . '/cdav/calendar/' . $rr['event_hash'], + 'name' => $rr['xchan_name'], + 'addr' => $rr['xchan_addr'], + 'url' => $rr['xchan_url'], + 'photo' => $rr['xchan_photo_s'], + 'when' => $when, + 'hclass' => ('notify-unseen'), + 'message' => t('posted an event') + ]; + + return $x; + + } + + static public function format_register($rr) { + + $x = [ + 'notify_link' => z_root() . '/admin/accounts', + 'name' => $rr['account_email'], + 'addr' => $rr['account_email'], + 'url' => '', + 'photo' => z_root() . '/' . get_default_profile_photo(48), + 'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['account_created']), + 'hclass' => ('notify-unseen'), + 'message' => t('requires approval') + ]; + + return $x; + + } } diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 5e4600df2..174af7f0e 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -369,7 +369,7 @@ class ThreadItem { 'folders' => $body['folders'], 'text' => strip_tags($body['html']), 'id' => $this->get_id(), - 'mid' => $item['mid'], + 'mid' => 'b64.' . base64url_encode($item['mid']), 'parent' => $item['parent'], 'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']), 'isevent' => $isevent, @@ -467,10 +467,9 @@ class ThreadItem { 'previewing' => ($conv->is_preview() ? true : false ), 'preview_lbl' => t('This is an unsaved preview'), 'wait' => t('Please wait'), - 'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])), 'thread_level' => $thread_level, 'settings' => $settings, - 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? $item['thr_parent'] : '') + 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? 'b64.' . base64url_encode($item['thr_parent']) : '') ); $arr = array('item' => $item, 'output' => $tmp_item); diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index 7c344966b..636fc4e33 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -145,7 +145,7 @@ class Mail extends \Zotlabs\Web\Controller { $o = ''; nav_set_selected('Mail'); - + if(! local_channel()) { notice( t('Permission denied.') . EOL); return login(); diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php new file mode 100644 index 000000000..97fee5f49 --- /dev/null +++ b/Zotlabs/Module/Sse.php @@ -0,0 +1,108 @@ + 0) + self::$offset = argv(2); + else + $_SESSION['sse_loadtime'] = datetime_convert(); + + $network = false; + $home = false; + $pubs = false; + $f = ''; + + switch (argv(1)) { + case 'network': + $network = true; + $f = 'bs_network'; + break; + case 'home': + $home = true; + $f = 'bs_home'; + break; + case 'pubs': + $pubs = true; + $f = 'bs_pubs'; + break; + default: + } + + //hz_syslog('init: ' . argv(1)); + //hz_syslog('offset: ' . argv(2)); + + if(self::$offset && $f) { + $result = self::$f(true); + json_return_and_die($result); + } + + $result = array_merge( + self::bs_network($network), + self::bs_home($home), + self::bs_notify(), + self::bs_intros(), + self::bs_forums(), + self::bs_pubs($pubs), + self::bs_files(), + self::bs_mail(), + self::bs_all_events(), + self::bs_register() + ); + + json_return_and_die($result); + } + + function bs_network($notifications) { + + $result['network']['notifications'] = []; + $result['network']['count'] = 0; + + if(! self::$uid) + return $result; + + $limit = intval(self::$limit); + $offset = self::$offset; + + $sql_extra = ''; + if(! (self::$vnotify & VNOTIFY_LIKE)) + $sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + + $sql_extra2 = ''; + if(self::$xchans) + $sql_extra2 = " AND (author_xchan IN (" . self::$xchans . ") OR owner_xchan IN (" . self::$xchans . ")) "; + + $item_normal = item_normal(); + + if ($notifications) { + $items = q("SELECT * FROM item + WHERE uid = %d + AND created <= '%s' + AND item_unseen = 1 AND item_wall = 0 + AND author_xchan != '%s' + $item_normal + $sql_extra + $sql_extra2 + ORDER BY created DESC LIMIT $limit OFFSET $offset", + intval(self::$uid), + dbescdate($_SESSION['sse_loadtime']), + dbesc(self::$ob_hash) + ); + + if($items) { + $result['network']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1); + xchan_query($items); + foreach($items as $item) { + $result['network']['notifications'][] = Enotify::format($item); + } + } + else { + $result['network']['offset'] = -1; + } + + } + + $r = q("SELECT count(id) as total FROM item + WHERE uid = %d and item_unseen = 1 AND item_wall = 0 + $item_normal + $sql_extra + AND author_xchan != '%s'", + intval(self::$uid), + dbesc(self::$ob_hash) + ); + + if($r) + $result['network']['count'] = intval($r[0]['total']); + + return $result; + } + + function bs_home($notifications) { + + $result['home']['notifications'] = []; + $result['home']['count'] = 0; + + if(! self::$uid) + return $result; + + $limit = intval(self::$limit); + $offset = self::$offset; + + $sql_extra = ''; + if(! (self::$vnotify & VNOTIFY_LIKE)) + $sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + + $sql_extra2 = ''; + if(self::$xchans) + $sql_extra2 = " AND (author_xchan IN (" . self::$xchans . ") OR owner_xchan IN (" . self::$xchans . ")) "; + + + $item_normal = item_normal(); + + if ($notifications) { + $items = q("SELECT * FROM item + WHERE uid = %d + AND created <= '%s' + AND item_unseen = 1 AND item_wall = 1 + AND author_xchan != '%s' + $item_normal + $sql_extra + $sql_extra2 + ORDER BY created DESC LIMIT $limit OFFSET $offset", + intval(self::$uid), + dbescdate($_SESSION['sse_loadtime']), + dbesc(self::$ob_hash) + ); + + if($items) { + $result['home']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1); + xchan_query($items); + foreach($items as $item) { + $result['home']['notifications'][] = Enotify::format($item); + } + } + else { + $result['home']['offset'] = -1; + } + + } + + $r = q("SELECT count(id) as total FROM item + WHERE uid = %d and item_unseen = 1 AND item_wall = 1 + $item_normal + $sql_extra + AND author_xchan != '%s'", + intval(self::$uid), + dbesc(self::$ob_hash) + ); + + if($r) + $result['home']['count'] = intval($r[0]['total']); + + return $result; + } + + function bs_pubs($notifications) { + + $result['pubs']['notifications'] = []; + $result['pubs']['count'] = 0; + + if(! isset($_SESSION['static_loadtime'])) + $_SESSION['static_loadtime'] = datetime_convert(); + + $limit = intval(self::$limit); + $offset = self::$offset; + + $sys = get_sys_channel(); + $sql_extra = ''; + if(! (self::$vnotify & VNOTIFY_LIKE)) + $sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + + $sql_extra2 = ''; + if(self::$xchans) + $sql_extra2 = " AND (author_xchan IN (" . self::$xchans . ") OR owner_xchan IN (" . self::$xchans . ")) "; + + $item_normal = item_normal(); + + if ($notifications) { + $items = q("SELECT * FROM item + WHERE uid = %d + AND created <= '%s' + AND item_unseen = 1 + AND author_xchan != '%s' + AND created > '%s' + $item_normal + $sql_extra + $sql_extra2 + ORDER BY created DESC LIMIT $limit OFFSET $offset", + intval($sys['channel_id']), + dbescdate($_SESSION['sse_loadtime']), + dbesc(self::$ob_hash), + dbescdate($_SESSION['static_loadtime']) + ); + + if($items) { + $result['pubs']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1); + xchan_query($items); + foreach($items as $item) { + $result['pubs']['notifications'][] = Enotify::format($item); + } + } + else { + $result['pubs']['offset'] = -1; + } + + + } + + $r = q("SELECT count(id) as total FROM item + WHERE uid = %d AND item_unseen = 1 + AND created > '%s' + $item_normal + $sql_extra + AND author_xchan != '%s'", + intval($sys['channel_id']), + dbescdate($_SESSION['static_loadtime']), + dbesc(self::$ob_hash) + ); + + if($r) + $result['pubs']['count'] = intval($r[0]['total']); + + return $result; + } + + + function bs_notify() { + + $result['notify']['notifications'] = []; + $result['notify']['count'] = 0; + $result['notify']['offset'] = -1; + + if(! self::$uid) + return $result; + + $r = q("SELECT * FROM notify WHERE uid = %d AND seen = 0 ORDER BY created DESC", + intval(self::$uid) + ); + if($r) { + foreach($r as $rr) { + $result['notify']['notifications'][] = Enotify::format_notify($rr); + } + $result['notify']['count'] = count($r); + } + + return $result; + + } + + function bs_intros() { + + $result['intros']['notifications'] = []; + $result['intros']['count'] = 0; + $result['intros']['offset'] = -1; + + if(! self::$uid) + return $result; + + $r = q("SELECT * FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ORDER BY abook_created DESC LIMIT 50", + intval(self::$uid) + ); + + if($r) { + foreach($r as $rr) { + $result['intros']['notifications'][] = Enotify::format_intros($rr); + } + $result['intros']['count'] = count($r); + } + + return $result; + + } + + function bs_forums() { + + $result['forums']['notifications'] = []; + $result['forums']['count'] = 0; + $result['forums']['offset'] = -1; + + if(! self::$uid) + return $result; + + $forums = get_forum_channels(self::$uid); + + if($forums) { + $item_normal = item_normal(); + + $sql_extra = ''; + if(! (self::$vnotify & VNOTIFY_LIKE)) + $sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + + $fcount = count($forums); + $i = 0; + + for($x = 0; $x < $fcount; $x ++) { + $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", + intval(self::$uid), + intval(TERM_FORUM), + dbesc($forums[$x]['xchan_name']) + ); + + $p_str = ids_to_querystr($p, 'parent'); + $p_sql = (($p_str) ? "OR parent IN ( $p_str )" : ''); + + $r = q("select count(id) as unseen from item + where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $sql_extra $item_normal", + intval(self::$uid), + dbesc($forums[$x]['xchan_hash']), + dbesc($forums[$x]['xchan_hash']) + ); + + if($r[0]['unseen']) { + $forums[$x]['notify_link'] = (($forums[$x]['private_forum']) ? $forums[$x]['xchan_url'] : z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id']); + $forums[$x]['name'] = $forums[$x]['xchan_name']; + $forums[$x]['addr'] = $forums[$x]['xchan_addr']; + $forums[$x]['url'] = $forums[$x]['xchan_url']; + $forums[$x]['photo'] = $forums[$x]['xchan_photo_s']; + $forums[$x]['unseen'] = $r[0]['unseen']; + $forums[$x]['private_forum'] = (($forums[$x]['private_forum']) ? 'lock' : ''); + $forums[$x]['message'] = (($forums[$x]['private_forum']) ? t('Private forum') : t('Public forum')); + + unset($forums[$x]['abook_id']); + unset($forums[$x]['xchan_hash']); + unset($forums[$x]['xchan_name']); + unset($forums[$x]['xchan_url']); + unset($forums[$x]['xchan_photo_s']); + + $i = $i + $r[0]['unseen']; + + } + else { + unset($forums[$x]); + } + } + + $result['forums']['count'] = $i; + $result['forums']['notifications'] = array_values($forums); + + } + + return $result; + + } + + function bs_files() { + + $result['files']['notifications'] = []; + $result['files']['count'] = 0; + $result['files']['offset'] = -1; + + if(! self::$uid) + return $result; + + $r = q("SELECT * FROM item + WHERE verb = '%s' + AND obj_type = '%s' + AND uid = %d + AND owner_xchan != '%s' + AND item_unseen = 1", + dbesc(ACTIVITY_POST), + dbesc(ACTIVITY_OBJ_FILE), + intval(self::$uid), + dbesc(self::$ob_hash) + ); + if($r) { + xchan_query($r); + foreach($r as $rr) { + $result['files']['notifications'][] = Enotify::format_files($rr); + } + $result['files']['count'] = count($r); + } + + return $result; + + } + + function bs_mail() { + + $result['mail']['notifications'] = []; + $result['mail']['count'] = 0; + $result['mail']['offset'] = -1; + + if(! self::$uid) + return $result; + + $r = q("select mail.*, xchan.* from mail left join xchan on xchan_hash = from_xchan + where channel_id = %d and mail_seen = 0 and mail_deleted = 0 + and from_xchan != '%s' order by created desc", + intval(self::$uid), + dbesc(self::$ob_hash) + ); + + if($r) { + foreach($r as $rr) { + $result['mail']['notifications'][] = Enotify::format_mail($rr); + } + $result['mail']['count'] = count($r); + } + + return $result; + + } + + function bs_all_events() { + + $result['all_events']['notifications'] = []; + $result['all_events']['count'] = 0; + $result['all_events']['offset'] = -1; + + if(! self::$uid) + return $result; + + $r = q("SELECT * FROM event left join xchan on event_xchan = xchan_hash + WHERE event.uid = %d AND dtstart < '%s' AND dtstart > '%s' and dismissed = 0 + and etype in ( 'event', 'birthday' ) + ORDER BY dtstart DESC", + intval(self::$uid), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval(self::$evdays) . ' days')), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) + ); + + if($r) { + foreach($r as $rr) { + $result['all_events']['notifications'][] = Enotify::format_all_events($rr); + } + $result['all_events']['count'] = count($r); + } + + return $result; + } + + function bs_register() { + + $result['register']['notifications'] = []; + $result['register']['count'] = 0; + $result['register']['offset'] = -1; + + if(! self::$uid && ! is_site_admin()) + return $result; + + $r = q("SELECT account_email, account_created from account where (account_flags & %d) > 0", + intval(ACCOUNT_PENDING) + ); + if($r) { + foreach($r as $rr) { + $result['register']['notifications'][] = Enotify::format_register($rr); + } + $result['register']['count'] = count($r); + } + + return $result; + + } + +} -- cgit v1.2.3 From 209d06a8f795282ddf370dff8228d2385004d05a Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 12 Nov 2019 10:11:58 +0000 Subject: better detection for who to send sys notifications (needs addons update) --- Zotlabs/Module/Sse.php | 2 ++ Zotlabs/Module/Sse_bs.php | 3 +++ 2 files changed, 5 insertions(+) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 97fee5f49..6f7e9543a 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -84,6 +84,7 @@ class Sse extends Controller { echo "\n\n"; del_xconfig(self::$ob_hash, 'sse', 'notifications'); + set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); unset($result); } @@ -96,6 +97,7 @@ class Sse extends Controller { flush(); if(connection_status() != CONNECTION_NORMAL || connection_aborted()) { + del_xconfig(self::$ob_hash, 'sse', 'timestamp'); break; } diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php index 672a6c5ef..c591a00bf 100644 --- a/Zotlabs/Module/Sse_bs.php +++ b/Zotlabs/Module/Sse_bs.php @@ -27,6 +27,9 @@ class Sse_bs extends Controller { self::$offset = 0; self::$xchans = ''; + if(self::$ob_hash) + set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); + if(!empty($_GET['nquery']) && $_GET['nquery'] !== '%') { $nquery = $_GET['nquery']; -- cgit v1.2.3 From 6e36820b1bbc35bc3d26ff4eca2b63a386b30462 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 12 Nov 2019 21:15:01 +0000 Subject: sse: do not delete xconfig - reset it --- Zotlabs/Module/Sse.php | 5 +++-- Zotlabs/Module/Sse_bs.php | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 6f7e9543a..3e46a325c 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -83,7 +83,7 @@ class Sse extends Controller { echo 'data: ' . json_encode($result); echo "\n\n"; - del_xconfig(self::$ob_hash, 'sse', 'notifications'); + set_xconfig(self::$ob_hash, 'sse', 'notifications', []); set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); unset($result); } @@ -97,7 +97,8 @@ class Sse extends Controller { flush(); if(connection_status() != CONNECTION_NORMAL || connection_aborted()) { - del_xconfig(self::$ob_hash, 'sse', 'timestamp'); + //TODO: this does not seem to be triggered + set_xconfig(self::$ob_hash, 'sse', 'timestamp', NULL_DATE); break; } diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php index c591a00bf..c7fcd0542 100644 --- a/Zotlabs/Module/Sse_bs.php +++ b/Zotlabs/Module/Sse_bs.php @@ -27,8 +27,10 @@ class Sse_bs extends Controller { self::$offset = 0; self::$xchans = ''; - if(self::$ob_hash) + if(self::$ob_hash) { set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); + set_xconfig(self::$ob_hash, 'sse', 'language', App::$language); + } if(!empty($_GET['nquery']) && $_GET['nquery'] !== '%') { $nquery = $_GET['nquery']; -- cgit v1.2.3 From e5e16da8cba85d347351f6d3f243fa7c5fee4c2f Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 13 Nov 2019 13:26:28 +0000 Subject: sse: reset to empty string instead of empty array --- Zotlabs/Module/Sse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 3e46a325c..e1778718c 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -83,7 +83,7 @@ class Sse extends Controller { echo 'data: ' . json_encode($result); echo "\n\n"; - set_xconfig(self::$ob_hash, 'sse', 'notifications', []); + set_xconfig(self::$ob_hash, 'sse', 'notifications', ''); set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); unset($result); } -- cgit v1.2.3 From 52bd27a0280c736e563ccc67a9307cd75bd14d3f Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 13 Nov 2019 13:40:40 +0000 Subject: check if file exists --- Zotlabs/Web/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index c4db0ef3e..96bf131b8 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -56,7 +56,7 @@ class Router { $routes = Route::get(); if($routes) { foreach($routes as $route) { - if(is_array($route) && strtolower($route[1]) === $module) { + if(is_array($route) && file_exists($route[0]) && strtolower($route[1]) === $module) { include_once($route[0]); if(class_exists($modname)) { $this->controller = new $modname; -- cgit v1.2.3 From a982aecd5b2f8f36507f6893028232d7f7a4c008 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 13 Nov 2019 13:51:00 +0000 Subject: sse: revert to reset to array --- Zotlabs/Module/Sse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index e1778718c..3e46a325c 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -83,7 +83,7 @@ class Sse extends Controller { echo 'data: ' . json_encode($result); echo "\n\n"; - set_xconfig(self::$ob_hash, 'sse', 'notifications', ''); + set_xconfig(self::$ob_hash, 'sse', 'notifications', []); set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); unset($result); } -- cgit v1.2.3 From f3fa2d853ab04441e223b0074462bf11c6f99184 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 13 Nov 2019 14:30:54 +0000 Subject: sse: make sure we have an observer --- Zotlabs/Module/Sse.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 3e46a325c..556fe2853 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -24,6 +24,9 @@ class Sse extends Controller { self::$ob_hash = get_observer_hash(); self::$vnotify = get_pconfig(self::$uid, 'system', 'vnotify'); + if(! self::$ob_hash) + return; + $sleep_seconds = 3; header("Content-Type: text/event-stream"); -- cgit v1.2.3 From 3009c88d246ddcafabf1965f88c5ebd8fe1717fd Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Nov 2019 09:43:39 +0000 Subject: AP fixes --- Zotlabs/Lib/Activity.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index e41e165b1..08a8b8d03 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -609,9 +609,15 @@ class Activity { } if($i['id'] != $i['parent']) { - $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); $reply = true; + // inReplyTo needs to be set in the activity for followup actiions (Like, Dislike, Attend, Announce, etc.), + // but *not* for comments, where it should only be present in the object + + if (! in_array($ret['type'],[ 'Create','Update' ])) { + $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); + } + if($i['item_private']) { $d = q("select xchan_url, xchan_addr, xchan_name from item left join xchan on xchan_hash = author_xchan where id = %d limit 1", intval($i['parent']) -- cgit v1.2.3 From de9a7f0fa909792656d26d369f2ff21c57fc1e4d Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Nov 2019 09:55:44 +0000 Subject: make inline pdf a security option, move thumbnail security to security options from admin/site --- Zotlabs/Module/Admin/Security.php | 14 +++++++++++--- Zotlabs/Module/Admin/Site.php | 3 --- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Module/Admin/Security.php b/Zotlabs/Module/Admin/Security.php index 80c1d85b7..16045f9ed 100644 --- a/Zotlabs/Module/Admin/Security.php +++ b/Zotlabs/Module/Admin/Security.php @@ -43,6 +43,12 @@ class Security { $be = $this->trim_array_elems(explode("\n",$_POST['embed_deny'])); set_config('system','embed_deny',$be); + + $thumbnail_security = ((x($_POST,'thumbnail_security')) ? intval($_POST['thumbnail_security']) : 0); + set_config('system', 'thumbnail_security' , $thumbnail_security); + + $inline_pdf = ((x($_POST,'inline_pdf')) ? intval($_POST['inline_pdf']) : 0); + set_config('system', 'inline_pdf' , $inline_pdf); $ts = ((x($_POST,'transport_security')) ? True : False); set_config('system','transport_security_header',$ts); @@ -86,7 +92,7 @@ class Security { $embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:"); $embedhelp3 = t("https://youtube.com/
https://www.youtube.com/
https://youtu.be/
https://vimeo.com/
https://soundcloud.com/
"); $embedhelp4 = t("All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."); - + $t = get_markup_template('admin_security.tpl'); return replace_macros($t, array( '$title' => t('Administration'), @@ -106,7 +112,9 @@ class Security { '$embed_sslonly' => array('embed_sslonly',t('Only allow embeds from secure (SSL) websites and links.'), intval(get_config('system','embed_sslonly')),''), '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. By default embedded content is filtered.')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), - + '$thumbnail_security' => [ 'thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.") ], + '$inline_pdf' => [ 'inline_pdf', t("Allow embedded (inline) PDF files"), get_config('system','inline_pdf',0), '' ], + // '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), '$submit' => t('Submit') @@ -128,4 +136,4 @@ class Security { } -} \ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 55c8ca928..4bb34b7b7 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -73,7 +73,6 @@ class Site { $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); $verify_email = ((x($_POST,'verify_email')) ? 1 : 0); $imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : ''); - $thumbnail_security = ((x($_POST,'thumbnail_security')) ? intval($_POST['thumbnail_security']) : 0); $force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000); $pub_incl = escape_tags(trim($_POST['pub_incl'])); $pub_excl = escape_tags(trim($_POST['pub_excl'])); @@ -100,7 +99,6 @@ class Site { set_config('system', 'from_email', $from_email); set_config('system', 'from_email_name' , $from_email_name); set_config('system', 'imagick_convert_path' , $imagick_path); - set_config('system', 'thumbnail_security' , $thumbnail_security); set_config('system', 'default_permissions_role', $permissions_role); set_config('system', 'pubstream_incl',$pub_incl); set_config('system', 'pubstream_excl',$pub_excl); @@ -341,7 +339,6 @@ class Site { '$force_queue' => array('force_queue', t("Queue Threshold"), get_config('system','force_queue_threshold',3000), t("Always defer immediate delivery if queue contains more than this number of entries.")), '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), '$imagick_path' => array('imagick_path', t("Path to ImageMagick convert program"), get_config('system','imagick_convert_path'), t("If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert")), - '$thumbnail_security' => array('thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), '$active_expire_days' => array('active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), ''), -- cgit v1.2.3 From 5a6b14f8787927ee6ea99c622d02875811d3a74a Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Nov 2019 10:01:21 +0000 Subject: onepoll: do not update dead feeds --- Zotlabs/Daemon/Onepoll.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 1d9fd5f72..2f06ec125 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -61,11 +61,13 @@ class Onepoll { if($contact['xchan_network'] === 'rss') { logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG); - handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']); - q("update abook set abook_connected = '%s' where abook_id = %d", - dbesc(datetime_convert()), - intval($contact['abook_id']) - ); + $alive = handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']); + if ($alive) { + q("update abook set abook_connected = '%s' where abook_id = %d", + dbesc(datetime_convert()), + intval($contact['abook_id']) + ); + } return; } -- cgit v1.2.3 From 965c51c2d45a98db10543c5108ac486e4fc6459e Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Nov 2019 20:29:58 +0000 Subject: sse: implement notifications for anonymous visitors (info, notice and pubs) and fix a potential memory leak --- Zotlabs/Daemon/Cron_daily.php | 6 ++++++ Zotlabs/Module/Sse.php | 31 +++++++++++++++++++++++++------ Zotlabs/Module/Sse_bs.php | 32 +++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 13 deletions(-) (limited to 'Zotlabs') diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php index dbfcff439..b41625963 100644 --- a/Zotlabs/Daemon/Cron_daily.php +++ b/Zotlabs/Daemon/Cron_daily.php @@ -44,6 +44,12 @@ class Cron_daily { db_utcnow(), db_quoteinterval('1 YEAR') ); + // expire anonymous sse notification entries once a day + + q("delete from xconfig where xchan like '%s'", + dbesc('sse_id.%') + ); + //update statistics in config require_once('include/statistics_fns.php'); diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 556fe2853..b227a396d 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -11,22 +11,41 @@ class Sse extends Controller { public static $uid; public static $ob_hash; + public static $sse_id; public static $vnotify; function init() { + if((observer_prohibited(true))) { + killme(); + } + + if(! intval(get_config('system','open_pubstream',1))) { + if(! get_observer_hash()) { + killme(); + } + } + // this is important! session_write_close(); - $sys = get_sys_channel(); - self::$uid = local_channel(); self::$ob_hash = get_observer_hash(); - self::$vnotify = get_pconfig(self::$uid, 'system', 'vnotify'); + self::$sse_id = false; - if(! self::$ob_hash) - return; + if(! self::$ob_hash) { + if(session_id()) { + self::$sse_id = true; + self::$ob_hash = 'sse_id.' . session_id(); + } + else { + return; + } + } + self::$vnotify = get_pconfig(self::$uid, 'system', 'vnotify'); + + $sys = get_sys_channel(); $sleep_seconds = 3; header("Content-Type: text/event-stream"); @@ -40,7 +59,7 @@ class Sse extends Controller { * Update chat presence indication (if applicable) */ - if(self::$ob_hash) { + if(! self::$sse_id) { $r = q("select cp_id, cp_room from chatpresence where cp_xchan = '%s' and cp_client = '%s' and cp_room = 0 limit 1", dbesc(self::$ob_hash), dbesc($_SERVER['REMOTE_ADDR']) diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php index c7fcd0542..270e8b9b9 100644 --- a/Zotlabs/Module/Sse_bs.php +++ b/Zotlabs/Module/Sse_bs.php @@ -11,6 +11,7 @@ class Sse_bs extends Controller { public static $uid; public static $ob_hash; + public static $sse_id; public static $vnotify; public static $evdays; public static $limit; @@ -21,16 +22,26 @@ class Sse_bs extends Controller { self::$uid = local_channel(); self::$ob_hash = get_observer_hash(); + self::$sse_id = false; + + if(! self::$ob_hash) { + if(session_id()) { + self::$sse_id = true; + self::$ob_hash = 'sse_id.' . session_id(); + } + else { + return; + } + } + self::$vnotify = get_pconfig(self::$uid, 'system', 'vnotify'); self::$evdays = intval(get_pconfig(self::$uid, 'system', 'evdays')); self::$limit = 100; self::$offset = 0; self::$xchans = ''; - if(self::$ob_hash) { - set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); - set_xconfig(self::$ob_hash, 'sse', 'language', App::$language); - } + set_xconfig(self::$ob_hash, 'sse', 'timestamp', datetime_convert()); + set_xconfig(self::$ob_hash, 'sse', 'language', App::$language); if(!empty($_GET['nquery']) && $_GET['nquery'] !== '%') { $nquery = $_GET['nquery']; @@ -69,9 +80,6 @@ class Sse_bs extends Controller { default: } - //hz_syslog('init: ' . argv(1)); - //hz_syslog('offset: ' . argv(2)); - if(self::$offset && $f) { $result = self::$f(true); json_return_and_die($result); @@ -227,6 +235,16 @@ class Sse_bs extends Controller { $result['pubs']['notifications'] = []; $result['pubs']['count'] = 0; + if((observer_prohibited(true))) { + return $result; + } + + if(! intval(get_config('system','open_pubstream',1))) { + if(! get_observer_hash()) { + return $result; + } + } + if(! isset($_SESSION['static_loadtime'])) $_SESSION['static_loadtime'] = datetime_convert(); -- cgit v1.2.3