From e74359fcfe4d97efe72a811b45526a69edae3893 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 11 Feb 2022 09:10:19 +0000 Subject: 3rd arg in str_replace() can not be null --- include/network.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/network.php b/include/network.php index 64605749d..044678a05 100644 --- a/include/network.php +++ b/include/network.php @@ -1986,6 +1986,10 @@ function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) { if($acceptedTypes === false) $acceptedTypes = $_SERVER['HTTP_ACCEPT']; + if (!$acceptedTypes) { + return null; + } + // Accept header is case insensitive, and whitespace isn’t important $accept = strtolower(str_replace(' ', '', $acceptedTypes)); // divide it into parts in the place of a "," -- cgit v1.2.3 From 139ffae3674e59307b46c67b0dcf77be9ec87b19 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 11 Feb 2022 09:51:21 +0000 Subject: fix another deprecation warning --- include/network.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/network.php b/include/network.php index 044678a05..fa408e602 100644 --- a/include/network.php +++ b/include/network.php @@ -365,9 +365,14 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) { if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) { $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); - $newurl = trim(array_pop($matches)); - if(strpos($newurl,'/') === 0) + + $newurl = ''; + if (array_pop($matches)) + $newurl = trim(array_pop($matches)); + + if($newurl && strpos($newurl,'/') === 0) $newurl = $url . $newurl; + $url_parsed = @parse_url($newurl); if (isset($url_parsed)) { curl_close($ch); -- cgit v1.2.3 From a7ec1805e3f5836641503d1f8cb6ccc1d8c885fa Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 13 Feb 2022 18:58:12 +0000 Subject: address deprecation warnings --- include/bbcode.php | 4 ++-- include/language.php | 5 +++++ include/text.php | 7 +++++-- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index 03115effe..794cb25d0 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -488,9 +488,9 @@ function getAttachmentData($body) { $data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8'); } - $data["description"] = trim($match[3]); + $data["description"] = ((isset($match[3])) ? trim($match[3]) : ''); - $data["after"] = trim($match[4]); + $data["after"] = ((isset($match[4])) ? trim($match[4]) : ''); return $data; } diff --git a/include/language.php b/include/language.php index d291deb63..23aff0a02 100644 --- a/include/language.php +++ b/include/language.php @@ -311,6 +311,11 @@ function string_plural_select_default($n) { * @return string Language code in 2-letter ISO 639-1 (en, de, fr) format */ function detect_language($s) { + + if (!$s) { + return EMPTY_STR; + } + $min_length = get_config('system', 'language_detect_min_length'); if ($min_length === false) $min_length = LANGUAGE_DETECT_MIN_LENGTH; diff --git a/include/text.php b/include/text.php index 29a2ab3b1..f69801302 100644 --- a/include/text.php +++ b/include/text.php @@ -108,7 +108,10 @@ function notags($string) { * @return string */ function escape_tags($string) { - return(htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false)); + if (!$string) { + return EMPTY_STR; + } + return (htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false)); } @@ -3531,7 +3534,7 @@ function text_highlight($s, $lang) { // echo (($xml->asXML('data.xml')) ? 'Your XML file has been generated successfully!' : 'Error generating XML file!'); function arrtoxml($root_elem,$arr) { - $xml = new SimpleXMLElement('<' . $root_elem . '>', null, false); + $xml = new SimpleXMLElement('<' . $root_elem . '>', 0, false); array2XML($xml,$arr); return $xml->asXML(); -- cgit v1.2.3 From c0350861ef0da66209e6b08c75af2c16e3673e25 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 13 Feb 2022 19:31:51 +0000 Subject: php8 warnings --- include/feedutils.php | 14 +++++++------- include/oembed.php | 12 +++++++----- include/text.php | 3 ++- include/zid.php | 2 ++ 4 files changed, 18 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/feedutils.php b/include/feedutils.php index 1c653325d..b21495d72 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -194,14 +194,14 @@ function construct_activity_object($item) { $r = json_decode($item['obj'],false); if(! $r) - return ''; - if($r->type) + return EMPTY_STR; + if(isset($r->type)) $o .= '' . xmlify($r->type) . '' . "\r\n"; - if($r->id) + if(isset($r->id)) $o .= '' . xmlify($r->id) . '' . "\r\n"; - if($r->title) + if(isset($r->title)) $o .= '' . xmlify($r->title) . '' . "\r\n"; - if($r->links) { + if(isset($r->links)) { /** @FIXME!! */ if(substr($r->link,0,1) === '<') { $r->link = preg_replace('/\/','',$r->link); @@ -210,7 +210,7 @@ function construct_activity_object($item) { else $o .= '' . "\r\n"; } - if($r->content) { + if(isset($r->content)) { $o .= '' . xmlify(bbcode($r->content)) . '' . "\r\n"; } $o .= '' . "\r\n"; @@ -218,7 +218,7 @@ function construct_activity_object($item) { return $o; } - return ''; + return EMPTY_STR; } function construct_activity_target($item) { diff --git a/include/oembed.php b/include/oembed.php index 9a25686fa..36938c577 100644 --- a/include/oembed.php +++ b/include/oembed.php @@ -134,6 +134,7 @@ function oembed_fetch_url($embedurl){ } $txt = null; + $j = null; // we should try to cache this and avoid a lookup on each render $is_matrix = is_matrix_url($embedurl); @@ -160,7 +161,7 @@ function oembed_fetch_url($embedurl){ if(is_null($txt)) { - $txt = ""; + $txt = EMPTY_STR; if ($action !== 'block') { // try oembed autodiscovery @@ -168,7 +169,7 @@ function oembed_fetch_url($embedurl){ $result = z_fetch_url($furl, false, $redirects, [ 'timeout' => 30, - 'accept_content' => "text/*", + 'accept_content' => 'text/*', 'novalidate' => true, 'session' => ((local_channel() && $zrl) ? true : false) ] @@ -227,9 +228,10 @@ function oembed_fetch_url($embedurl){ $txt = $x['embed']; } - $txt=trim($txt); + $txt = trim($txt); - if ($txt[0]!="{") $txt='{"type":"error"}'; + if (substr($txt, 0, 1) !== '{') + $txt = '{"type":"error"}'; // save in cache @@ -247,7 +249,7 @@ function oembed_fetch_url($embedurl){ } if($action === 'filter') { - if($j['html']) { + if(isset($j['html']) && $j['html']) { $orig = $j['html']; $allow_position = (($is_matrix) ? true : false); diff --git a/include/text.php b/include/text.php index f69801302..9a2ca1af4 100644 --- a/include/text.php +++ b/include/text.php @@ -4057,9 +4057,10 @@ function sanitize_text_field($str) { */ function substr_words($str, $max_length, $suffix = '...') { + $ret = ''; + if (strlen($str) > $max_length) { $words = preg_split('/\s/', $str); - $ret = ''; $i = 0; while (true) { $length = (strlen($ret) + strlen($words[$i])); diff --git a/include/zid.php b/include/zid.php index ae7d9e252..5710d9f3f 100644 --- a/include/zid.php +++ b/include/zid.php @@ -58,6 +58,8 @@ function zid($s, $address = '') { $mine_parsed = parse_url($mine); $s_parsed = parse_url($s); + + $url_match = false; if(isset($mine_parsed['host']) && isset($s_parsed['host']) && $mine_parsed['host'] === $s_parsed['host']) $url_match = true; -- cgit v1.2.3 From 2a60f1cc6ed49ab559090c831788308fe3df0706 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 20 Feb 2022 20:18:24 +0000 Subject: merge branch pdledit_gui into dev - many widgets still miss their description and requirements (this is work in progress) --- include/plugin.php | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'include') diff --git a/include/plugin.php b/include/plugin.php index 95c9882d0..25fa22e10 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -793,6 +793,79 @@ function get_theme_info($theme){ return $info; } +/** + * @brief Parse template comment in search of template info. + * + * like + * \code + * * Name: MyWidget + * * Description: A widget + * * Version: 1.2.3 + * * Author: John + * * Author: Jane + * * ContentRegionID: some_id + * * ContentRegionID: some_other_id + * * + *\endcode + * @param string $widget the name of the widget + * @return array with the information + */ +function get_template_info($template){ + $m = array(); + $info = array( + 'name' => $template, + 'description' => '', + 'author' => array(), + 'maintainer' => array(), + 'version' => '', + 'content_regions' => [] + ); + + $checkpaths = [ + "view/php/$template.php", + ]; + + $template_found = false; + + foreach ($checkpaths as $path) { + if (is_file($path)) { + $template_found = true; + $f = file_get_contents($path); + break; + } + } + + if(! ($template_found && $f)) + return $info; + + $f = escape_tags($f); + $r = preg_match("|/\*.*\*/|msU", $f, $m); + + if ($r) { + $ll = explode("\n", $m[0]); + foreach( $ll as $l ) { + $l = trim($l, "\t\n\r */"); + if ($l != ""){ + list($k, $v) = array_map("trim", explode(":", $l, 2)); + $k = strtolower($k); + if ($k == 'author' || $k == 'maintainer'){ + $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m); + if ($r) { + $info[$k][] = array('name' => $m[1], 'link' => $m[2]); + } else { + $info[$k][] = array('name' => $v); + } + } + else { + $info[$k] = $v; + } + } + } + } + + return $info; +} + /** * @brief Returns the theme's screenshot. * -- cgit v1.2.3 From 01b9f2dfcf3b23dcbf1dff06e7e42397840594a9 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 1 Mar 2022 10:14:05 +0000 Subject: enhanced content filters --- include/feedutils.php | 10 +++++---- include/items.php | 56 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/feedutils.php b/include/feedutils.php index b21495d72..fbd97b598 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1060,6 +1060,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { return; } + + $sys_expire = intval(get_config('system', 'default_expire_days')); $chn_expire = intval($importer['channel_expire_days']); @@ -1353,7 +1355,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } - if(! post_is_importable($datarray, $contact)) + if(! post_is_importable($importer['channel_id'], $datarray, $contact)) continue; $datarray['parent_mid'] = $datarray['mid']; @@ -1509,7 +1511,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } - if(! post_is_importable($datarray, $contact)) + if(! post_is_importable($importer['channel_id'], $datarray, $contact)) continue; logger('author: ' . print_r($author, true), LOGGER_DEBUG); @@ -1764,8 +1766,8 @@ function handle_feed($uid, $abook_id, $url) { //logger('data:' . print_r($z, true), LOGGER_DATA); if($z['success']) { - consume_feed($z['body'], $channel, $x[0], 1); - consume_feed($z['body'], $channel, $x[0], 2); + consume_feed($z['body'], $channel, $x, 1); + consume_feed($z['body'], $channel, $x, 2); return true; } diff --git a/include/items.php b/include/items.php index 0b33d876d..10a5a3385 100644 --- a/include/items.php +++ b/include/items.php @@ -10,6 +10,7 @@ use Zotlabs\Lib\MarkdownSoap; use Zotlabs\Lib\MessageFilter; use Zotlabs\Lib\ThreadListener; use Zotlabs\Lib\IConfig; +use Zotlabs\Lib\PConfig; use Zotlabs\Lib\Activity; use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Libzot; @@ -2218,9 +2219,9 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) { $arr['deny_gid'] = ((array_key_exists('deny_gid',$arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']); $arr['item_private'] = ((array_key_exists('item_private',$arr)) ? intval($arr['item_private']) : $orig[0]['item_private']); - $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : ''); - $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); - $arr['html'] = ((array_key_exists('html',$arr) && strlen($arr['html'])) ? trim($arr['html']) : ''); + $arr['title'] = ((array_key_exists('title',$arr) && $arr['title']) ? trim($arr['title']) : ''); + $arr['body'] = ((array_key_exists('body',$arr) && $arr['body']) ? trim($arr['body']) : ''); + $arr['html'] = ((array_key_exists('html',$arr) && $arr['html']) ? trim($arr['html']) : ''); $arr['attach'] = ((array_key_exists('attach',$arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']); $arr['app'] = ((array_key_exists('app',$arr)) ? notags(trim($arr['app'])) : $orig[0]['app']); @@ -3495,24 +3496,57 @@ function check_item_source($uid, $item) { return false; } -function post_is_importable($item,$abook) { - if(! $abook) - return true; +// Checks an incoming item against the per-channel and per-connection content filter. +// This implements the backend of the 'Content Filter' system app - if(($abook['abook_channel']) && (! feature_enabled($abook['abook_channel'],'connfilter'))) - return true; +function post_is_importable($channel_id, $item, $abook) { - if(! $item) + if (! $item) { return false; + } + + $incl = PConfig::get($channel_id, 'system', 'message_filter_incl', EMPTY_STR); + $excl = PConfig::get($channel_id, 'system', 'message_filter_excl', EMPTY_STR); + + if ($incl || $excl) { + $x = MessageFilter::evaluate($item, $incl, $excl); + if (! $x) { + logger('MessageFilter: channel blocked content', LOGGER_DEBUG, LOG_INFO); + return false; + } + } + + if(!feature_enabled($channel_id, 'connfilter')) { + return true; + } - if(! ($abook['abook_incl'] || $abook['abook_excl'])) + if (! $abook) { return true; + } - return MessageFilter::evaluate($item,$abook['abook_incl'],$abook['abook_excl']); + foreach ($abook as $ab) { + // check eligibility + if (intval($ab['abook_self'])) { + continue; + } + if (! ($ab['abook_incl'] || $ab['abook_excl'])) { + continue; + } + $evaluator = MessageFilter::evaluate($item, $ab['abook_incl'], $ab['abook_excl']); + // A negative assessment for any individual connections + // is an instant fail + if (! $evaluator) { + logger('MessageFilter: connection blocked content', LOGGER_DEBUG, LOG_INFO); + return false; + } + } + + return true; } + function fix_private_photos($s, $uid, $item = null, $cid = 0) { logger('fix_private_photos', LOGGER_DEBUG); -- cgit v1.2.3 From 6930c4e23b8b24f7436c0e265d751460bed9b1d2 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 1 Mar 2022 20:06:10 +0000 Subject: fix feedutils regression --- include/feedutils.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/feedutils.php b/include/feedutils.php index fbd97b598..734018922 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1355,7 +1355,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } - if(! post_is_importable($importer['channel_id'], $datarray, $contact)) + if(! post_is_importable($importer['channel_id'], $datarray, [$contact])) continue; $datarray['parent_mid'] = $datarray['mid']; @@ -1511,7 +1511,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } - if(! post_is_importable($importer['channel_id'], $datarray, $contact)) + if(! post_is_importable($importer['channel_id'], $datarray, [$contact])) continue; logger('author: ' . print_r($author, true), LOGGER_DEBUG); @@ -1766,8 +1766,8 @@ function handle_feed($uid, $abook_id, $url) { //logger('data:' . print_r($z, true), LOGGER_DATA); if($z['success']) { - consume_feed($z['body'], $channel, $x, 1); - consume_feed($z['body'], $channel, $x, 2); + consume_feed($z['body'], $channel, $x[0], 1); + consume_feed($z['body'], $channel, $x[0], 2); return true; } -- cgit v1.2.3 From c8417df6f1bf6cf8eae03a1b14e67e6c3c113afa Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 3 Mar 2022 16:52:04 +0000 Subject: fix duplicate ids in login form and move login/register buttons into the hamburger menu on small screens --- include/auth.php | 39 ++++++++++++++++++++++----------------- include/nav.php | 4 ++-- 2 files changed, 24 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/auth.php b/include/auth.php index 8eeb077b5..07b8e2971 100644 --- a/include/auth.php +++ b/include/auth.php @@ -30,9 +30,9 @@ require_once('include/security.php'); * The return array is dependent on the login mechanism. * $ret['account'] will be set if either an email or channel address validation was successful (local login). * $ret['channel'] will be set if a channel address validation was successful. - * $ret['xchan'] will be set if a guest access token validation was successful. - * Keys will exist for invalid return arrays but will be set to null. - * This function does not perform a login. It merely validates systems passwords and tokens. + * $ret['xchan'] will be set if a guest access token validation was successful. + * Keys will exist for invalid return arrays but will be set to null. + * This function does not perform a login. It merely validates systems passwords and tokens. * */ @@ -44,7 +44,7 @@ function account_verify_password($login, $pass) { $email_verify = get_config('system', 'verify_email'); $register_policy = get_config('system', 'register_policy'); - if(! $login) + if(!$login || !$pass) return null; $account = null; @@ -72,7 +72,7 @@ function account_verify_password($login, $pass) { $ret['account'] = $addon_auth['user_record']; return $ret; } - else { + else { if(! strpos($login,'@')) { $channel = channelx_by_nick($login); if(! $channel) { @@ -102,7 +102,7 @@ function account_verify_password($login, $pass) { $account = $a[0]; // Currently we only verify email address if there is an open registration policy. - // This isn't because of any policy - it's because the workflow gets too complicated if + // This isn't because of any policy - it's because the workflow gets too complicated if // you have to verify the email and then go through the account approval workflow before // letting them login. @@ -112,7 +112,7 @@ function account_verify_password($login, $pass) { } if($channel) { - // Try the authentication plugin again since weve determined we are using the channel login instead of account login + // Try the authentication plugin again since weve determined we are using the channel login instead of account login $addon_auth = [ 'username' => $account['account_email'], 'password' => trim($pass), @@ -128,7 +128,7 @@ function account_verify_password($login, $pass) { } } - if(($account['account_flags'] == ACCOUNT_OK) + if(($account['account_flags'] == ACCOUNT_OK) && (hash('whirlpool',$account['account_salt'] . $pass) === $account['account_password'])) { logger('password verified for ' . $login); $ret['account'] = $account; @@ -193,7 +193,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && $_SESSION = $_SESSION['delegate_push']; info( t('Delegation session ended.') . EOL); } - else { + else { App::$session->nuke(); info( t('Logged out.') . EOL); } @@ -280,8 +280,11 @@ else { // handle a fresh login request - if((x($_POST, 'password')) && strlen($_POST['password'])) - $encrypted = hash('whirlpool', trim($_POST['password'])); + $password = $_POST['main_login_password'] ?? $_POST['modal_login_password']; + $username = $_POST['main_login_username'] ?? $_POST['modal_login_username']; + + if($password) + $encrypted = hash('whirlpool', trim($password)); if((x($_POST, 'auth-params')) && $_POST['auth-params'] === 'login') { @@ -289,10 +292,10 @@ else { $account = null; $channel = null; - $verify = account_verify_password($_POST['username'], $_POST['password']); + $verify = account_verify_password($username, $password); if($verify && array_key_exists('reason',$verify) && $verify['reason'] === 'unvalidated') { notice( t('Email validation is incomplete. Please check your email.')); - goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($_POST['username']))))); + goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($username))))); } elseif($verify) { $atoken = $verify['xchan']; @@ -311,8 +314,8 @@ else { } if(! ($account || $atoken)) { - $error = 'authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']; - logger($error); + $error = 'authenticate: failed login attempt: ' . notags(trim($username)) . ' from IP ' . $_SERVER['REMOTE_ADDR']; + logger($error); // Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention $authlog = get_config('system', 'authlog'); if ($authlog) @@ -334,7 +337,9 @@ else { // (i.e. expire when the browser is closed), even when there's a time expiration // on the cookie - if(($_POST['remember_me']) || ($_POST['remember'])) { + $remember = $_POST['main_login_remember'] ?? $_POST['modal_login_remember']; + + if($remember) { $_SESSION['remember_me'] = 1; App::$session->new_cookie(31449600); // one year } @@ -360,7 +365,7 @@ else { * and returns the corresponding channel_id. * * @fixme How do we prevent that an OpenID identity is used more than once? - * + * * @param string $authid * The given openid_identity * @return int|bool diff --git a/include/nav.php b/include/nav.php index 9278c1587..b9b24e34c 100644 --- a/include/nav.php +++ b/include/nav.php @@ -118,11 +118,11 @@ function nav($template = 'default') { else { if (!get_account_id()) { if (App::$module === 'channel') { - $nav['login'] = login(true, 'main-login', false, false); + $nav['login'] = login(true, 'modal_login', false, false); $nav['loginmenu'][] = ['login', t('Login'), '', t('Sign in'), '']; } else { - $nav['login'] = login(true, 'main-login', false, false); + $nav['login'] = login(true, 'modal_login', false, false); $nav['loginmenu'][] = ['login', t('Login'), '', t('Sign in'), 'login_nav_btn']; App::$page['content'] .= replace_macros(get_markup_template('nav_login.tpl'), -- cgit v1.2.3 From 65ed3818ec0b25d2f2093a08935003a7a07ddb3f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Thu, 3 Mar 2022 19:29:56 +0100 Subject: Use correct base url for stylesheets and js. Use z_root instead of script_path when formatting stylesheet and javascript links for the head section. script_path does not preserve information about the port if the site uses a nonstandard port. --- include/plugin.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/plugin.php b/include/plugin.php index 25fa22e10..f0ae1ecb1 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -941,9 +941,7 @@ function head_get_links() { function format_css_if_exists($source) { - // script_path() returns https://yoursite.tld - - $path_prefix = script_path(); + $path_prefix = z_root(); $script = $source[0]; @@ -1054,7 +1052,7 @@ function head_get_main_js() { } function format_js_if_exists($source) { - $path_prefix = script_path(); + $path_prefix = z_root(); if(strpos($source,'/') !== false) { // The source is a known path on the system -- cgit v1.2.3 From 34ffff3947b8e89a667367277f0fde9c626fd143 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Thu, 3 Mar 2022 19:50:07 +0100 Subject: Remove now unused function script_path. --- include/plugin.php | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'include') diff --git a/include/plugin.php b/include/plugin.php index f0ae1ecb1..f9cee7ed6 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -963,44 +963,6 @@ function format_css_if_exists($source) { } } -/** - * This basically calculates the baseurl. We have other functions to do that, but - * there was an issue with script paths and mixed-content whose details are arcane - * and perhaps lost in the message archives. The short answer is that we're ignoring - * the URL which we are "supposed" to use, and generating script paths relative to - * the URL which we are currently using; in order to ensure they are found and aren't - * blocked due to mixed content issues. - * - * @return string - */ -function script_path() { - if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) - $scheme = 'https'; - elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) - $scheme = 'https'; - elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') - $scheme = 'https'; - else - $scheme = 'http'; - - // Some proxy setups may require using http_host - - if(isset(App::$config['system']['script_path_use_http_host']) && intval(App::$config['system']['script_path_use_http_host'])) - $server_var = 'HTTP_HOST'; - else - $server_var = 'SERVER_NAME'; - - - if(x($_SERVER,$server_var)) { - $hostname = $_SERVER[$server_var]; - } - else { - return z_root(); - } - - return $scheme . '://' . $hostname; -} - function head_add_js($src, $priority = 0) { if(isset(App::$js_sources[$priority]) && !is_array(App::$js_sources[$priority])) App::$js_sources[$priority] = []; -- cgit v1.2.3 From db14dbacc9290f63d12804398924af55c62eee1d Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 4 Mar 2022 15:05:58 +0000 Subject: streamline event activity handling --- include/event.php | 178 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 50 deletions(-) (limited to 'include') diff --git a/include/event.php b/include/event.php index 440f559da..fbfa4c6d2 100644 --- a/include/event.php +++ b/include/event.php @@ -70,8 +70,83 @@ function format_event_html($ev) { } function format_event_obj($jobject) { + $event = []; + $object = json_decode($jobject, true); + +/******* + This is our encoded format + + $x = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $r[0]['resource_id'], + 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($r[0],false), + ]; + if(! $arr['nofinish']) { + $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00')); + } + +******/ + + if (is_array($object) && (array_key_exists('summary', $object) || array_key_exists('name', $object))) { + + $dtend = ((array_key_exists('endTime', $object)) ? $object['endTime'] : NULL_DATE); + $title = ((isset($object['summary']) && $object['summary']) ? zidify_links(smilies(bbcode($object['summary']))) : $object['name']); + + // mobilizon sets a timezone in the object + // we will assume that events with an timezone should be adjusted + $tz = $object['timezone'] ?? ''; + $adjust = ((strpos($object['startTime'], 'Z') !== false) || $tz); + + $allday = (($adjust) ? false : true); + + $dtstart = new DateTime($object['startTime']); + $dtend_obj = new DateTime($dtend); + $dtdiff = $dtstart->diff($dtend_obj); + + if($allday && ($dtdiff->days < 2)) + $oneday = true; + + if($allday && !$oneday) { + // Subtract one day from the end date so we can use the "first day - last day" format for display. + $dtend_obj->modify('-1 day'); + $dtend = datetime_convert('UTC', 'UTC', $dtend_obj->format('Y-m-d H:i:s')); + } + + $bd_format = (($allday) ? t('l F d, Y') : t('l F d, Y \@ g:i A')); // Friday January 18, 2011 @ 8:01 AM or Friday January 18, 2011 for allday events + + $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'), array( + '$title' => $title, + '$dtstart_label' => t('Start:'), + '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['startTime'], ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtstart_dt' => (($adjust) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['startTime'], $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $object['startTime'], $bd_format))), + '$finish' => ((array_key_exists('endTime', $object)) ? true : false), + '$dtend_label' => t('End:'), + '$dtend_title' => datetime_convert('UTC', 'UTC', $dtend, ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtend_dt' => (($adjust) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $dtend, $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $dtend, $bd_format))), + '$allday' => $allday, + '$oneday' => $oneday, + '$event_tz' => ['label' => t('Timezone'), 'value' => (($tz === date_default_timezone_get()) ? '' : $tz)] + )); + + $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'), array( + '$description' => $object['content'], + '$location_label' => t('Location:'), + '$location' => ((array_path_exists('location/content', $object)) ? zidify_links(smilies(bbcode($object['location']['content']))) : EMPTY_STR) + )); + } + + return $event; +/* + $event = []; $object = json_decode($jobject,true); $event_tz = ''; @@ -136,6 +211,7 @@ function format_event_obj($jobject) { )); return $event; +*/ } function ical_wrapper($ev) { @@ -1122,34 +1198,35 @@ function event_store_item($arr, $event) { if($r) { - set_iconfig($r[0]['id'], 'event', 'timezone', $arr['timezone'], true); - xchan_query($r); - $r = fetch_post_tags($r,true); - - $object = json_encode(array( - 'type' => ACTIVITY_OBJ_EVENT, - 'id' => z_root() . '/event/' . $r[0]['resource_id'], - 'title' => $arr['summary'], - 'timezone' => $arr['timezone'], - 'dtstart' => $arr['dtstart'], - 'dtend' => $arr['dtend'], - 'nofinish' => $arr['nofinish'], - 'description' => $arr['description'], - 'location' => $arr['location'], - 'adjust' => $arr['adjust'], - 'content' => format_event_bbcode($arr), + //set_iconfig($r[0]['id'], 'event', 'timezone', $arr['timezone'], true); + //xchan_query($r); + //$r = fetch_post_tags($r,true); + + $x = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $r[0]['resource_id'], + 'name' => $arr['summary'], +// 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($r[0], false), 'attachment' => Activity::encode_attachment($r[0]), - 'author' => array( - 'name' => $r[0]['author']['xchan_name'], - 'address' => $r[0]['author']['xchan_addr'], - 'guid' => $r[0]['author']['xchan_guid'], - 'guid_sig' => $r[0]['author']['xchan_guid_sig'], - 'link' => array( - array('rel' => 'alternate', 'type' => 'text/html', 'href' => $r[0]['author']['xchan_url']), - array('rel' => 'photo', 'type' => $r[0]['author']['xchan_photo_mimetype'], 'href' => $r[0]['author']['xchan_photo_m']) - ), - ), - )); + 'tag' => Activity::encode_taxonomy($r[0]) + ]; + + if (! $arr['nofinish']) { + $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00')); + } + + if ($event['event_repeat']) { + $x['eventRepeat'] = $event['event_repeat']; + } + + $object = json_encode($x); $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); @@ -1285,29 +1362,30 @@ function event_store_item($arr, $event) { dbesc($arr['event_xchan']) ); if($x) { - $item_arr['obj'] = json_encode(array( - 'type' => ACTIVITY_OBJ_EVENT, - 'id' => z_root() . '/event/' . $event['event_hash'], - 'title' => $arr['summary'], - 'timezone' => $arr['timezone'], - 'dtstart' => $arr['dtstart'], - 'dtend' => $arr['dtend'], - 'nofinish' => $arr['nofinish'], - 'description' => $arr['description'], - 'location' => $arr['location'], - 'adjust' => $arr['adjust'], - 'content' => format_event_bbcode($arr), - 'attachment' => Activity::encode_attachment($item_arr), - 'author' => array( - 'name' => $x[0]['xchan_name'], - 'address' => $x[0]['xchan_addr'], - 'guid' => $x[0]['xchan_guid'], - 'guid_sig' => $x[0]['xchan_guid_sig'], - 'link' => array( - array('rel' => 'alternate', 'type' => 'text/html', 'href' => $x[0]['xchan_url']), - array('rel' => 'photo', 'type' => $x[0]['xchan_photo_mimetype'], 'href' => $x[0]['xchan_photo_m'])), - ), - )); + $y = [ + 'type' => 'Event', + 'id' => z_root() . '/event/' . $event['event_hash'], + 'name' => $arr['summary'], +// 'summary' => bbcode($arr['summary']), + // RFC3339 Section 4.3 + 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($arr['description']), + 'location' => [ 'type' => 'Place', 'content' => bbcode($arr['location']) ], + 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ], + 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], + 'actor' => Activity::encode_person($z, false), + 'attachment' => Activity::encode_attachment($item_arr), + 'tag' => Activity::encode_taxonomy($item_arr) + ]; + + if (! $arr['nofinish']) { + $y['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00')); + } + if ($arr['event_repeat']) { + $y['eventRepeat'] = $arr['event_repeat']; + } + + $item_arr['obj'] = json_encode($y); } // propagate the event resource_id so that posts containing it are easily searchable in downstream copies -- cgit v1.2.3 From 37f56e1efd9d412d1e84d699b40746b52a0a4fc2 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 4 Mar 2022 18:43:21 +0000 Subject: event fixes --- include/event.php | 14 +++++++++----- include/html2bbcode.php | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/event.php b/include/event.php index fbfa4c6d2..c15c44cc0 100644 --- a/include/event.php +++ b/include/event.php @@ -73,7 +73,7 @@ function format_event_obj($jobject) { $event = []; $object = json_decode($jobject, true); - +hz_syslog(print_r($object,true)); /******* This is our encoded format @@ -103,7 +103,11 @@ function format_event_obj($jobject) { // mobilizon sets a timezone in the object // we will assume that events with an timezone should be adjusted $tz = $object['timezone'] ?? ''; - $adjust = ((strpos($object['startTime'], 'Z') !== false) || $tz); + + // friendica has its own flag for adjust + $dfrn_adjust = $object['dfrn:adjust'] ?? ''; + + $adjust = ((strpos($object['startTime'], 'Z') !== false) || $tz || $dfrn_adjust); $allday = (($adjust) ? false : true); @@ -140,7 +144,7 @@ function format_event_obj($jobject) { $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'), array( '$description' => $object['content'], '$location_label' => t('Location:'), - '$location' => ((array_path_exists('location/content', $object)) ? zidify_links(smilies(bbcode($object['location']['content']))) : EMPTY_STR) + '$location' => ((array_path_exists('location/name', $object)) ? zidify_links(smilies(bbcode($object['location']['name']))) : EMPTY_STR) )); } @@ -1210,7 +1214,7 @@ function event_store_item($arr, $event) { // RFC3339 Section 4.3 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), 'content' => bbcode($arr['description']), - 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ], + 'location' => [ 'type' => 'Place', 'name' => $arr['location'] ], 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ], 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], 'actor' => Activity::encode_person($r[0], false), @@ -1370,7 +1374,7 @@ function event_store_item($arr, $event) { // RFC3339 Section 4.3 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')), 'content' => bbcode($arr['description']), - 'location' => [ 'type' => 'Place', 'content' => bbcode($arr['location']) ], + 'location' => [ 'type' => 'Place', 'name' => bbcode($arr['location']) ], 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ], 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ], 'actor' => Activity::encode_person($z, false), diff --git a/include/html2bbcode.php b/include/html2bbcode.php index 173ea63bd..cc67a5666 100644 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -87,7 +87,7 @@ function deletenode(&$doc, $node) function html2bbcode($message) { - if(!$message) + if(!is_string($message) && !$message) return; $message = str_replace("\r", "", $message); -- cgit v1.2.3 From 740fa058aa770cce9923ff2e13fb277636e60292 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 4 Mar 2022 18:43:54 +0000 Subject: remove logging --- include/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/event.php b/include/event.php index c15c44cc0..3d3dda035 100644 --- a/include/event.php +++ b/include/event.php @@ -73,7 +73,7 @@ function format_event_obj($jobject) { $event = []; $object = json_decode($jobject, true); -hz_syslog(print_r($object,true)); + /******* This is our encoded format -- cgit v1.2.3 From 8c19ab8f9f47a522ad2b929495f3b5821efd2f34 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sun, 20 Mar 2022 12:57:42 +0100 Subject: Add helper to escape URLs. The escaping makes the URL safe for display and for use in HTML element attributes (such as href="..." etc), but does not guarantee that the URL itself is valid after conversion. This should be good enough for mitigating XSS issues caused by injecting html or javascript into a URL. Also probably good enough for _most_ normal URLs, but there may be devils hidden in the details somewhere. --- include/text.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/text.php b/include/text.php index 9a2ca1af4..0c806d009 100644 --- a/include/text.php +++ b/include/text.php @@ -114,6 +114,18 @@ function escape_tags($string) { return (htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false)); } +/** + * Escape URL's so they're safe for use in HTML and in HTML element attributes. + */ +function escape_url($input) { + if (empty($input)) { + return EMPTY_STR; + } + + // This is a bit crude but seems to do the trick for now. It makes no + // guarantees that the URL is valid for use after escaping. + return htmlspecialchars($input, ENT_HTML5 | ENT_QUOTES); +} function z_input_filter($s,$type = 'text/bbcode',$allow_code = false) { -- cgit v1.2.3 From b02f6a1dae3e3fae4af4b24e65256cdf653b2515 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sun, 20 Mar 2022 14:35:25 +0100 Subject: Add function is_local_url() to check if url is local. --- include/network.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/network.php b/include/network.php index fa408e602..a236a6f8e 100644 --- a/include/network.php +++ b/include/network.php @@ -559,6 +559,14 @@ function z_dns_check($h,$check_mx = 0) { return((@dns_get_record($h,$opts) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); } +function is_local_url($url) { + if (str_starts_with($url, z_root()) || str_starts_with($url, '/')) { + return true; + } + + return false; +} + /** * @brief Validates a given URL. * -- cgit v1.2.3 From 62ac0ff21ecf8292e55722cdcdce08fa8bbdb87d Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 23 Mar 2022 19:01:42 +0000 Subject: streamline comment policy with downstream --- include/items.php | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index 10a5a3385..8a2faa623 100644 --- a/include/items.php +++ b/include/items.php @@ -1073,21 +1073,6 @@ function encode_item($item,$mirror = false,$zap_compat = false) { $x['type'] = 'activity'; $x['encoding'] = 'zot'; - $r = q("select channel_id from channel where channel_id = %d limit 1", - intval($item['uid']) - ); - - if($r) - $comment_scope = PermissionLimits::Get($item['uid'],'post_comments'); - else - $comment_scope = 0; - - $scope = $item['public_policy']; - if(! $scope) - $scope = 'public'; - - $c_scope = map_scope($comment_scope); - $key = get_config('system','prvkey'); // If we're trying to backup an item so that it's recoverable or for export/imprt, @@ -1180,10 +1165,7 @@ function encode_item($item,$mirror = false,$zap_compat = false) { $x['public_scope'] = $scope; - if($item['item_nocomment']) - $x['comment_scope'] = 'none'; - else - $x['comment_scope'] = $c_scope; + $x['comment_scope'] = $item['comment_policy']; if(! empty($item['term'])) $x['tags'] = encode_item_terms($item['term'],$mirror); -- cgit v1.2.3