diff options
Diffstat (limited to 'include')
33 files changed, 889 insertions, 696 deletions
diff --git a/include/account.php b/include/account.php index bea84cea7..fefe61d15 100644 --- a/include/account.php +++ b/include/account.php @@ -4,6 +4,8 @@ * @brief Somme account related functions. */ +use Zotlabs\Lib\Crypto; + require_once('include/config.php'); require_once('include/network.php'); require_once('include/plugin.php'); @@ -26,8 +28,8 @@ function check_account_email($email) { $email = punify($email); $result = array('error' => false, 'message' => ''); - // Caution: empty email isn't counted as an error in this function. - // Check for empty value separately. + // Caution: empty email isn't counted as an error in this function. + // Check for empty value separately. if(! strlen($email)) return $result; @@ -36,7 +38,7 @@ function check_account_email($email) { $result['message'] .= t('Not a valid email address') . EOL; elseif(! allowed_email($email)) $result['message'] = t('Your email domain is not among those allowed on this site'); - else { + else { $r = q("select account_email from account where account_email = '%s' limit 1", dbesc($email) ); @@ -175,7 +177,7 @@ function create_account($arr) { // Ensure that there is a host keypair. if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { - $hostkey = new_keypair(4096); + $hostkey = Crypto::new_keypair(4096); set_config('system', 'pubkey', $hostkey['pubkey']); set_config('system', 'prvkey', $hostkey['prvkey']); } @@ -306,8 +308,8 @@ function verify_email_address($arr) { ); $res = z_mail( - [ - 'toEmail' => $arr['email'], + [ + 'toEmail' => $arr['email'], 'messageSubject' => sprintf( t('Registration confirmation for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, ] @@ -375,8 +377,8 @@ function send_reg_approval_email($arr) { )); $res = z_mail( - [ - 'toEmail' => $admin['email'], + [ + 'toEmail' => $admin['email'], 'messageSubject' => sprintf( t('Registration request at %s'), get_config('system','sitename')), 'textVersion' => $email_msg, ] @@ -403,7 +405,7 @@ function send_register_success_email($email,$password) { )); $res = z_mail( - [ + [ 'toEmail' => $email, 'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, @@ -446,7 +448,7 @@ function account_allow($hash) { intval(ACCOUNT_BLOCKED), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_PENDING), intval(ACCOUNT_PENDING), @@ -466,7 +468,7 @@ function account_allow($hash) { )); $res = z_mail( - [ + [ 'toEmail' => $account[0]['account_email'], 'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, @@ -556,13 +558,13 @@ function account_approve($hash) { intval(ACCOUNT_BLOCKED), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_PENDING), intval(ACCOUNT_PENDING), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_UNVERIFIED), intval(ACCOUNT_UNVERIFIED), @@ -583,7 +585,7 @@ function account_approve($hash) { else { $_SESSION['login_return_url'] = 'new_channel'; authenticate_success($account[0],null,true,true,false,true); - } + } return true; } @@ -592,19 +594,19 @@ function account_approve($hash) { /** * @brief Checks for accounts that have past their expiration date. * - * If the account has a service class which is not the site default, + * If the account has a service class which is not the site default, * the service class is reset to the site default and expiration reset to never. * If the account has no service class it is expired and subsequently disabled. * called from include/poller.php as a scheduled task. * * Reclaiming resources which are no longer within the service class limits is - * not the job of this function, but this can be implemented by plugin if desired. - * Default behaviour is to stop allowing additional resources to be consumed. + * not the job of this function, but this can be implemented by plugin if desired. + * Default behaviour is to stop allowing additional resources to be consumed. */ function downgrade_accounts() { - $r = q("select * from account where not ( account_flags & %d ) > 0 - and account_expires > '%s' + $r = q("select * from account where not ( account_flags & %d ) > 0 + and account_expires > '%s' and account_expires < %s ", intval(ACCOUNT_EXPIRED), dbesc(NULL_DATE), @@ -744,8 +746,8 @@ function service_class_fetch($uid, $property) { $service_class = App::$account['account_service_class']; } else { - $r = q("select account_service_class as service_class - from channel c, account a + $r = q("select account_service_class as service_class + from channel c, account a where c.channel_account_id=a.account_id and c.channel_id= %d limit 1", intval($uid) ); @@ -778,6 +780,8 @@ function service_class_fetch($uid, $property) { */ function account_service_class_fetch($aid, $property) { + $service_class = null; + $r = q("select account_service_class as service_class from account where account_id = %d limit 1", intval($aid) ); @@ -785,7 +789,7 @@ function account_service_class_fetch($aid, $property) { $service_class = $r[0]['service_class']; } - if(! x($service_class)) + if(! isset($service_class)) return false; // everything is allowed $arr = get_config('service_class', $service_class); diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 8da46649c..f158a439b 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -63,6 +63,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $single_group = false; $just_me = false; $custom = false; + $groups = ''; if($allow_cid || $allow_gid || $deny_gid || $deny_cid) { $has_acl = true; @@ -112,11 +113,11 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $forums_count = 0; $forum_otions = ''; foreach($forums as $f) { - if($f['no_post_perms']) + if(isset($f['no_post_perms'])) continue; - $private = (($f['private_forum']) ? ' (' . t('Private Forum') . ')' : ''); - $selected = (($single_group && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : ''); + $private = ((isset($f['private_forum'])) ? ' (' . t('Private Forum') . ')' : ''); + $selected = (($single_group && isset($f['hash'], $allow_cid[0]) && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : ''); $forum_otions .= '<option id="^' . $f['abook_id'] . '" value="^' . $f['xchan_hash'] . '"' . $selected . '>' . $f['xchan_name'] . $private . '</option>' . "\r\n"; $forums_count++; } @@ -133,7 +134,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $o = replace_macros($tpl, array( '$showall' => $showall_caption, '$onlyme' => t('Only me'), - '$groups' => $groups, + '$groups' => $groups, '$public_selected' => (($has_acl) ? false : true), '$justme_selected' => $just_me, '$custom_selected' => $custom, diff --git a/include/api_zot.php b/include/api_zot.php index 8f621d998..9beaaa19c 100644 --- a/include/api_zot.php +++ b/include/api_zot.php @@ -87,12 +87,13 @@ return false; } $sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : ''); + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); if($_REQUEST['posts']) { $sections = get_default_export_sections(); $sections[] = 'items'; } - json_return_and_die(identity_basic_export(api_user(),$sections)); + json_return_and_die(identity_basic_export(api_user(),$sections,$codebase)); } function api_item_export_page($type) { @@ -111,8 +112,9 @@ $start = datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['since']); } $finish = datetime_convert(date_default_timezone_get(),'UTC', (($_REQUEST['until']) ? $_REQUEST['until'] : 'now')); + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); - json_return_and_die(channel_export_items_page(api_user(),$start,$finish,$page,$records)); + json_return_and_die(channel_export_items_page(api_user(),$start,$finish,$page,$records,$codebase)); } @@ -289,10 +291,11 @@ return false; if(! $_REQUEST['file_id']) return false; + $codebase = ((isset($_REQUEST['zap_compat']) && $_REQUEST['zap_compat']) ? true : false); $channel = channelx_by_n(api_user()); - $ret = attach_export_data($channel,$_REQUEST['file_id']); + $ret = attach_export_data($channel,$_REQUEST['file_id'],false,$codebase); if($ret) { json_return_and_die($ret); diff --git a/include/attach.php b/include/attach.php index 9ba6be109..db7046ef0 100644 --- a/include/attach.php +++ b/include/attach.php @@ -2339,7 +2339,7 @@ function filepath_macro($s) { } -function attach_export_data($channel, $resource_id, $deleted = false) { +function attach_export_data($channel, $resource_id, $deleted = false, $zap_compat = false) { $ret = array(); @@ -2429,7 +2429,7 @@ function attach_export_data($channel, $resource_id, $deleted = false) { xchan_query($items); $items = fetch_post_tags($items,true); foreach($items as $rr) - $ret['item'][] = encode_item($rr,true); + $ret['item'][] = encode_item($rr,true,$zap_compat); } } } diff --git a/include/bbcode.php b/include/bbcode.php index e1a5c7e47..388a828c4 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -80,7 +80,7 @@ function tryoembed($match) { return $match[0]; $html = oembed_format_object($o); - return $html; + return $html; } @@ -92,7 +92,7 @@ function nakedoembed($match) { // this function no longer performs oembed on naked links // because they author may have created naked links intentionally. // Now it just strips zids on naked links. - + return str_replace($url,$strip_url,$match[0]); } @@ -152,6 +152,18 @@ function bb_spacefy($st) { } // The previously spacefied [noparse][ i ]italic[ /i ][/noparse], +// now turns back returning [noparse][i]italic[/i][/noparse] +function bb_unspacefy($st) { + $whole_match = $st[0]; + $captured = $st[1]; + $spacefied = preg_replace("/\[ (.*?) \]/", "[$1]", $captured); + $new_str = str_replace($captured, $spacefied, $whole_match); + + return $new_str; +} + + +// The previously spacefied [noparse][ i ]italic[ /i ][/noparse], // now turns back and the [noparse] tags are trimmed // returning [i]italic[/i] @@ -272,6 +284,26 @@ function bb_parse_crypt($match) { return $Text; } +/** + * @brief Returns raw base64 encoded crypt content. + * + * @param array $match + * @return string + */ +function bb_parse_b64_crypt($match) { + + if(empty($match[2])) + return; + + $r .= '----- ENCRYPTED CONTENT -----' . PHP_EOL; + $r .= $match[2] . PHP_EOL; + $r .= '----- END ENCRYPTED CONTENT -----'; + + return $r; + +} + + function bb_parse_app($match) { $app = Zotlabs\Lib\Apps::app_decode($match[1]); @@ -283,7 +315,7 @@ function bb_svg($match) { $params = str_replace(['<br>', '"'], [ '', '"'],$match[1]); $Text = str_replace([ '[',']' ], [ '<','>' ], $match[2]); - + $output = '<svg' . (($params) ? $params : ' width="100%" height="480" ') . '>' . str_replace(['<br>', '"', ' '], [ '', '"', ' '],$Text) . '</svg>'; $purify = new SvgSanitizer(); @@ -641,24 +673,24 @@ function bb_definitionList($match) { // The bbcode transformation will be: // [*=term-text] description-text => </dd> <dt>term-text<dt><dd> description-text - // then after all replacements have been made, the extra </dd> at the start of the + // then after all replacements have been made, the extra </dd> at the start of the // first line can be removed. HTML5 allows the tag to be missing from the end of the last line. // Using '(?<!\\\)' to allow backslash-escaped closing braces to appear in the term-text. $closeDescriptionTag = "</dd>\n"; $eatLeadingSpaces = '(?: |[ \t])*'; // prevent spaces infront of [*= from adding another line to the previous element $listElements = preg_replace('/^(\n|<br \/>)/', '', $match[2]); // ltrim the first newline $listElements = preg_replace( - '/' . $eatLeadingSpaces . '\[\*=([[:print:]]*?)(?<!\\\)\]/uism', - $closeDescriptionTag . '<dt>$1</dt><dd>', + '/' . $eatLeadingSpaces . '\[\*=([[:print:]]*?)(?<!\\\)\]/uism', + $closeDescriptionTag . '<dt>$1</dt><dd>', $listElements ); // Unescape any \] inside the <dt> tags $listElements = preg_replace_callback('/<dt>(.*?)<\/dt>/ism', 'bb_definitionList_unescapeBraces', $listElements); - + // Remove the extra </dd> at the start of the string, if there is one. $firstOpenTag = strpos($listElements, '<dd>'); $firstCloseTag = strpos($listElements, $closeDescriptionTag); - if ($firstCloseTag !== false && ($firstOpenTag === false || ($firstCloseTag < $firstOpenTag))) { + if ($firstCloseTag !== false && ($firstOpenTag === false || ($firstCloseTag < $firstOpenTag))) { $listElements = preg_replace( '/<\/dd>/ism', '', $listElements, 1); } @@ -802,7 +834,7 @@ function bb_imgoptions($match) { // $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); // alt text cannot contain ']' - + // [img|zmg=wwwxhhh float=left|right alt=alt text]url[/img|zmg] $local_match = null; @@ -818,7 +850,7 @@ function bb_imgoptions($match) { if ($x) { $alt = $matches[1]; } - + $x = preg_match("/alt=\"\;(.*?)\"\;/ism", $attributes, $matches); if ($x) { $alt = $matches[1]; @@ -828,7 +860,7 @@ function bb_imgoptions($match) { if ($x) { $width = $matches[1]; } - + $x = preg_match("/width=\"\;(.*?)\"\;/ism", $attributes, $matches); if ($x) { $width = $matches[1]; @@ -838,7 +870,7 @@ function bb_imgoptions($match) { if ($x) { $height = $matches[1]; } - + $x = preg_match("/height=\"\;(.*?)\"\;/ism", $attributes, $matches); if ($x) { $height = $matches[1]; @@ -848,14 +880,14 @@ function bb_imgoptions($match) { if ($x) { $style = $matches[1]; } - + $x = preg_match("/style=\"\;(.*?)\"\;/ism", $attributes, $matches); if ($x) { $style = $matches[1]; } // legacy img options - + if ($match[2] === '=') { // pull out (optional) legacy size declarations first if (preg_match("/([0-9]*)x([0-9]*)/ism",$match[3],$local_match)) { @@ -873,16 +905,16 @@ function bb_imgoptions($match) { $float = 'right'; $match[3] = substr($match[3],$n + 11); } - + // finally alt text which extends to the close of the tag if ((! $alt) && ($n = strpos($match[3],'alt=') !== false)) { $alt = substr($match[3],$n + 4); } // now assemble the resulting img tag from these components - + $output = '<img ' . (($match[1] === 'z') ? 'class="zrl" loading="eager"' : '') . ' '; - + if ($width) { $style .= 'width: 100%; max-width: ' . $width . 'px; '; } @@ -892,13 +924,13 @@ function bb_imgoptions($match) { if ($float) { $style .= 'float: ' . $float . '; '; } - + $output .= (($style) ? 'style="' . $style . '" ' : '') . 'alt="' . htmlentities(($alt) ? $alt : t('Image/photo'),ENT_COMPAT,'UTF-8') . '" '; $output .= 'src="' . $match[4] . '" >'; - + return $output; - + } function bb_code_protect($s) { @@ -914,14 +946,14 @@ function bb_code_unprotect_sub($match) { } function bb_code($match) { - if(strpos($match[0], "<br />")) + if(strpos($match[0], PHP_EOL)) return '<pre><code>' . bb_code_protect(trim($match[1])) . '</code></pre>'; else return '<code class="inline-code">' . bb_code_protect(trim($match[1])) . '</code>'; } function bb_code_options($match) { - if(strpos($match[0], "<br />")) { + if(strpos($match[0], PHP_EOL)) { $class = ""; $pre = true; } else { @@ -935,7 +967,7 @@ function bb_code_options($match) { } if($pre) { return '<pre><code class="'. $class .'" style="'. $style .'">' . bb_code_protect(trim($match[2])) . '</code></pre>'; - } else { + } else { return '<code class="'. $class .'" style="'. $style .'">' . bb_code_protect(trim($match[2])) . '</code>'; } } @@ -949,7 +981,7 @@ function bb_fixtable_lf($match) { // remove extraneous whitespace between table element tags since newlines will all // be converted to '<br />' and turn your neatly crafted tables into a whole lot of // empty space. - + $x = preg_replace("/\]\s+\[/",'][',$match[1]); return '[table]' . $x . '[/table]'; @@ -991,7 +1023,7 @@ function parseIdentityAwareHTML($Text) { } if (strpos($Text,'[pre]') !== false) { $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); - } + } // process [observer] tags before we do anything else because we might // be stripping away stuff that then doesn't need to be worked on anymore @@ -1012,7 +1044,7 @@ function parseIdentityAwareHTML($Text) { $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text); } - } + } // replace [observer.baseurl] if ($observer) { $s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">'; @@ -1033,11 +1065,11 @@ function parseIdentityAwareHTML($Text) { $Text = str_replace('[observer.webname]','',$Text); $Text = str_replace('[observer.photo]','', $Text); } - + $Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text); - - // Unhide all [noparse] contained bbtags unspacefying them + + // Unhide all [noparse] contained bbtags unspacefying them // and triming the [noparse] tag. if (strpos($Text,'[noparse]') !== false) { $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); @@ -1077,6 +1109,9 @@ function bbcode($Text, $options = []) { if (strpos($Text,'[pre]') !== false) { $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); } + if (strpos($Text,'[summary]') !== false) { + $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_spacefy',$Text); + } $Text = bb_format_attachdata($Text); @@ -1153,23 +1188,8 @@ function bbcode($Text, $options = []) { $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text); - // Convert new line chars to html <br /> tags - - // nlbr seems to be hopelessly messed up - // $Text = nl2br($Text); - - // We'll emulate it. - - $Text = str_replace("\r\n", "\n", $Text); - $Text = str_replace(array("\r", "\n"), array('<br />', '<br />'), $Text); - - if ($preserve_nl) - $Text = str_replace(array("\n", "\r"), array('', ''), $Text); - - $Text = str_replace(array("\t", " "), array(" ", " "), $Text); - // Check for [code] text if (strpos($Text,'[code]') !== false) { $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text); @@ -1219,9 +1239,12 @@ function bbcode($Text, $options = []) { $Text = preg_replace("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $Text); } - if (strpos($Text,'[/share]') !== false) { + $count = 0; + while (strpos($Text,'[/share]') !== false && $count < 10) { $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text); + $count ++; } + if($tryoembed) { if (strpos($Text,'[/url]') !== false) { $Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text); @@ -1266,7 +1289,7 @@ function bbcode($Text, $options = []) { $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text); } } - + // Check for bold text if (strpos($Text,'[b]') !== false) { $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $Text); @@ -1392,8 +1415,8 @@ function bbcode($Text, $options = []) { $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $Text); // [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large - // etc. style may be specified for the "terms" in the definition list. The quotation marks - // are also optional. The regex looks intimidating, but breaks down as: + // etc. style may be specified for the "terms" in the definition list. The quotation marks + // are also optional. The regex looks intimidating, but breaks down as: // "[dl" <optional-whitespace> <optional-termStyles> "]" <matchGroup2> "[/dl]" // where optional-termStyles are: "terms=" <optional-quote> <matchGroup1> <optional-quote> $Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:"|")?([a-zA-Z]+)(?:"|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text); @@ -1430,11 +1453,6 @@ function bbcode($Text, $options = []) { $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $Text); } - - if(strpos($Text,'[/summary]') !== false) { - $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", 'bb_summary', $Text); - } - // Check for [spoiler] text $endlessloop = 0; while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) { @@ -1522,18 +1540,18 @@ function bbcode($Text, $options = []) { // html5 video and audio if (strpos($Text,'[/video]') !== false) { - $Text = preg_replace_callback("/\[video (.*?)\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/video\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[video\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/video\]/ism", 'tryzrlvideo', $Text); + $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/audio]') !== false) { - $Text = preg_replace_callback("/\[audio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\[\/audio\]/ism", 'tryzrlaudio', $Text); + $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text); } if (strpos($Text,'[/zvideo]') !== false) { - $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/zvideo\]/ism", 'videowithopts', $Text); - $Text = preg_replace_callback("/\[zvideo\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\[\/zvideo\]/ism", 'tryzrlvideo', $Text); + $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text); + $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/zaudio]') !== false) { - $Text = preg_replace_callback("/\[zaudio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\[\/zaudio\]/ism", 'tryzrlaudio', $Text); + $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text); } // SVG stuff @@ -1579,7 +1597,7 @@ function bbcode($Text, $options = []) { // If we found an event earlier, strip out all the event code and replace with a reformatted version. // Replace the event-start section with the entire formatted event. The other bbcode is stripped. - // Summary (e.g. title) is required, earlier revisions only required description (in addition to + // Summary (e.g. title) is required, earlier revisions only required description (in addition to // start which is always required). Allow desc with a missing summary for compatibility. if ((x($ev,'desc') || x($ev,'summary')) && x($ev,'dtstart')) { @@ -1588,7 +1606,7 @@ function bbcode($Text, $options = []) { $sub = str_replace('$',"\0",$sub); - $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text); + $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text); $Text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$Text); $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text); @@ -1603,7 +1621,14 @@ function bbcode($Text, $options = []) { } - // Unhide all [noparse] contained bbtags unspacefying them + if (strpos($Text,'[summary]') !== false) { + $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_unspacefy',$Text); + } + if(strpos($Text,'[/summary]') !== false) { + $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/is", 'bb_summary', $Text); + } + + // Unhide all [noparse] contained bbtags unspacefying them // and triming the [noparse] tag. if (strpos($Text,'[noparse]') !== false) { $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text); @@ -1633,6 +1658,19 @@ function bbcode($Text, $options = []) { $Text = bb_replace_images($Text, $saved_images); + // Convert new line chars to html <br /> tags + + // nlbr seems to be hopelessly messed up + // $Text = nl2br($Text); + + // We'll emulate it. + + $Text = str_replace("\r\n", "\n", $Text); + $Text = str_replace(array("\r", "\n"), array('<br />', '<br />'), $Text); + + if ($preserve_nl) + $Text = str_replace(array("\n", "\r"), array('', ''), $Text); + call_hooks('bbcode', $Text); return $Text; diff --git a/include/bookmarks.php b/include/bookmarks.php index 145119347..207cf5a33 100644 --- a/include/bookmarks.php +++ b/include/bookmarks.php @@ -73,6 +73,6 @@ function get_bookmark_link($observer) { $h = @parse_url($observer['xchan_url']); if($h) - return $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '') . '/rbmark?f='; + return $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : '') . '/rbmark?f='; return ''; } diff --git a/include/channel.php b/include/channel.php index 2d79cd074..ecb7c24f7 100644 --- a/include/channel.php +++ b/include/channel.php @@ -9,6 +9,7 @@ use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\Permissions; use Zotlabs\Daemon\Master; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\System; use Zotlabs\Render\Comanche; use Zotlabs\Lib\Libzot; @@ -107,7 +108,7 @@ function create_sys_channel() { if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { require_once('include/crypto.php'); - $hostkey = new_keypair(4096); + $hostkey = Crypto::new_keypair(4096); set_config('system', 'pubkey', $hostkey['pubkey']); set_config('system', 'prvkey', $hostkey['prvkey']); } @@ -232,10 +233,10 @@ function create_identity($arr) { } $guid = Libzot::new_uid($nick); - $key = new_keypair(4096); + $key = Crypto::new_keypair(4096); // legacy zot - $zsig = base64url_encode(rsa_sign($guid,$key['prvkey'])); + $zsig = base64url_encode(Crypto::sign($guid,$key['prvkey'])); $zhash = make_xchan_hash($guid,$zsig); // zot6 @@ -302,8 +303,8 @@ function create_identity($arr) { $photo_type = null; $z = [ - 'account' => $a[0], - 'channel' => $r[0], + 'account' => $a[0] ?? [], + 'channel' => $r[0] ?? [], 'photo_url' => '' ]; /** @@ -345,7 +346,7 @@ function create_identity($arr) { 'hubloc_addr' => channel_reddress($ret['channel']), 'hubloc_primary' => intval($primary), 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$ret['channel']['channel_prvkey'])), 'hubloc_host' => App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => get_config('system','pubkey'), @@ -502,23 +503,22 @@ function create_identity($arr) { // right away as a default group for new contacts. require_once('include/group.php'); - group_add($newuid, t('Friends')); - group_add_member($newuid,t('Friends'),$ret['channel']['channel_hash']); + $group_hash = group_add($newuid, t('Friends')); - // if our role_permissions indicate that we're using a default collection ACL, add it. + if($group_hash) { + group_add_member($newuid,t('Friends'),$ret['channel']['channel_hash']); - if(is_array($role_permissions) && $role_permissions['default_collection']) { - $r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1", - intval($newuid), - dbesc( t('Friends') ) - ); - if($r) { - q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", - dbesc($r[0]['hash']), - dbesc('<' . $r[0]['hash'] . '>'), - intval($newuid) - ); + $default_collection_str = ''; + // if our role_permissions indicate that we're using a default collection ACL, add it. + if(is_array($role_permissions) && $role_permissions['default_collection']) { + $default_collection_str = '<' . $group_hash . '>'; } + + q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", + dbesc($group_hash), + dbesc($default_collection_str), + intval($newuid) + ); } if(! $system) { @@ -603,9 +603,9 @@ function change_channel_keys($channel) { $stored = []; - $key = new_keypair(4096); + $key = Crypto::new_keypair(4096); - $sig = base64url_encode(rsa_sign($channel['channel_guid'],$key['prvkey'])); + $sig = base64url_encode(Crypto::sign($channel['channel_guid'],$key['prvkey'])); $hash = make_xchan_hash($channel['channel_guid'],$sig); $stored['old_guid'] = $channel['channel_guid']; @@ -614,7 +614,7 @@ function change_channel_keys($channel) { $stored['old_hash'] = $channel['channel_hash']; $stored['new_key'] = $key['pubkey']; - $stored['new_sig'] = base64url_encode(rsa_sign($key['pubkey'],$channel['channel_prvkey'])); + $stored['new_sig'] = base64url_encode(Crypto::sign($key['pubkey'],$channel['channel_prvkey'])); // Save this info for the notifier to collect @@ -651,7 +651,7 @@ function change_channel_keys($channel) { foreach($h as $hv) { $hv['hubloc_guid_sig'] = $sig; $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modified['channel_prvkey'])); + $hv['hubloc_url_sig'] = base64url_encode(Crypto::sign(z_root(),$modified['channel_prvkey'])); hubloc_store_lowlevel($hv); } } @@ -890,20 +890,27 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals unset($ret['channel']['channel_salt']); } if ($zap_compat) { - $channel['channel_guid_sig'] = 'sha256.' . $channel['channel_guid_sig']; - $channel['channel_hash'] = $channel['channel_portable_id']; - unset($channel['channel_portable_id']); + unset($ret['channel']['channel_portable_id']); } - - } if(in_array('channel',$sections) || in_array('profile',$sections)) { $r = q("select * from profile where uid = %d", intval($channel_id) ); - if($r) + if($r) { $ret['profile'] = $r; + if ($zap_compat) { + // zap only supports one profile + foreach ($r as $rv) { + if ($rv['is_default']) { + $ret['profile'] = [ $rv ]; + break; + } + } + } + } + $r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1", @@ -936,50 +943,47 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals $newconfig = []; $abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']); - // Partly revert of commit 85cf25a2a8bfbbfe10de485d4affd54626fbbfa4 if($abconfig) { - $ret['abook'][$x]['abconfig'] = $abconfig; - } + if ($zap_compat) { + foreach ($abconfig as $abc) { + + if ($abc['cat'] === 'my_perms') { + if (intval($abc['v'])) { + $my_perms[] = $abc['k']; + } + continue; + } + if ($abc['cat'] === 'their_perms') { + if (intval($abc['v'])) { + $their_perms[] = $abc['k']; + } + continue; + } + if (preg_match('|^a:[0-9]+:{.*}$|s', $abc['v'])) { + $abc['v'] = serialise(unserialize($abc['v'])); + } + $newconfig[] = $abc; + } - /* This was added in commit 85cf25a2a8bfbbfe10de485d4affd54626fbbfa4 - * Seems unfinished work on zap compatibility for cloning. - * It breaks cloning of abconfig for hubzilla - reverted to the above code. + $ret['abook'][$x]['abconfig'] = $newconfig; - if($abconfig) { - foreach ($abconfig as $abc) { + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_xchan'], 'cat' => 'system', 'k' => 'my_perms', 'v' => implode(',',$my_perms) ]; + $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_xchan'], 'cat' => 'system', 'k' => 'their_perms', 'v' => implode(',',$their_perms) ]; - if ($abc['cat'] === 'my_perms' && intval($abc['v'])) { - $my_perms[] = $abc['k']; - continue; - } - if ($abc['cat'] === 'their_perms' && intval($abc['v'])) { - $their_perms[] = $abc['k']; - continue; - } - if ($zap_compat && preg_match('|^a:[0-9]+:{.*}$|s', $abc['v'])) { - $abc['v'] = serialise(unserialize($abc['v'])); - } - $newconfig[] = $abc; } - - $ret['abook'][$x]['abconfig'] = $newconfig; - - if ($zap_compat) { - $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'my_perms', 'v' => implode(',',$my_perms) ]; - $ret['abook'][$x]['abconfig'][] = [ 'chan' => $channel_id, 'xchan' => $ret['abook'][$x]['abook_chan'], 'cat' => 'system', 'k' => 'their_perms', 'v' => implode(',',$their_perms) ]; + else { + $ret['abook'][$x]['abconfig'] = $abconfig; } } - */ + translate_abook_perms_outbound($ret['abook'][$x]); } - - // pick up the zot xchan and hublocs also - if($ret['channel']['channel_portable_id']) { + if($ret['channel']['channel_portable_id'] && ! $zot_compat) { $xchans[] = $ret['channel']['channel_portable_id']; } @@ -1090,13 +1094,24 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals } if(in_array('events',$sections)) { - $r = q("select * from event where uid = %d", + + // @fixme - Not totally certain how to handle $zot_compat for the event timezone which exists + // in Hubzilla but is stored with the item and not the event. In Zap, stored information is + // always UTC and localised on access as per standard conventions for working with global time data. + + // Older Zot (pre-Zot6) records aren't translated correctly w/r/t AS2 so only include events for the last year or so if + // migrating to Zap. + + $sqle = (($zap_compat) ? " and created > '2020-01-01 00:00:00' " : ''); + + $r = q("select * from event where uid = %d $sqle", intval($channel_id) ); - if($r) + if ($r) { $ret['event'] = $r; + } - $r = q("select * from item where resource_type = 'event' and uid = %d", + $r = q("select * from item where resource_type = 'event' and uid = %d $sqle", intval($channel_id) ); if($r) { @@ -1104,7 +1119,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['event_item'][] = encode_item($rr,true); + $ret['event_item'][] = encode_item($rr,true, $zap_compat); } } @@ -1127,7 +1142,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['webpages'][] = encode_item($rr,true); + $ret['webpages'][] = encode_item($rr,true, $zap_compat); } } @@ -1164,7 +1179,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rv) { - $ret['wiki'][] = encode_item($rv,true); + $ret['wiki'][] = encode_item($rv,true, $zap_compat); } } } @@ -1189,7 +1204,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals xchan_query($r); $r = fetch_post_tags($r,true); foreach($r as $rr) - $ret['item'][] = encode_item($rr,true); + $ret['item'][] = encode_item($rr,true, $zap_compat); } } @@ -1222,7 +1237,7 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals * * \e array \b relocate - (optional) * * \e array \b item - array with items encoded_item() */ -function identity_export_year($channel_id, $year, $month = 0) { +function identity_export_year($channel_id, $year, $month = 0, $zap_compat = false) { if(! $year) return array(); @@ -1240,7 +1255,7 @@ function identity_export_year($channel_id, $year, $month = 0) { else $maxdate = datetime_convert('UTC', 'UTC', $year+1 . '-01-01 00:00:00'); - return channel_export_items_date($channel_id,$mindate,$maxdate); + return channel_export_items_date($channel_id,$mindate,$maxdate, $zap_compat); } @@ -1255,7 +1270,7 @@ function identity_export_year($channel_id, $year, $month = 0) { * @return array */ -function channel_export_items_date($channel_id, $start, $finish) { +function channel_export_items_date($channel_id, $start, $finish, $zap_compat = false) { if(! $start) return array(); @@ -1273,6 +1288,11 @@ function channel_export_items_date($channel_id, $start, $finish) { $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; } + if ($zap_compat) { + $ret['compatibility']['codebase'] = 'zap'; + } + + $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type != 'photo' order by created", intval(ITEM_TYPE_POST), intval($channel_id), @@ -1285,7 +1305,7 @@ function channel_export_items_date($channel_id, $start, $finish) { xchan_query($r); $r = fetch_post_tags($r, true); foreach($r as $rr) - $ret['item'][] = encode_item($rr, true); + $ret['item'][] = encode_item($rr, true, $zap_compat); } return $ret; @@ -1303,7 +1323,7 @@ function channel_export_items_date($channel_id, $start, $finish) { * @return array */ -function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50) { +function channel_export_items_page($channel_id, $start, $finish, $page = 0, $limit = 50, $zap_compat = false) { if(intval($page) < 1) { $page = 0; @@ -1335,6 +1355,11 @@ function channel_export_items_page($channel_id, $start, $finish, $page = 0, $lim $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()]; } + if ($zap_compat) { + $ret['compatibility']['codebase'] = 'zap'; + } + + $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and resource_type != 'photo' and created >= '%s' and created <= '%s' order by created limit %d offset %d", intval(ITEM_TYPE_POST), intval($channel_id), @@ -1349,7 +1374,7 @@ function channel_export_items_page($channel_id, $start, $finish, $page = 0, $lim xchan_query($r); $r = fetch_post_tags($r, true); foreach($r as $rr) - $ret['item'][] = encode_item($rr, true); + $ret['item'][] = encode_item($rr, true, $zap_compat); } return $ret; diff --git a/include/cli_startup.php b/include/cli_startup.php index a4c1f629a..b9e7d124d 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -9,4 +9,4 @@ function cli_startup() { sys_boot(); App::set_baseurl(get_config('system','baseurl')); -}
\ No newline at end of file +} diff --git a/include/conversation.php b/include/conversation.php index 08d16a413..04aa1ef5a 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -865,7 +865,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $x = [ 'mode' => $mode, 'item' => $item ]; call_hooks('stream_item',$x); - if($x['item']['blocked']) + if(isset($x['item']['blocked'])) continue; $item = $x['item']; @@ -923,7 +923,6 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa // logger('nouveau: ' . print_r($threads,true)); - $o .= replace_macros($page_template, array( '$baseurl' => z_root(), '$photo_item' => $content_html, @@ -935,6 +934,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa '$wait' => t('Loading...'), '$conversation_tools' => t('Conversation Tools'), '$dropping' => ($page_dropping?t('Delete Selected Items'):False), + '$preview' => $preview )); return $o; @@ -1313,6 +1313,7 @@ function hz_status_editor($a, $x, $popup = false) { if($c && $c['channel_moved']) return $o; + $webpage = ((x($x,'webpage')) ? $x['webpage'] : ''); $plaintext = true; $feature_nocomment = feature_enabled($x['profile_uid'], 'disable_comments'); @@ -1366,8 +1367,6 @@ function hz_status_editor($a, $x, $popup = false) { else $id_select = ''; - $webpage = ((x($x,'webpage')) ? $x['webpage'] : ''); - $reset = ((x($x,'reset')) ? $x['reset'] : ''); $feature_auto_save_draft = ((feature_enabled($x['profile_uid'], 'auto_save_draft')) ? "true" : "false"); @@ -1474,7 +1473,9 @@ function hz_status_editor($a, $x, $popup = false) { '$nocomment' => ((array_key_exists('item',$x)) ? $x['item']['item_nocomment'] : 0), '$clearloc' => $clearloc, '$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''), + '$summary' => ((x($x, 'summary')) ? htmlspecialchars($x['summary'], ENT_COMPAT,'UTF-8') : ''), '$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')), + '$placeholdersummary' => ((x($x, 'placeholdersummary')) ? $x['placeholdersummary'] : t('Summary (optional)')), '$catsenabled' => $catsenabled, '$category' => ((x($x, 'category')) ? $x['category'] : ''), '$placeholdercategory' => t('Categories (optional, comma-separated list)'), @@ -1561,7 +1562,7 @@ function sort_item_children($items) { $result = $items; usort($result,'sort_thr_created_rev'); foreach($result as $k => $i) { - if($result[$k]['children']) { + if(isset($result[$k]['children'])) { $result[$k]['children'] = sort_item_children($result[$k]['children']); } } @@ -1571,7 +1572,7 @@ function sort_item_children($items) { function add_children_to_list($children, &$arr) { foreach($children as $y) { $arr[] = $y; - if($y['children']) + if(isset($y['children'])) add_children_to_list($y['children'], $arr); } } @@ -1725,13 +1726,11 @@ function get_responses($conv_responses,$response_verbs,$ob,$item) { $ret = array(); foreach($response_verbs as $v) { $ret[$v] = array(); - $ret[$v]['count'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid']] : ''); + $ret[$v]['count'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid']] : 0); $ret[$v]['list'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid'] . '-l'] : ''); $ret[$v]['button'] = get_response_button_text($v,$ret[$v]['count']); $ret[$v]['title'] = $conv_responses[$v]['title']; - if($ret[$v]['count'] > MAX_LIKERS) { - $ret[$v]['modal'] = true; - } + $ret[$v]['modal'] = (($ret[$v]['count'] > MAX_LIKERS) ? true : false); } $count = 0; diff --git a/include/crypto.php b/include/crypto.php index 39bfd8d43..40e68a4e7 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -25,7 +25,7 @@ function rsa_verify($data,$sig,$key,$alg = 'sha256') { if($verify === (-1)) { while($msg = openssl_error_string()) logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); - btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); + btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); } return (($verify > 0) ? true : false); @@ -110,7 +110,7 @@ function CAST5CFB_decrypt($data,$key,$iv) { function crypto_encapsulate($data,$pubkey,$alg='aes256cbc') { $fn = strtoupper($alg) . '_encrypt'; - + if($alg === 'aes256cbc') return aes_encapsulate($data,$pubkey); @@ -150,7 +150,7 @@ function other_encapsulate($data,$pubkey,$alg) { // assurance of security since it is meaningless if the source algorithms // have been compromised. Also none of this matters if RSA has been // compromised by state actors and evidence is mounting that this has - // already happened. + // already happened. $result = [ 'encrypted' => true ]; $key = openssl_random_pseudo_bytes(256); @@ -163,7 +163,7 @@ function other_encapsulate($data,$pubkey,$alg) { } $result['alg'] = $alg; - $result['key'] = base64url_encode($k,true); + $result['key'] = base64url_encode($k,true); openssl_public_encrypt($iv,$i,$pubkey,$padding); $result['iv'] = base64url_encode($i,true); return $result; @@ -177,11 +177,11 @@ function other_encapsulate($data,$pubkey,$alg) { function crypto_methods() { - // aes256cbc is provided for compatibility with earlier zot implementations which assume 32-byte key and 16-byte iv. + // aes256cbc is provided for compatibility with earlier zot implementations which assume 32-byte key and 16-byte iv. // other_encapsulate() now produces these longer keys/ivs by default so that it is difficult to guess a - // particular implementation or choice of underlying implementations based on the key/iv length. + // particular implementation or choice of underlying implementations based on the key/iv length. // The actual methods are responsible for deriving the actual key/iv from the provided parameters; - // possibly by truncation or segmentation - though many other methods could be used. + // possibly by truncation or segmentation - though many other methods could be used. $r = [ 'aes256ctr.oaep', 'camellia256cfb.oaep', 'cast5cfb.oaep', 'aes256ctr', 'camellia256cfb', 'cast5cfb', 'aes256cbc', 'aes128cbc', 'cast5cbc' ]; call_hooks('crypto_methods',$r); @@ -192,7 +192,6 @@ function crypto_methods() { function signing_methods() { - $r = [ 'sha256' ]; call_hooks('signing_methods',$r); return $r; @@ -215,7 +214,7 @@ function aes_encapsulate($data,$pubkey) { logger('aes_encapsulate: RSA failed. ' . print_r($x[0],true)); } $result['alg'] = 'aes256cbc'; - $result['key'] = base64url_encode($k,true); + $result['key'] = base64url_encode($k,true); openssl_public_encrypt($iv,$i,$pubkey); $result['iv'] = base64url_encode($i,true); return $result; @@ -226,9 +225,9 @@ function crypto_unencapsulate($data,$prvkey) { return; $alg = ((is_array($data) && (array_key_exists('encrypted',$data) || array_key_exists('iv',$data))) ? $data['alg'] : ''); - if(! $alg) { + if(! $alg) { return $data; - } + } if($alg === 'aes256cbc') { return aes_unencapsulate($data,$prvkey); @@ -280,13 +279,13 @@ function new_keypair($bits) { $openssl_options = array( 'digest_alg' => 'sha1', 'private_key_bits' => $bits, - 'encrypt_key' => false + 'encrypt_key' => false ); $conf = get_config('system','openssl_conf_file'); if($conf) $openssl_options['config'] = $conf; - + $result = openssl_pkey_new($openssl_options); if(empty($result)) { @@ -310,36 +309,36 @@ function new_keypair($bits) { function DerToPem($Der, $Private=false) { - //Encode: - $Der = base64_encode($Der); - //Split lines: - $lines = str_split($Der, 65); - $body = implode("\n", $lines); - //Get title: - $title = $Private? 'RSA PRIVATE KEY' : 'PUBLIC KEY'; - //Add wrapping: - $result = "-----BEGIN {$title}-----\n"; - $result .= $body . "\n"; - $result .= "-----END {$title}-----\n"; - - return $result; + //Encode: + $Der = base64_encode($Der); + //Split lines: + $lines = str_split($Der, 65); + $body = implode("\n", $lines); + //Get title: + $title = $Private? 'RSA PRIVATE KEY' : 'PUBLIC KEY'; + //Add wrapping: + $result = "-----BEGIN {$title}-----\n"; + $result .= $body . "\n"; + $result .= "-----END {$title}-----\n"; + + return $result; } function DerToRsa($Der) { - //Encode: - $Der = base64_encode($Der); - //Split lines: - $lines = str_split($Der, 64); - $body = implode("\n", $lines); - //Get title: - $title = 'RSA PUBLIC KEY'; - //Add wrapping: - $result = "-----BEGIN {$title}-----\n"; - $result .= $body . "\n"; - $result .= "-----END {$title}-----\n"; - - return $result; + //Encode: + $Der = base64_encode($Der); + //Split lines: + $lines = str_split($Der, 64); + $body = implode("\n", $lines); + //Get title: + $title = 'RSA PUBLIC KEY'; + //Add wrapping: + $result = "-----BEGIN {$title}-----\n"; + $result .= $body . "\n"; + $result .= "-----END {$title}-----\n"; + + return $result; } @@ -387,7 +386,7 @@ function metopem($m,$e) { $der = pkcs8_encode($m,$e); $key = DerToPem($der,false); return $key; -} +} function pubrsatome($key,&$m,&$e) { @@ -431,7 +430,7 @@ function metorsa($m,$e) { $der = pkcs1_encode($m,$e); $key = DerToRsa($der); return $key; -} +} diff --git a/include/dir_fns.php b/include/dir_fns.php index 88a1bb74f..8326415ed 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -3,6 +3,7 @@ * @file include/dir_fns.php */ +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Webfinger; use Zotlabs\Lib\Zotfinger; @@ -280,7 +281,7 @@ function sync_directories($dirmode) { logger('key unavailable on this site for ' . $rr['channel']); continue; } - if (! rsa_verify($rr['target'] . '.' . $rr['rating'] . '.' . $rr['rating_text'], base64url_decode($rr['signature']),$y[0]['xchan_pubkey'])) { + if (! Crypto::verify($rr['target'] . '.' . $rr['rating'] . '.' . $rr['rating_text'], base64url_decode($rr['signature']),$y[0]['xchan_pubkey'])) { logger('failed to verify rating'); continue; } diff --git a/include/environment.php b/include/environment.php index 96a614821..274eca214 100644 --- a/include/environment.php +++ b/include/environment.php @@ -52,17 +52,18 @@ function getPhpiniUploadLimits() { */ function phpiniSizeToBytes($val) { $val = trim($val); + $num = (double)$val; $unit = strtolower($val[strlen($val)-1]); switch($unit) { case 'g': - $val *= 1024; + $num *= 1024; case 'm': - $val *= 1024; + $num *= 1024; case 'k': - $val *= 1024; + $num *= 1024; default: break; } - return (int)$val; + return (int)$num; } diff --git a/include/feedutils.php b/include/feedutils.php index 352b8f038..6cae14a01 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -440,8 +440,7 @@ function get_atom_elements($feed, $item) { $summary = ''; if(($summary) && ((strpos($summary,'<') !== false) || (strpos($summary,'>') !== false))) { - $summary = purify_html($summary); - $summary = html2bbcode($summary); + $summary = html2plain($summary); } @@ -722,17 +721,17 @@ function get_atom_elements($feed, $item) { if(! $type) $type = 'application/octet-stream'; - if($ostatus_protocol) { - if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; - } - if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[video]' . $link . '[/video]'; - } - if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]'; - } + // put media enclosures in bbcode markup + if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; } + if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[video]' . $link . '[/video]'; + } + if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]'; + } + $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); } } diff --git a/include/follow.php b/include/follow.php index a4d382545..64ae8f7f1 100644 --- a/include/follow.php +++ b/include/follow.php @@ -9,6 +9,8 @@ // $return['abook'] Address book entry joined with xchan if successful // $return['message'] error text if success is false. +use Zotlabs\Lib\Crypto; + require_once('include/zot.php'); function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) { @@ -19,7 +21,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $is_zot = false; $protocol = ''; - + if(substr($url,0,1) === '[') { $x = strpos($url,']'); if($x) { @@ -62,7 +64,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) call_hooks('follow_init', $arr); - if($arr['channel']['success']) + if($arr['channel']['success']) $ret = $arr['channel']; elseif((! $is_http) && ((! $protocol) || (strtolower($protocol) === 'zot'))) $ret = Zotlabs\Zot\Finger::run($url,$channel); @@ -98,11 +100,11 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) return $result; } } - - + + // do we have an xchan and hubloc? - // If not, create them. + // If not, create them. $x = import_xchan($j); @@ -111,13 +113,13 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) return $result; } - if(! $x['success']) + if(! $x['success']) return $x; $xchan_hash = $x['hash']; if( array_key_exists('permissions',$j) && array_key_exists('data',$j['permissions'])) { - $permissions = crypto_unencapsulate(array( + $permissions = Crypto::unencapsulate(array( 'data' => $j['permissions']['data'], 'alg' => $j['permissions']['alg'], 'key' => $j['permissions']['key'], @@ -140,7 +142,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $xchan_hash = ''; $sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : ''); - + $r = q("select * from xchan where (xchan_addr = '%s' or xchan_url = '%s') $sql_options ", dbesc($url), diff --git a/include/group.php b/include/group.php index efda389d6..bb1ed5ed8 100644 --- a/include/group.php +++ b/include/group.php @@ -4,23 +4,23 @@ use Zotlabs\Lib\Libsync; function group_add($uid,$name,$public = 0) { - $ret = false; + $success = false; if(x($uid) && x($name)) { $r = group_byname($uid,$name); // check for dups if($r !== false) { - // This could be a problem. + // This could be a problem. // Let's assume we've just created a group which we once deleted // all the old members are gone, but the group remains so we don't break any security // access lists. What we're doing here is reviving the dead group, but old content which - // was restricted to this group may now be seen by the new group members. + // was restricted to this group may now be seen by the new group members. $z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1", intval($r) ); if(($z) && $z[0]['deleted']) { q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id'])); - notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL); + notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL); } return true; } @@ -42,12 +42,18 @@ function group_add($uid,$name,$public = 0) { intval($public), dbesc($name) ); - $ret = $r; - } - Libsync::build_sync_packet($uid,null,true); + if($r) + $success = true; + } - return $ret; + + if($success) { + Libsync::build_sync_packet($uid,null,true); + return $hash; + } + + return false; } @@ -88,7 +94,7 @@ function group_rmv($uid,$name) { } if($change) { - q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s' + q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s' WHERE channel_id = %d", intval($user_info['channel_default_group']), dbesc($user_info['channel_allow_gid']), @@ -159,7 +165,7 @@ function group_rmv_member($uid,$name,$member) { Libsync::build_sync_packet($uid,null,true); return $r; - + } @@ -170,13 +176,13 @@ function group_add_member($uid,$name,$member,$gid = 0) { if((! $gid) || (! $uid) || (! $member)) return false; - $r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1", + $r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1", intval($uid), intval($gid), dbesc($member) ); if($r) - return true; // You might question this, but + return true; // You might question this, but // we indicate success because the group member was in fact created // -- It was just created at another time if(! $r) @@ -195,7 +201,7 @@ function group_add_member($uid,$name,$member,$gid = 0) { function group_get_members($gid) { $ret = array(); if(intval($gid)) { - $r = q("SELECT * FROM pgrp_member + $r = q("SELECT * FROM pgrp_member LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ", intval($gid), @@ -245,7 +251,7 @@ function group_get_profile_members_xchan($uid,$gid) { function mini_group_select($uid,$group = '') { - + $grps = array(); $o = ''; @@ -263,7 +269,7 @@ function mini_group_select($uid,$group = '') { $o = replace_macros(get_markup_template('group_selection.tpl'), array( '$label' => t('Add new connections to this privacy group'), - '$groups' => $grps + '$groups' => $grps )); return $o; } @@ -287,12 +293,12 @@ function group_side($every="connections",$each="group",$edit = false, $group_id $member_of = array(); if($cid) { $member_of = groups_containing(local_channel(),$cid); - } + } if($r) { foreach($r as $rr) { $selected = (($group_id == $rr['id']) ? ' group-selected' : ''); - + if ($edit) { $groupedit = array( 'href' => "group/".$rr['id'], @@ -301,7 +307,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id } else { $groupedit = null; } - + $groups[] = array( 'id' => $rr['id'], 'enc_cid' => base64url_encode($cid), @@ -314,8 +320,8 @@ function group_side($every="connections",$each="group",$edit = false, $group_id ); } } - - + + $tpl = get_markup_template("group_side.tpl"); $o = replace_macros($tpl, array( '$title' => t('Privacy Groups'), @@ -325,8 +331,8 @@ function group_side($every="connections",$each="group",$edit = false, $group_id '$groups' => $groups, '$add' => t('add'), )); - - + + return $o; } @@ -356,7 +362,7 @@ function expand_groups($g) { else { $x[] = $gv; } - } + } if($x) { stringify_array_elms($x,true); diff --git a/include/help.php b/include/help.php index ebf1ccc08..38facb04a 100644 --- a/include/help.php +++ b/include/help.php @@ -285,6 +285,7 @@ function load_context_help() { $path = App::$cmd; $args = App::$argv; $lang = App::$language; + $context_help = ''; if(! isset($lang) || !is_dir('doc/context/' . $lang . '/')) { $lang = 'en'; diff --git a/include/html2plain.php b/include/html2plain.php index fde70bd01..bf8581bdb 100644 --- a/include/html2plain.php +++ b/include/html2plain.php @@ -76,38 +76,59 @@ function quotelevel($message, $wraplength = 75) return(implode("\n", $newlines)); } + function collecturls($message) { + $pattern = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/is'; preg_match_all($pattern, $message, $result, PREG_SET_ORDER); - - $urls = array(); - foreach ($result as $treffer) { - // A list of some links that should be ignored - $list = array("/user/", "/tag/", "/group/", "/profile/", "/channel/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/", - "//facebook.com/profile.php?id=", "//plus.google.com/"); - foreach ($list as $listitem) - if (strpos($treffer[1], $listitem) !== false) - $ignore = true; - - if ((strpos($treffer[1], "//plus.google.com/") !== false) and (strpos($treffer[1], "/posts") !== false)) + + $urls = []; + if ($result) { + $ignore = false; + foreach ($result as $treffer) { + // A list of some links that should be ignored + $list = [ + "/user/", + "/tag/", + "/group/", + "/profile/", + "/channel/", + "/search?search=", + "/search?tag=", + "mailto:", + "/u/", + "/node/", + "//facebook.com/profile.php?id=", + "//plus.google.com/" + ]; + foreach ($list as $listitem) + if (strpos($treffer[1], $listitem) !== false) + $ignore = true; + + if ((strpos($treffer[1], "//plus.google.com/") !== false) and (strpos($treffer[1], "/posts") !== false)) $ignore = false; - - if (!$ignore) - $urls[$treffer[1]] = $treffer[1]; + + if (! $ignore) + $urls[$treffer[1]] = $treffer[1]; + } } + return($urls); } + function html2plain($html, $wraplength = 75, $compact = false) { $message = str_replace("\r", "", $html); + $message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); - $doc = new DOMDocument(); - $doc->preserveWhiteSpace = false; + if(!$message) + return; - $message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; @$doc->loadHTML($message); $xpath = new DomXPath($doc); diff --git a/include/items.php b/include/items.php index 83108455f..8b22a7b4c 100644 --- a/include/items.php +++ b/include/items.php @@ -4,6 +4,7 @@ * @brief Items related functions. */ +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Enotify; use Zotlabs\Lib\MarkdownSoap; use Zotlabs\Lib\MessageFilter; @@ -1088,7 +1089,7 @@ function empty_acl($item) { return (($item['allow_cid'] === EMPTY_STR && $item['allow_gid'] === EMPTY_STR && $item['deny_cid'] === EMPTY_STR && $item['deny_gid'] === EMPTY_STR) ? true : false); } -function encode_item($item,$mirror = false) { +function encode_item($item,$mirror = false,$zap_compat = false) { $x = []; $x['type'] = 'activity'; $x['encoding'] = 'zot'; @@ -1166,9 +1167,9 @@ function encode_item($item,$mirror = false) { $x['summary'] = $item['summary']; $x['body'] = $item['body']; $x['app'] = $item['app']; - $x['verb'] = $item['verb']; - $x['object_type'] = $item['obj_type']; - $x['target_type'] = $item['tgt_type']; + $x['verb'] = (($zap_compat) ? Activity::activity_mapper($item['verb']) : $item['verb']); + $x['object_type'] = (($zap_compat && $item['obj_type']) ? Activity::activity_obj_mapper($item['obj_type']) : $item['obj_type']); + $x['target_type'] = (($zap_compat && $item['tgt_type']) ? Activity::activity_obj_mapper($item['tgt_type']) : $item['tgt_type']); $x['permalink'] = $item['plink']; $x['location'] = $item['location']; $x['longlat'] = $item['coord']; @@ -1177,10 +1178,19 @@ function encode_item($item,$mirror = false) { $x['owner'] = encode_item_xchan($item['owner']); $x['author'] = encode_item_xchan($item['author']); - if($item['obj']) - $x['object'] = json_decode($item['obj'],true); + if ($zap_compat) { + $x['object'] = Activity::encode_item_object($item,'obj'); + } + else { + if ($item['obj']) { + $x['object'] = json_decode($item['obj'],true); + } + } + if($item['target']) - $x['target'] = json_decode($item['target'],true); + $x['target'] = (($zap_compat) + ? Activity::encode_item_object($item,'target') + : json_decode($item['target'],true)) ; if($item['attach']) $x['attach'] = json_decode($item['attach'],true); if($y = encode_item_flags($item)) @@ -1196,12 +1206,19 @@ function encode_item($item,$mirror = false) { else $x['comment_scope'] = $c_scope; - if($item['term']) - $x['tags'] = encode_item_terms($item['term'],$mirror); - - if($item['iconfig']) - $x['meta'] = encode_item_meta($item['iconfig'],$mirror); + if(! empty($item['term'])) + $x['tags'] = encode_item_terms($item['term'],$mirror); + if(! empty($item['iconfig'])) { + if ($zap_compat) { + for ($y = 0; $y < count($item['iconfig']); $y ++) { + if (preg_match('|^a:[0-9]+:{.*}$|s', $item['iconfig'][$y]['v'])) { + $item['iconfig'][$y]['v'] = serialise(unserialize($item['iconfig'][$y]['v'])); + } + } + } + $x['meta'] = encode_item_meta($item['iconfig'],$mirror); + } logger('encode_item: ' . print_r($x,true), LOGGER_DATA); @@ -1399,6 +1416,30 @@ function decode_tags($t) { return ''; } + +function purify_imported_object($obj) { + $ret = null; + if (is_array($obj)) { + foreach ( $obj as $k => $v ) { + if (is_array($v)) { + $ret[$k] = purify_imported_object($v); + } + elseif (is_string($v)) { + $ret[$k] = purify_html($v); + } + } + } + elseif (is_string($obj)) { + $ret = purify_html($obj); + } + + return $ret; +} + + + + + /** * @brief Santise a potentially complex array. * @@ -1410,6 +1451,10 @@ function activity_sanitise($arr) { if(is_array($arr)) { $ret = array(); foreach($arr as $k => $x) { + if (in_array($k, [ 'content', 'summary', 'contentMap', 'summaryMap' ])) { + $ret[$k] = purify_imported_object($arr[$k]); + continue; + } if(is_array($x)) $ret[$k] = activity_sanitise($x); else @@ -1652,7 +1697,7 @@ function item_sign(&$item) { if(! $r) return; - $item['sig'] = base64url_encode(rsa_sign($item['body'], $r[0]['channel_prvkey'])); + $item['sig'] = base64url_encode(Crypto::sign($item['body'], $r[0]['channel_prvkey'])); $item['item_verified'] = 1; } @@ -2391,9 +2436,14 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) { logger('item_store_update: ' . print_r($arr,true), LOGGER_DATA); - $str = ''; - foreach($arr as $k => $v) { - if($str) + $columns = db_columns('item'); + $str = ''; + foreach ($arr as $k => $v) { + if (!in_array($k, $columns)) { + continue; + } + + if ($str) $str .= ","; $str .= " " . TQUOT . $k . TQUOT . " = '" . $v . "' "; } @@ -2695,10 +2745,13 @@ function tag_deliver($uid, $item_id) { return; } + /* this should not be required anymore due to the check above if (strpos($item['body'],'[/share]')) { logger('W2W post already shared'); return; } + */ + // group delivery via W2W logger('rewriting W2W post for ' . $u[0]['channel_address']); start_delivery_chain($u[0], $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); @@ -2779,11 +2832,11 @@ function tag_deliver($uid, $item_id) { * Now we've got those out of the way. Let's see if this is a post that's tagged for re-delivery */ - $terms = array_merge(get_terms_oftype($item['term'],TERM_MENTION),get_terms_oftype($item['term'],TERM_FORUM)); - - if($terms) + $terms = []; + if (array_key_exists('term', $item)) { + $terms = array_merge(get_terms_oftype($item['term'],TERM_MENTION),get_terms_oftype($item['term'],TERM_FORUM)); logger('Post mentions: ' . print_r($terms,true), LOGGER_DATA); - + } $max_forums = get_config('system','max_tagged_forums',2); $matched_forums = 0; @@ -2792,7 +2845,7 @@ function tag_deliver($uid, $item_id) { $link = normalise_link($u[0]['xchan_url']); - if($terms) { + if(count($terms) > 0) { foreach($terms as $term) { if(! link_compare($term['url'],$link)) { continue; @@ -2971,7 +3024,7 @@ function item_community_tag($channel,$item) { $pitem = $items[0]; $auth = get_iconfig($item,'system','communitytagauth'); if($auth) { - if(rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['owner']['xchan_pubkey']) || rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['author']['xchan_pubkey'])) { + if(Crypto::verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['owner']['xchan_pubkey']) || Crypto::verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['author']['xchan_pubkey'])) { logger('tag_deliver: tagging the post: ' . $channel['channel_name']); $tag_the_post = true; } @@ -2980,7 +3033,7 @@ function item_community_tag($channel,$item) { if(($pitem['owner_xchan'] === $channel['channel_hash']) && (! intval(get_pconfig($channel['channel_id'],'system','blocktags')))) { logger('tag_deliver: community tag recipient: ' . $channel['channel_name']); $tag_the_post = true; - $sig = rsa_sign('tagauth.' . $item['mid'],$channel['channel_prvkey']); + $sig = Crypto::sign('tagauth.' . $item['mid'],$channel['channel_prvkey']); logger('tag_deliver: setting iconfig for ' . $item['id']); set_iconfig($item['id'],'system','communitytagauth',base64url_encode($sig),1); } @@ -3200,13 +3253,15 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $item['mid'] = z_root() . '/item/' . $item['uuid']; $item['parent_mid'] = $item['mid']; $item['thr_parent'] = $item['mid']; + $item['llink'] = z_root() . '/display/' . gen_link_id($item['mid']); } - $r = q("UPDATE item SET author_xchan = '%s', mid = '%s', parent_mid = '%s', thr_parent = '%s' WHERE id = %d", + $r = q("UPDATE item SET author_xchan = '%s', mid = '%s', parent_mid = '%s', thr_parent = '%s', llink = '%s' WHERE id = %d", dbesc($item['author_xchan']), dbesc($item['mid']), dbesc($item['parent_mid']), dbesc($item['thr_parent']), + dbesc($item['llink']), intval($item_id) ); } @@ -3268,24 +3323,19 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $arr['item_wall'] = 1; $arr['item_thread_top'] = 1; - if (strpos($item['body'], "[/share]") !== false) { - $pos = strpos($item['body'], "[share"); - $bb = substr($item['body'], $pos); - } else { - $bb = "[share author='" . urlencode($item['author']['xchan_name']). - "' profile='" . $item['author']['xchan_url'] . - "' portable_id='" . $item['author']['xchan_hash'] . - "' avatar='" . $item['author']['xchan_photo_s'] . - "' link='" . $item['plink'] . - "' auth='" . ((in_array($item['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') . - "' posted='" . $item['created'] . - "' message_id='" . $item['mid'] . - "']"; - if($item['title']) - $bb .= '[h3][b]'.$item['title'].'[/b][/h3]'."\r\n"; - $bb .= $item['body']; - $bb .= "[/share]"; - } + $bb = "[share author='" . urlencode($item['author']['xchan_name']). + "' profile='" . $item['author']['xchan_url'] . + "' portable_id='" . $item['author']['xchan_hash'] . + "' avatar='" . $item['author']['xchan_photo_s'] . + "' link='" . $item['plink'] . + "' auth='" . ((in_array($item['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') . + "' posted='" . $item['created'] . + "' message_id='" . $item['mid'] . + "']"; + if($item['title']) + $bb .= '[h3][b]'.$item['title'].'[/b][/h3]'."\r\n"; + $bb .= $item['body']; + $bb .= "[/share]"; $arr['body'] = $bb; $arr['term'] = $item['term']; @@ -4185,9 +4235,9 @@ function list_post_dates($uid, $wall, $mindate) { $start_month = datetime_convert('','',$dstart,'Y-m-d'); $end_month = datetime_convert('','',$dend,'Y-m-d'); $str = day_translate(datetime_convert('','',$dnow,'F')); - if(! $ret[$dyear]) - $ret[$dyear] = array(); - $ret[$dyear][] = array($str,$end_month,$start_month); + if(! isset($ret[$dyear])) + $ret[$dyear] = []; + $ret[$dyear][] = [ $str, $end_month, $start_month ]; $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d'); } @@ -4266,17 +4316,17 @@ function fetch_post_tags($items, $link = false) { foreach($tags as $t) { if(($link) && ($t['ttype'] == TERM_MENTION)) $t['url'] = chanlink_url($t['url']); - if(array_key_exists('item_id',$items[$x])) { + if(array_key_exists('item_id', $items[$x])) { if($t['oid'] == $items[$x]['item_id']) { - if(! is_array($items[$x]['term'])) - $items[$x]['term'] = array(); + if(array_key_exists('term', $items[$x]) && ! is_array($items[$x]['term'])) + $items[$x]['term'] = []; $items[$x]['term'][] = $t; } } else { if($t['oid'] == $items[$x]['id']) { - if(! is_array($items[$x]['term'])) - $items[$x]['term'] = array(); + if(array_key_exists('term', $items[$x]) && ! is_array($items[$x]['term'])) + $items[$x]['term'] = []; $items[$x]['term'][] = $t; } } @@ -4286,16 +4336,16 @@ function fetch_post_tags($items, $link = false) { foreach($imeta as $i) { if(array_key_exists('item_id',$items[$x])) { if($i['iid'] == $items[$x]['item_id']) { - if(! is_array($items[$x]['iconfig'])) - $items[$x]['iconfig'] = array(); + if(! isset($items[$x]['iconfig'])) + $items[$x]['iconfig'] = []; $i['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$i['v'])) ? unserialize($i['v']) : $i['v']); $items[$x]['iconfig'][] = $i; } } else { if($i['iid'] == $items[$x]['id']) { - if(! is_array($items[$x]['iconfig'])) - $items[$x]['iconfig'] = array(); + if(array_key_exists('iconfig', $items[$x]) && ! is_array($items[$x]['iconfig'])) + $items[$x]['iconfig'] = []; $i['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$i['v'])) ? unserialize($i['v']) : $i['v']); $items[$x]['iconfig'][] = $i; } @@ -4438,18 +4488,23 @@ function zot_feed($uid, $observer_hash, $arr) { function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = CLIENT_MODE_NORMAL,$module = 'network') { - $result = array('success' => false); - - $sql_extra = ''; - $sql_nets = ''; + $result = ['success' => false]; + $sql_extra = ''; + $sql_nets = ''; $sql_options = ''; - $sql_extra2 = ''; - $sql_extra3 = ''; - $def_acl = ''; - - $item_uids = ' true '; + $sql_extra2 = ''; + $sql_extra3 = ''; + $def_acl = ''; + $item_uids = ' true '; $item_normal = item_normal(); + if (! (isset($arr['include_follow']) && intval($arr['include_follow']))) { + $item_normal .= sprintf(" and not verb in ('%s', '%s') ", + dbesc(ACTIVITY_FOLLOW), + dbesc(ACTIVITY_UNFOLLOW) + ); + } + if($arr['uid']) { $uid = $arr['uid']; } @@ -4632,7 +4687,6 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C ); require_once('include/items.php'); - xchan_query($items); $items = fetch_post_tags($items,true); @@ -4805,7 +4859,7 @@ function item_remove_cid($xchan_hash,$mid,$uid) { } // Set item permissions based on results obtained from linkify_tags() -function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, $profile_uid, $parent_item = false, &$private) { +function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, $profile_uid, &$private, $parent_item = false) { $first_access_tag = true; foreach($linkified as $x) { diff --git a/include/language.php b/include/language.php index 622b9614d..d291deb63 100644 --- a/include/language.php +++ b/include/language.php @@ -77,7 +77,7 @@ function get_best_language() { if(! isset($preferred)) { /* - * We could find no perfect match for any of the preferred languages. + * We could find no perfect match for any of the preferred languages. * For cases where the preference is fr-fr and we have fr but *not* fr-fr * run the test again and only look for the language base * which should provide an interface they can sort of understand @@ -262,11 +262,15 @@ function tt($singular, $plural, $count, $ctx = ''){ * @return string */ function ta($k){ + $t = null; - $t = App::$strings[$k]; - if (is_array($t)) - $t = implode("/", $t); - return ($t == "" ? $k : $t); + if(isset(App::$strings[$k])) + $t = App::$strings[$k]; + + if (is_array($t)) + $t = implode("/", $t); + + return ($t == "" ? $k : $t); } /** diff --git a/include/message.php b/include/message.php index 37fe6749d..e6c9ed8ee 100644 --- a/include/message.php +++ b/include/message.php @@ -17,9 +17,9 @@ function mail_prepare_binary($item) { // send a private message - -function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $replyto = '', $expires = NULL_DATE, $mimetype = 'text/bbcode', $raw = false, $sig = '') { + +function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $replyto = '', $expires = NULL_DATE, $mimetype = 'text/bbcode', $raw = false, $sig = '') { $ret = array('success' => false); $is_reply = false; @@ -80,7 +80,7 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep $ret['message'] = t('No recipient provided.'); return $ret; } - + if(! strlen($subject)) $subject = t('[no subject]'); @@ -99,13 +99,13 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep if($r) { $conv_guid = $r[0]['conv_guid']; } - } + } if(! $conv_guid) { // create a new conversation - $retconv = create_conversation($channel,$recipient,$subject); + $retconv = create_conversation($channel,$recipient,$subject); if($retconv) { $conv_guid = $retconv['guid']; } @@ -153,7 +153,7 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep /** * - * When a photo was uploaded into the message using the (profile wall) ajax + * When a photo was uploaded into the message using the (profile wall) ajax * uploader, The permissions are initially set to disallow anybody but the * owner from seeing it. This is because the permissions may not yet have been * set for the post. If it's private, the photo permissions should be set @@ -232,7 +232,7 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep dbesc($image_uri), intval($channel['channel_id']), dbesc('<' . $channel['channel_hash'] . '>') - ); + ); } } @@ -293,7 +293,7 @@ function create_conversation($channel,$recipient,$subject) { dbesc($conv_guid), intval($channel['channel_id']) ); - + return $r[0]; } @@ -308,11 +308,12 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { if($numitems) $limit = " LIMIT " . intval($numitems) . " OFFSET " . intval($start); - + if($mailbox !== '') { $x = q("select channel_hash from channel where channel_id = %d limit 1", intval($uid) ); + if(! $x) return array(); @@ -332,10 +333,9 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { case 'combined': default: $parents = q("SELECT mail.parent_mid FROM mail LEFT JOIN conv ON mail.conv_guid = conv.guid WHERE mail.mid = mail.parent_mid AND mail.channel_id = %d ORDER BY conv.updated DESC $limit", - dbesc($local_channel) + intval($local_channel) ); break; - } } @@ -346,7 +346,7 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { foreach($parents as $parent) { $all = q("SELECT * FROM mail WHERE parent_mid = '%s' AND channel_id = %d ORDER BY created DESC limit 1", dbesc($parent['parent_mid']), - dbesc($local_channel) + intval($local_channel) ); if($all) { @@ -356,7 +356,7 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { } } } - else { + elseif($sql) { $r = q($sql); } @@ -477,7 +477,7 @@ function private_messages_drop($channel_id, $messageitem_id, $drop_conversation dbesc($x[0]['conv_guid']), intval($channel_id) ); - } + } $m['mail'] = array(); foreach($z as $zz) { xchan_mail_query($zz); @@ -513,7 +513,7 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda intval($messageitem_id) ); - if(! $r) + if(! $r) return array(); $messages = q("select * from mail where parent_mid = '%s' and channel_id = %d order by created asc", @@ -559,7 +559,7 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda intval($channel_id) ); } - + return $messages; } diff --git a/include/nav.php b/include/nav.php index b2a061661..994f7e0c0 100644 --- a/include/nav.php +++ b/include/nav.php @@ -14,39 +14,41 @@ function nav($template = 'default') { * */ - if(!(x(App::$page,'nav'))) - App::$page['nav'] = ''; - + App::$page['nav'] = App::$page['nav'] ?? ''; + App::$page['htmlhead'] = App::$page['htmlhead'] ?? ''; App::$page['htmlhead'] .= '<script>$(document).ready(function() { $("#nav-search-text").search_autocomplete(\'' . z_root() . '/acl' . '\');});</script>'; - $is_owner = (((local_channel()) && ((App::$profile_uid == local_channel()) || (App::$profile_uid == 0))) ? true : false); + $observer = []; + $sitelocation = ''; - if(local_channel()) { - $channel = App::get_channel(); + if (local_channel()) { + $channel = App::get_channel(); $observer = App::get_observer(); - $prof = q("select id from profile where uid = %d and is_default = 1", + + $prof = q("select id from profile where uid = %d and is_default = 1", intval($channel['channel_id']) ); - if(! $_SESSION['delegate']) { + if (empty($_SESSION['delegate'])) { $chans = q("select channel_name, channel_id from channel where channel_account_id = %d and channel_removed = 0 order by channel_name ", intval(get_account_id()) ); } $sitelocation = (($is_owner) ? '' : App::$profile['reddress']); } - elseif(remote_channel()) { - $observer = App::get_observer(); + elseif (remote_channel()) { + $observer = App::get_observer(); $sitelocation = ((App::$profile['reddress']) ? App::$profile['reddress'] : '@' . App::get_hostname()); } require_once('include/conversation.php'); - $nav_apps = []; - $navbar_apps = []; + $nav_apps = []; + $navbar_apps = []; $channel_apps = []; - - $channel_apps[] = channel_apps($is_owner, App::$profile['channel_address']); + + if (isset(App::$profile['channel_address'])) + $channel_apps[] = channel_apps($is_owner, App::$profile['channel_address']); /** @@ -55,117 +57,121 @@ function nav($template = 'default') { * */ - $banner = get_config('system','banner'); + $banner = get_config('system', 'banner'); + + if ($banner === false) + $banner = get_config('system', 'sitename'); - if($banner === false) - $banner = get_config('system','sitename'); - - call_hooks('get_banner',$banner); + call_hooks('get_banner', $banner); - App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array( + App::$page['header'] = App::$page['header'] ?? ''; + App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), [ //we could additionally use this to display important system notifications e.g. for updates - )); + ]); // nav links: array of array('href', 'text', 'extra css classes', 'title') $nav = []; - if(can_view_public_stream()) + if (can_view_public_stream()) $nav['pubs'] = true; /** * Display login or logout - */ + */ - $nav['usermenu'] = []; - $userinfo = null; + $nav['usermenu'] = []; $nav['loginmenu'] = []; + $userinfo = []; - if($observer) { + if ($observer) { $userinfo = [ - 'icon' => $observer['xchan_photo_m'].'?rev='.strtotime($observer['xchan_photo_date']), + 'icon' => $observer['xchan_photo_m'] . '?rev=' . strtotime($observer['xchan_photo_date']), 'name' => $observer['xchan_addr'], ]; } - elseif(! $_SESSION['authenticated']) { + elseif (empty($_SESSION['authenticated'])) { $nav['remote_login'] = remote_login(); - $nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn'); + $nav['loginmenu'][] = ['rmagic', t('Remote authentication'), '', t('Click to authenticate to your home hub'), 'rmagic_nav_btn']; } - if(local_channel()) { + if (local_channel()) { + + if (empty($_SESSION['delegate'])) { + $nav['manage'] = ['manage', t('Channel Manager'), "", t('Manage your channels'), 'manage_nav_btn']; + } + if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) + $nav['group'] = ['group', t('Privacy Groups'), "", t('Manage your privacy groups'), 'group_nav_btn']; - if(! $_SESSION['delegate']) { - $nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage your channels'),'manage_nav_btn'); - } - if(Apps::system_app_installed(local_channel(), 'Privacy Groups')) - $nav['group'] = array('group', t('Privacy Groups'),"", t('Manage your privacy groups'),'group_nav_btn'); + $nav['settings'] = ['settings', t('Settings'), "", t('Account/Channel Settings'), 'settings_nav_btn']; - $nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn'); - - if($chans && count($chans) > 1 && feature_enabled(local_channel(),'nav_channel_select')) + if ($chans && count($chans) > 1 && feature_enabled(local_channel(), 'nav_channel_select')) $nav['channels'] = $chans; - $nav['logout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; - + $nav['logout'] = ['logout', t('Logout'), "", t('End this session'), 'logout_nav_btn']; + // user menu - $nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), ((\App::$nav_sel['raw_name'] == 'Profile') ? 'active' : ''), t('Your profile page'),'profile_nav_btn']; + $nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), ((App::$nav_sel['raw_name'] == 'Profile') ? 'active' : ''), t('Your profile page'), 'profile_nav_btn']; - if(feature_enabled(local_channel(),'multi_profiles')) - $nav['usermenu'][] = ['profiles', t('Edit Profiles'), ((\App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : '') , t('Manage/Edit profiles'),'profiles_nav_btn']; + if (feature_enabled(local_channel(), 'multi_profiles')) + $nav['usermenu'][] = ['profiles', t('Edit Profiles'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : ''), t('Manage/Edit profiles'), 'profiles_nav_btn']; else - $nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'), ((\App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : ''), t('Edit your profile'),'profiles_nav_btn']; + $nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'), ((App::$nav_sel['raw_name'] == 'Profiles') ? 'active' : ''), t('Edit your profile'), 'profiles_nav_btn']; } else { - if(! get_account_id()) { - if(App::$module === 'channel') { - $nav['login'] = login(true,'main-login',false,false); - $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'']; + if (!get_account_id()) { + if (App::$module === 'channel') { + $nav['login'] = login(true, 'main-login', false, false); + $nav['loginmenu'][] = ['login', t('Login'), '', t('Sign in'), '']; } else { - $nav['login'] = login(true,'main-login',false,false); - $nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'login_nav_btn']; + $nav['login'] = login(true, 'main-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'), - [ - '$nav' => $nav, + [ + '$nav' => $nav, 'userinfo' => $userinfo ] ); } } else - $nav['alogout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn']; + $nav['alogout'] = ['logout', t('Logout'), "", t('End this session'), 'logout_nav_btn']; } $my_url = get_my_url(); - if(! $my_url) { + if (!$my_url) { $observer = App::get_observer(); - $my_url = (($observer) ? $observer['xchan_url'] : ''); + $my_url = (($observer) ? $observer['xchan_url'] : ''); } $homelink_arr = parse_url($my_url); - $homelink = $homelink_arr['scheme'] . '://' . $homelink_arr['host']; + $scheme = $homelink_arr['scheme'] ?? ''; + $host = $homelink_arr['host'] ?? ''; + $homelink = $scheme . '://' . $host; - if(! $is_owner) { - $nav['rusermenu'] = array( + if (!$is_owner) { + $nav['rusermenu'] = [ $homelink, t('Take me home'), 'logout', ((local_channel()) ? t('Logout') : t('Log me out of this site')) - ); + ]; } - if(((get_config('system','register_policy') == REGISTER_OPEN) || (get_config('system','register_policy') == REGISTER_APPROVE)) && (! $_SESSION['authenticated'])) - $nav['register'] = ['register',t('Register'), "", t('Create an account'),'register_nav_btn']; + if (((get_config('system', 'register_policy') == REGISTER_OPEN) || (get_config('system', 'register_policy') == REGISTER_APPROVE)) && (empty($_SESSION['authenticated']))) + $nav['register'] = ['register', t('Register'), "", t('Create an account'), 'register_nav_btn']; - if(! get_config('system','hide_help')) { - $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; - $context_help = ''; - $enable_context_help = ((intval(get_config('system','enable_context_help')) === 1 || get_config('system','enable_context_help') === false) ? true : false); - if($enable_context_help === true) { + if (!get_config('system', 'hide_help')) { + $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; + $context_help = ''; + $enable_context_help = ((intval(get_config('system', 'enable_context_help')) === 1 || get_config('system', 'enable_context_help') === false) ? true : false); + if ($enable_context_help === true) { require_once('include/help.php'); $context_help = load_context_help(); //point directly to /help if $context_help is empty - this can be removed once we have context help for all modules @@ -174,7 +180,7 @@ function nav($template = 'default') { $nav['help'] = [$help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help]; } - switch(App::$module) { + switch (App::$module) { case 'network': $search_form_action = 'network'; break; @@ -190,32 +196,32 @@ function nav($template = 'default') { /** * Admin page */ - if (is_site_admin()) { - $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration'),'admin_nav_btn'); - } + if (is_site_admin()) { + $nav['admin'] = ['admin/', t('Admin'), "", t('Site Setup and Configuration'), 'admin_nav_btn']; + } - $x = array('nav' => $nav, 'usermenu' => $userinfo ); + $x = ['nav' => $nav, 'usermenu' => $userinfo]; call_hooks('nav', $x); - // Not sure the best place to put this on the page. So I'm implementing it but leaving it - // turned off until somebody discovers this and figures out a good location for it. + // Not sure the best place to put this on the page. So I'm implementing it but leaving it + // turned off until somebody discovers this and figures out a good location for it. $powered_by = ''; - $url = ''; + $url = ''; $settings_url = ''; - if(App::$profile_uid && App::$nav_sel['raw_name']) { + if (App::$profile_uid && App::$nav_sel['raw_name']) { $active_app = q("SELECT app_url FROM app WHERE app_channel = %d AND app_name = '%s' LIMIT 1", intval(App::$profile_uid), dbesc(App::$nav_sel['raw_name']) ); - if($active_app) { - if(strpos($active_app[0]['app_url'], ',')) { + if ($active_app) { + if (strpos($active_app[0]['app_url'], ',')) { $urls = explode(',', $active_app[0]['app_url']); - $url = trim($urls[0]); - if($is_owner) + $url = trim($urls[0]); + if ($is_owner) $settings_url = trim($urls[1]); } else { @@ -224,42 +230,39 @@ function nav($template = 'default') { } } - if(! $settings_url && isset(App::$nav_sel['settings_url'])) + if (!$settings_url && isset(App::$nav_sel['settings_url'])) $settings_url = App::$nav_sel['settings_url']; $pinned_list = []; - $syslist = []; //app bin - if($is_owner) { - if(get_pconfig(local_channel(), 'system','import_system_apps') !== datetime_convert('UTC','UTC','now','Y-m-d')) { + if ($is_owner) { + if (get_pconfig(local_channel(), 'system', 'import_system_apps') !== datetime_convert('UTC', 'UTC', 'now', 'Y-m-d')) { Apps::import_system_apps(); - set_pconfig(local_channel(), 'system','import_system_apps', datetime_convert('UTC','UTC','now','Y-m-d')); + set_pconfig(local_channel(), 'system', 'import_system_apps', datetime_convert('UTC', 'UTC', 'now', 'Y-m-d')); } - if(get_pconfig(local_channel(), 'system','force_import_system_apps') !== STD_VERSION) { + if (get_pconfig(local_channel(), 'system', 'force_import_system_apps') !== STD_VERSION) { Apps::import_system_apps(); - set_pconfig(local_channel(), 'system','force_import_system_apps', STD_VERSION); + set_pconfig(local_channel(), 'system', 'force_import_system_apps', STD_VERSION); } - $list = Apps::app_list(local_channel(), false, [ 'nav_pinned_app' ]); - if($list) { - foreach($list as $li) { + $list = Apps::app_list(local_channel(), false, ['nav_pinned_app']); + if ($list) { + foreach ($list as $li) { $pinned_list[] = Apps::app_encode($li); } } Apps::translate_system_apps($pinned_list); - usort($pinned_list,'Zotlabs\\Lib\\Apps::app_name_compare'); - - $pinned_list = Apps::app_order(local_channel(),$pinned_list, 'nav_pinned_app'); - + usort($pinned_list, 'Zotlabs\\Lib\\Apps::app_name_compare'); + $pinned_list = Apps::app_order(local_channel(), $pinned_list, 'nav_pinned_app'); $syslist = []; - $list = Apps::app_list(local_channel(), false, [ 'nav_featured_app' ]); + $list = Apps::app_list(local_channel(), false, ['nav_featured_app']); - if($list) { - foreach($list as $li) { + if ($list) { + foreach ($list as $li) { $syslist[] = Apps::app_encode($li); } } @@ -270,85 +273,82 @@ function nav($template = 'default') { $syslist = Apps::get_system_apps(true); } - usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare'); + usort($syslist, 'Zotlabs\\Lib\\Apps::app_name_compare'); - $syslist = Apps::app_order(local_channel(),$syslist, 'nav_featured_app'); + $syslist = Apps::app_order(local_channel(), $syslist, 'nav_featured_app'); - - if($pinned_list) { - foreach($pinned_list as $app) { - if(\App::$nav_sel['name'] == $app['name']) + if ($pinned_list) { + foreach ($pinned_list as $app) { + if (App::$nav_sel['name'] == $app['name']) $app['active'] = true; - if($is_owner) { - $navbar_apps[] = Apps::app_render($app,'navbar'); + if ($is_owner) { + $navbar_apps[] = Apps::app_render($app, 'navbar'); } - elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) { - $navbar_apps[] = Apps::app_render($app,'navbar'); + elseif (!$is_owner && strpos($app['requires'], 'local_channel') === false) { + $navbar_apps[] = Apps::app_render($app, 'navbar'); } } } - - if($syslist) { - foreach($syslist as $app) { - if(\App::$nav_sel['name'] == $app['name']) + if ($syslist) { + foreach ($syslist as $app) { + if (isset(App::$nav_sel['name']) && App::$nav_sel['name'] == $app['name']) $app['active'] = true; - - if($is_owner) { - $nav_apps[] = Apps::app_render($app,'nav'); + if ($is_owner) { + $nav_apps[] = Apps::app_render($app, 'nav'); } - elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) { - $nav_apps[] = Apps::app_render($app,'nav'); + elseif (!$is_owner && (!isset($app['requires']) || (isset($app['requires']) && strpos($app['requires'], 'local_channel') === false))) { + $nav_apps[] = Apps::app_render($app, 'nav'); } } } - $c = theme_include('navbar_' . purify_filename($template) . '.css'); + $c = theme_include('navbar_' . purify_filename($template) . '.css'); $tpl = get_markup_template('navbar_' . purify_filename($template) . '.tpl'); - if($c && $tpl) { + if ($c && $tpl) { head_add_css('navbar_' . $template . '.css'); } - if(! $tpl) { + if (!$tpl) { $tpl = get_markup_template('navbar_default.tpl'); } - App::$page['nav'] .= replace_macros($tpl, array( - '$baseurl' => z_root(), - '$fulldocs' => t('Help'), - '$sitelocation' => $sitelocation, - '$nav' => $x['nav'], - '$banner' => $banner, + App::$page['nav'] .= replace_macros($tpl, [ + '$baseurl' => z_root(), + '$fulldocs' => t('Help'), + '$sitelocation' => $sitelocation, + '$nav' => $x['nav'], + '$banner' => $banner, '$emptynotifications' => t('Loading'), - '$userinfo' => $x['usermenu'], - '$localuser' => local_channel(), - '$is_owner' => $is_owner, - '$sel' => App::$nav_sel, - '$powered_by' => $powered_by, - '$help' => t('@name, !forum, #tag, ?doc, content'), - '$pleasewait' => t('Please wait...'), - '$nav_apps' => $nav_apps, - '$navbar_apps' => $navbar_apps, - '$channel_menu' => get_pconfig(App::$profile_uid,'system','channel_menu',get_config('system','channel_menu')), - '$channel_thumb' => ((App::$profile) ? App::$profile['thumb'] : ''), - '$channel_apps' => $channel_apps, - '$addapps' => t('Add Apps'), - '$orderapps' => t('Arrange Apps'), - '$sysapps_toggle' => t('Toggle System Apps'), - '$url' => (($url) ? $url : z_root() . '/' . App::$cmd), - '$settings_url' => $settings_url - )); - - if(x($_SESSION, 'reload_avatar') && $observer) { - // The avatar has been changed on the server but the browser doesn't know that, + '$userinfo' => $x['usermenu'], + '$localuser' => local_channel(), + '$is_owner' => $is_owner, + '$sel' => App::$nav_sel, + '$powered_by' => $powered_by, + '$help' => t('@name, !forum, #tag, ?doc, content'), + '$pleasewait' => t('Please wait...'), + '$nav_apps' => $nav_apps, + '$navbar_apps' => $navbar_apps, + '$channel_menu' => get_pconfig(App::$profile_uid, 'system', 'channel_menu', get_config('system', 'channel_menu')), + '$channel_thumb' => ((App::$profile) ? App::$profile['thumb'] : ''), + '$channel_apps' => $channel_apps, + '$addapps' => t('Add Apps'), + '$orderapps' => t('Arrange Apps'), + '$sysapps_toggle' => t('Toggle System Apps'), + '$url' => (($url) ? $url : z_root() . '/' . App::$cmd), + '$settings_url' => $settings_url + ]); + + if (x($_SESSION, 'reload_avatar') && $observer) { + // The avatar has been changed on the server but the browser doesn't know that, // force the browser to reload the image from the server instead of its cache. $tpl = get_markup_template('force_image_reload.tpl'); - App::$page['nav'] .= replace_macros($tpl, array( + App::$page['nav'] .= replace_macros($tpl, [ '$imgUrl' => $observer['xchan_photo_m'] - )); + ]); unset($_SESSION['reload_avatar']); } @@ -358,9 +358,9 @@ function nav($template = 'default') { /* * Set a menu item in navbar as selected - * + * */ -function nav_set_selected($raw_name, $settings_url = ''){ +function nav_set_selected($raw_name, $settings_url = '') { App::$nav_sel['raw_name'] = $raw_name; $item = ['name' => $raw_name]; @@ -368,7 +368,7 @@ function nav_set_selected($raw_name, $settings_url = ''){ App::$nav_sel['name'] = $item['name']; - if($settings_url) + if ($settings_url) App::$nav_sel['settings_url'] = z_root() . '/' . $settings_url; } @@ -376,20 +376,20 @@ function channel_apps($is_owner = false, $nickname = null) { // Don't provide any channel apps if we're running as the sys channel - if(App::$is_sys) + if (App::$is_sys) return ''; $channel = App::get_channel(); - if($channel && is_null($nickname)) + if ($channel && is_null($nickname)) $nickname = $channel['channel_address']; - $uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel()); + $uid = ((isset(App::$profile['profile_uid'])) ? App::$profile['profile_uid'] : local_channel()); - if(! get_pconfig($uid, 'system', 'channelapps','1')) - return; + if (!get_pconfig($uid, 'system', 'channelapps', '1')) + return; - if($uid == local_channel()) { + if ($uid == local_channel()) { return; } else { @@ -399,9 +399,9 @@ function channel_apps($is_owner = false, $nickname = null) { $sql_options = item_permissions_sql($uid); $r = q("select item.* from item left join iconfig on item.id = iconfig.iid - where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' - and item.item_delayed = 0 and item.item_deleted = 0 - and ( iconfig.k = 'WEBPAGE' and item_type = %d ) + where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' + and item.item_delayed = 0 and item.item_deleted = 0 + and ( iconfig.k = 'WEBPAGE' and item_type = %d ) $sql_options limit 1", intval($uid), dbesc('home'), @@ -410,7 +410,7 @@ function channel_apps($is_owner = false, $nickname = null) { $has_webpages = (($r) ? true : false); - if(x($_GET, 'tab')) + if (x($_GET, 'tab')) $tab = notags(trim($_GET['tab'])); $url = z_root() . '/channel/' . $nickname; @@ -427,7 +427,7 @@ function channel_apps($is_owner = false, $nickname = null) { ], ]; - $p = get_all_perms($uid,get_observer_hash()); + $p = get_all_perms($uid, get_observer_hash()); if ($p['view_profile']) { $tabs[] = [ @@ -458,7 +458,7 @@ function channel_apps($is_owner = false, $nickname = null) { ]; } - if($p['view_stream'] && $cal_link) { + if ($p['view_stream'] && $cal_link) { $tabs[] = [ 'label' => t('Calendar'), 'url' => z_root() . $cal_link, @@ -470,13 +470,13 @@ function channel_apps($is_owner = false, $nickname = null) { } - if ($p['chat'] && Apps::system_app_installed($uid,'Chatrooms')) { + if ($p['chat'] && Apps::system_app_installed($uid, 'Chatrooms')) { $has_chats = Chatroom::list_count($uid); if ($has_chats) { $tabs[] = [ 'label' => t('Chatrooms'), 'url' => z_root() . '/chat/' . $nickname, - 'sel' => ((argv(0) == 'chat') ? 'active' : '' ), + 'sel' => ((argv(0) == 'chat') ? 'active' : ''), 'title' => t('Chatrooms'), 'id' => 'chat-tab', 'icon' => 'comments-o' @@ -484,7 +484,7 @@ function channel_apps($is_owner = false, $nickname = null) { } } - $has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK); + $has_bookmarks = menu_list_count(local_channel(), '', MENU_BOOKMARK) + menu_list_count(local_channel(), '', MENU_SYSTEM | MENU_BOOKMARK); if ($is_owner && $has_bookmarks) { $tabs[] = [ 'label' => t('Bookmarks'), @@ -496,10 +496,10 @@ function channel_apps($is_owner = false, $nickname = null) { ]; } - if($p['view_pages'] && Apps::system_app_installed($uid, 'Cards')) { + if ($p['view_pages'] && Apps::system_app_installed($uid, 'Cards')) { $tabs[] = [ 'label' => t('Cards'), - 'url' => z_root() . '/cards/' . $nickname , + 'url' => z_root() . '/cards/' . $nickname, 'sel' => ((argv(0) == 'cards') ? 'active' : ''), 'title' => t('View Cards'), 'id' => 'cards-tab', @@ -507,10 +507,10 @@ function channel_apps($is_owner = false, $nickname = null) { ]; } - if($p['view_pages'] && Apps::system_app_installed($uid, 'Articles')) { + if ($p['view_pages'] && Apps::system_app_installed($uid, 'Articles')) { $tabs[] = [ 'label' => t('Articles'), - 'url' => z_root() . '/articles/' . $nickname , + 'url' => z_root() . '/articles/' . $nickname, 'sel' => ((argv(0) == 'articles') ? 'active' : ''), 'title' => t('View Articles'), 'id' => 'articles-tab', @@ -519,7 +519,7 @@ function channel_apps($is_owner = false, $nickname = null) { } - if($has_webpages && Apps::system_app_installed($uid, 'Webpages')) { + if ($has_webpages && Apps::system_app_installed($uid, 'Webpages')) { $tabs[] = [ 'label' => t('Webpages'), 'url' => z_root() . '/page/' . $nickname . '/home', @@ -529,7 +529,7 @@ function channel_apps($is_owner = false, $nickname = null) { 'icon' => 'newspaper-o' ]; } - + if ($p['view_wiki'] && Apps::system_app_installed($uid, 'Wiki')) { $tabs[] = [ @@ -542,11 +542,11 @@ function channel_apps($is_owner = false, $nickname = null) { ]; } - $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); + $arr = ['is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs]; - call_hooks('channel_apps', $arr); + call_hooks('channel_apps', $arr); - return replace_macros(get_markup_template('profile_tabs.tpl'), + return replace_macros(get_markup_template('profile_tabs.tpl'), [ '$tabs' => $arr['tabs'], '$name' => App::$profile['channel_name'], diff --git a/include/network.php b/include/network.php index f5ff48fce..fcc7b4289 100644 --- a/include/network.php +++ b/include/network.php @@ -1134,11 +1134,15 @@ function discover_by_webbie($webbie, $protocol = '') { foreach($x['links'] as $link) { if(array_key_exists('rel',$link)) { if($link['rel'] === PROTOCOL_ZOT6 && ((! $protocol) || (strtolower($protocol) === 'zot6'))) { + logger('zot6 found for ' . $webbie, LOGGER_DEBUG); $record = Zotfinger::exec($link['href']); + if (! $record) { + logger('Record not found for ' . $link['href']); + continue; + } // Check the HTTP signature - $hsig = $record['signature']; if($hsig && $hsig['signer'] === $link['href'] && $hsig['header_valid'] === true && $hsig['content_valid'] === true) $hsig_valid = true; @@ -1226,7 +1230,7 @@ function webfinger_rfc7033($webbie, $zot = false) { if($m['scheme'] !== 'https') return false; - $rhs = $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); + $rhs = $m['host'] . (array_key_exists('port', $m) ? ':' . $m['port'] : ''); $resource = urlencode($webbie); } } @@ -1957,10 +1961,10 @@ function service_plink($contact, $guid) { $m = parse_url($contact['xchan_url']); if($m) { - $url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); + $url = $m['scheme'] . '://' . $m['host'] . (array_key_exists('port', $m) ? ':' . $m['port'] : ''); } else { - $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1); + $url = 'https://' . substr($contact['xchan_addr'], strpos($contact['xchan_addr'], '@') + 1); } $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@')); diff --git a/include/oembed.php b/include/oembed.php index 1550eaacf..9a25686fa 100644 --- a/include/oembed.php +++ b/include/oembed.php @@ -14,7 +14,7 @@ function oembed_replacecb($matches){ $j = oembed_fetch_url($result['url']); $s = oembed_format_object($j); - return $s; + return $s; } @@ -52,7 +52,7 @@ function oembed_action($embedurl) { } } } - + $found = false; if(($x = get_config('system','embed_allow'))) { @@ -74,7 +74,7 @@ function oembed_action($embedurl) { } // allow individual members to block something that wasn't blocked already. - // They cannot over-ride the site to allow or change the filtering on an + // They cannot over-ride the site to allow or change the filtering on an // embed that is not allowed by the site admin. if(local_channel()) { @@ -96,7 +96,7 @@ function oembed_action($embedurl) { $arr = array('url' => $embedurl, 'action' => $action); call_hooks('oembed_action',$arr); - logger('action: ' . $arr['action'] . ' url: ' . $arr['url'], LOGGER_DEBUG,LOG_DEBUG); + logger('action: ' . $arr['action'] . ' url: ' . $arr['url'], LOGGER_DEBUG,LOG_DEBUG); return $arr; @@ -122,7 +122,7 @@ function oembed_fetch_url($embedurl){ $noexts = [ '.mp3', '.mp4', '.ogg', '.ogv', '.oga', '.ogm', '.webm', '.opus', '.m4a' ]; - $result = oembed_action($embedurl); + $result = oembed_action($embedurl); $embedurl = $result['url']; $action = $result['action']; @@ -153,7 +153,7 @@ function oembed_fetch_url($embedurl){ 'title' => t('View PDF'), 'type' => 'pdf' ]; - + // set $txt to something so that we don't attempt to fetch what could be a lengthy pdf. $txt = EMPTY_STR; } @@ -165,12 +165,12 @@ function oembed_fetch_url($embedurl){ if ($action !== 'block') { // try oembed autodiscovery $redirects = 0; - $result = z_fetch_url($furl, false, $redirects, + $result = z_fetch_url($furl, false, $redirects, [ - 'timeout' => 30, - 'accept_content' => "text/*", - 'novalidate' => true, - 'session' => ((local_channel() && $zrl) ? true : false) + 'timeout' => 30, + 'accept_content' => "text/*", + 'novalidate' => true, + 'session' => ((local_channel() && $zrl) ? true : false) ] ); @@ -180,7 +180,8 @@ function oembed_fetch_url($embedurl){ logger('fetch failure: ' . $furl); if($html_text) { - $dom = @DOMDocument::loadHTML($html_text); + $dom = new DOMDocument; + @$dom->loadHTML($html_text); if ($dom){ $xpath = new DOMXPath($dom); $attr = "oembed"; @@ -192,9 +193,9 @@ function oembed_fetch_url($embedurl){ // Youtube will happily hand us an http oembed URL even if we specify an https link; and the returned http link will fail with a 40x if you try and fetch it // This is not our bug, but good luck getting google to fix it. - if (strpos($href,'http:') === 0 && strpos($href,'youtu') !== false) { - $href = str_replace('http:','https:', $href); - } + //if (strpos($href,'http:') === 0 && strpos($href,'youtu') !== false) { + // $href = str_replace('http:','https:', $href); + //} $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); if($x['success']) @@ -203,7 +204,7 @@ function oembed_fetch_url($embedurl){ logger('fetch failed: ' . $href); break; } - // soundcloud is now using text/json+oembed instead of application/json+oembed, + // soundcloud is now using text/json+oembed instead of application/json+oembed, // others may be also $entries = $xpath->query("//link[@type='text/json+oembed']"); foreach($entries as $e){ @@ -218,18 +219,18 @@ function oembed_fetch_url($embedurl){ } } } - + if ($txt==false || $txt=="") { $x = array('url' => $embedurl,'videowidth' => App::$videowidth); call_hooks('oembed_probe',$x); if(array_key_exists('embed',$x)) $txt = $x['embed']; } - + $txt=trim($txt); if ($txt[0]!="{") $txt='{"type":"error"}'; - + // save in cache if(! get_config('system','oembed_cache_disable')) @@ -252,7 +253,7 @@ function oembed_fetch_url($embedurl){ // some sites wrap their entire embed in an iframe // which we will purify away and which we provide anyway. - // So if we see this, grab the frame src url and use that + // So if we see this, grab the frame src url and use that // as the embed content - which will still need to be purified. if(preg_match('#\<iframe(.*?)src\=[\'\"](.*?)[\'\"]#',$j['html'],$matches)) { @@ -261,16 +262,16 @@ function oembed_fetch_url($embedurl){ } logger('frame src: ' . $j['html'], LOGGER_DATA); - + $j['html'] = purify_html($j['html'],$allow_position); if($j['html'] != $orig) { - logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j['html'], LOGGER_DEBUG, LOG_INFO); + logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j['html'], LOGGER_DEBUG, LOG_INFO); } $orig_len = mb_strlen(preg_replace('/\s+/','',$orig)); $new_len = mb_strlen(preg_replace('/\s+/','',$j['html'])); - if(stripos($orig,'<script') || (! $new_len)) + if(stripos($orig,'<script') || (! $new_len)) $j['type'] = 'error'; elseif($orig_len) { $ratio = $new_len / $orig_len; @@ -292,7 +293,7 @@ function oembed_fetch_url($embedurl){ } - + function oembed_format_object($j){ $embedurl = $j['embedurl']; @@ -308,7 +309,7 @@ function oembed_format_object($j){ $tw = (isset($j['thumbnail_width'])) ? $j['thumbnail_width'] : 200; $th = (isset($j['thumbnail_height'])) ? $j['thumbnail_height'] : 180; $tr = $tw/$th; - + $th=120; $tw = $th*$tr; $tpl=get_markup_template('oembed_video.tpl'); @@ -320,7 +321,7 @@ function oembed_format_object($j){ '$th'=>$th, '$turl'=> $j['thumbnail_url'], )); - + } else { $ret=$jhtml; } @@ -329,7 +330,7 @@ function oembed_format_object($j){ case "photo": { $ret.= "<img width='".$j['width']."' src='".$j['url']."'>"; $ret.="<br>"; - }; break; + }; break; case "link": { if($j['thumbnail_url']) { if(is_matrix_url($embedurl)) { @@ -340,14 +341,14 @@ function oembed_format_object($j){ } //$ret = "<a href='".$embedurl."'>".$j['title']."</a>"; - }; break; + }; break; case 'pdf': { $ret = $j['html']; break; } case "rich": { - // not so safe.. + // not so safe.. if($j['zrl']) { $ret = ((preg_match('/^<div[^>]+>(.*?)<\/div>$/is',$j['html'],$o)) ? $o[1] : $j['html']); } else { @@ -382,7 +383,7 @@ function oembed_iframe($src,$width,$height) { $scroll = ' scrolling="auto" '; } - // try and leave some room for the description line. + // try and leave some room for the description line. $height = intval($height) + 80; $width = intval($width) + 40; @@ -390,8 +391,8 @@ function oembed_iframe($src,$width,$height) { // Make sure any children are sandboxed within their own iframe. - return '<iframe ' . $scroll . 'height="' . $height . '" width="' . $width . '" src="' . $s . '" allowfullscreen frameborder="no" >' - . t('Embedded content') . '</iframe>'; + return '<iframe ' . $scroll . 'height="' . $height . '" width="' . $width . '" src="' . $s . '" allowfullscreen frameborder="no" >' + . t('Embedded content') . '</iframe>'; } @@ -418,7 +419,7 @@ function oe_get_inner_html( $node ) { $innerHTML .= $child->ownerDocument->saveXML( $child ); } return $innerHTML; -} +} /** * Find <span class='oembed'>..<a href='url' rel='oembed'>..</a></span> @@ -427,17 +428,20 @@ function oe_get_inner_html( $node ) { function oembed_html2bbcode($text) { // start parser only if 'oembed' is in text if (strpos($text, "oembed")){ - + // convert non ascii chars to html entities $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text)); - + // If it doesn't parse at all, just return the text. - $dom = @DOMDocument::loadHTML($html_text); + + $dom = new DOMDocument; + @$dom->loadHTML($html_text); if(! $dom) return $text; + $xpath = new DOMXPath($dom); $attr = "oembed"; - + $xattr = oe_build_xpath("class","oembed"); $entries = $xpath->query("//span[$xattr]"); @@ -449,7 +453,7 @@ function oembed_html2bbcode($text) { return oe_get_inner_html( $dom->getElementsByTagName("body")->item(0) ); } else { return $text; - } + } } diff --git a/include/permissions.php b/include/permissions.php index c7eee11f4..9dd503132 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -6,7 +6,7 @@ require_once('include/security.php'); * @file include/permissions.php * * This file conntains functions to check and work with permissions. - * + * */ @@ -27,7 +27,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ $api = App::get_oauth_key(); if($api) - return get_all_api_perms($uid,$api); + return get_all_api_perms($uid,$api); $global_perms = \Zotlabs\Access\Permissions::Perms(); @@ -210,7 +210,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ $ret[$perm_name] = false; continue; } - + $ret[$perm_name] = true; continue; } @@ -294,14 +294,14 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = if($channel_perm & PERMS_AUTHED) return true; - $x = q("select abook_my_perms, abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash + $x = q("select abook_my_perms, abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_xchan = '%s' and abook_self = 0 limit 1", intval($uid), dbesc($observer_xchan) ); // If they're blocked - they can't read or write - + if(($x) && intval($x[0]['abook_blocked'])) return false; @@ -324,9 +324,9 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = // This requires an explanation and the effects are subtle. // The following line creates a fake connection, and this allows - // access tokens to have specific permissions even though they are + // access tokens to have specific permissions even though they are // not actual connections. - // The existence of this fake entry must be checked when dealing + // The existence of this fake entry must be checked when dealing // with connection related permissions. $x = array(pseudo_abook($y[0])); @@ -343,7 +343,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = return false; // Check if this $uid is actually the $observer_xchan - // you will have full access unless the channel was moved - + // you will have full access unless the channel was moved - // in which case you will have read_only access if($r[0]['channel_hash'] === $observer_xchan) { @@ -366,7 +366,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = // If we're still here, we have an observer, check the network. if($channel_perm & PERMS_NETWORK) { - if ($x && in_array($x[0]['xchan_network'], ['zot','zot6'])) + if ($x && in_array($x[0]['xchan_network'], ['zot','zot6'])) return true; } @@ -382,7 +382,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = return false; } - // From here on we require that the observer be a connection or pseudo connection + // From here on we require that the observer be a connection or pseudo connection if(! $x) { return false; @@ -425,7 +425,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = return false; } -function get_all_api_perms($uid,$api) { +function get_all_api_perms($uid,$api) { $global_perms = \Zotlabs\Access\Permissions::Perms(); @@ -541,7 +541,8 @@ function site_default_perms() { 'write_pages' => PERMS_SPECIFIC, 'write_wiki' => PERMS_SPECIFIC, 'delegate' => PERMS_SPECIFIC, - 'post_like' => PERMS_NETWORK + 'republish' => PERMS_SPECIFIC, + 'post_like' => PERMS_NETWORK, ); $global_perms = \Zotlabs\Access\Permissions::Perms(); diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 87b1d96fe..8de5185af 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -111,7 +111,7 @@ function guess_image_type($filename, $data = '') { elseif (is_array($data) && array_key_exists('body', $data)) $body = $data['body']; if ($body) { - $image = new Imagick($filename); + $image = new Imagick(); $image->readImageBlob($body); $r = $image->identifyImage(); if ($r && is_array($r) && array_key_exists($r['mimetype'], $types)) diff --git a/include/plugin.php b/include/plugin.php index 269903373..5b041f228 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -929,8 +929,9 @@ function script_path() { } function head_add_js($src, $priority = 0) { - if(! is_array(App::$js_sources[$priority])) - App::$js_sources[$priority] = array(); + if(isset(App::$js_sources[$priority]) && !is_array(App::$js_sources[$priority])) + App::$js_sources[$priority] = []; + App::$js_sources[$priority][] = $src; } diff --git a/include/queue_fn.php b/include/queue_fn.php index b72730d2f..1e8171b1d 100644 --- a/include/queue_fn.php +++ b/include/queue_fn.php @@ -132,7 +132,7 @@ function queue_deliver($outq, $immediate = false) { $base = null; $h = parse_url($outq['outq_posturl']); if($h !== false) - $base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : ''); + $base = $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : ''); if(($base) && ($base !== z_root()) && ($immediate)) { $y = q("select site_update, site_dead from site where site_url = '%s' ", diff --git a/include/security.php b/include/security.php index 40905925f..066b1dcf4 100644 --- a/include/security.php +++ b/include/security.php @@ -18,6 +18,7 @@ function authenticate_success($user_record, $channel = null, $login_initial = fa $_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; $lastlog_updated = false; + $uid_to_load = null; if (x($user_record, 'account_id')) { App::$account = $user_record; diff --git a/include/taxonomy.php b/include/taxonomy.php index 7745b6a5b..f765a9f0e 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -331,11 +331,11 @@ function pubtagblock($net,$site,$limit,$recent = 0,$safemode = 1, $type = TERM_H } -function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { - - $item_normal = item_normal(); - $count = intval($limit); - +function pub_tagadelic($net, $site, $limit, $recent, $safemode, $type) { + + $item_normal = item_normal(); + $count = intval($limit); + $sql_extra = ""; if($site) $uids = " and item.uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) and item_private = 0 and item_wall = 1 "; else { @@ -345,7 +345,7 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { } if($recent) - $sql_extra .= " and item.created > '" . datetime_convert('UTC','UTC', 'now - ' . intval($recent) . ' days ') . "' "; + $sql_extra .= " and item.created > NOW() - INTERVAL " . db_quoteinterval(intval($recent) . ' DAY') . " "; if($safemode) { diff --git a/include/text.php b/include/text.php index 1e08d136c..85950c58b 100644 --- a/include/text.php +++ b/include/text.php @@ -9,6 +9,7 @@ use Michelf\MarkdownExtra; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\SvgSanitizer; require_once("include/bbcode.php"); @@ -1541,39 +1542,46 @@ function unobscure_mail(&$item) { function theme_attachments(&$item) { + $s = ''; $arr = json_decode($item['attach'],true); - if(is_array($arr) && count($arr)) { - $attaches = array(); + + $attaches = []; foreach($arr as $r) { - $icon = getIconFromType($r['type']); + if(isset($r['type'])) + $icon = getIconFromType($r['type']); - if($r['title']) + if(isset($r['title'])) $label = urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')); - if(! $label && $r['href']) + if(! $label && isset($r['href'])) $label = basename($r['href']); //some feeds provide an attachment where title an empty space if(! $label || $label == ' ') $label = t('Unknown Attachment'); - $title = t('Size') . ' ' . (($r['length']) ? userReadableSize($r['length']) : t('unknown')); + $title = t('Size') . ' ' . (isset($r['length']) ? userReadableSize($r['length']) : t('unknown')); require_once('include/channel.php'); - if(is_foreigner($item['author_xchan'])) - $url = $r['href']; - else - $url = z_root() . '/magic?f=&owa=1&hash=' . $item['author_xchan'] . '&bdest=' . bin2hex($r['href'] . '/' . $r['revision']); + + if (isset($r['href'])) { + if(is_foreigner($item['author_xchan'])) + $url = $r['href']; + else + $url = z_root() . '/magic?f=&owa=1&hash=' . $item['author_xchan'] . '&bdest=' . bin2hex($r['href'] . '/' . $r['revision']); + } //$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; - $attaches[] = array('label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title); + if (isset($label) && isset($url) && isset($icon) && isset($title)) + $attaches[] = array('label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title); } - $s = replace_macros(get_markup_template('item_attach.tpl'), array( - '$attaches' => $attaches - )); + if (count($attaches) > 0) + $s = replace_macros(get_markup_template('item_attach.tpl'), [ + '$attaches' => $attaches + ]); } return $s; @@ -1611,8 +1619,8 @@ function format_categories(&$item,$writeable) { */ function format_hashtags(&$item) { - $s = ''; + $s = ''; $terms = get_terms_oftype($item['term'], array(TERM_HASHTAG,TERM_COMMUNITYTAG)); if($terms) { foreach($terms as $t) { @@ -1634,13 +1642,14 @@ function format_hashtags(&$item) { } - function format_mentions(&$item) { - $s = ''; + $s = ''; $terms = get_terms_oftype($item['term'],TERM_MENTION); if($terms) { foreach($terms as $t) { + if(! isset($t['term'])) + continue; $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; if(! trim($term)) continue; @@ -2836,7 +2845,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) // replace tag by the link. Make sure to not replace something in the middle of a word - $body = preg_replace('/(?<![a-zA-Z0-9=])'.preg_quote($tag,'/').'/', $newtag, $body); + $body = preg_replace('/(?<![a-zA-Z0-9=\/])'.preg_quote($tag,'/').'/', $newtag, $body); $replaced = true; } @@ -3248,7 +3257,7 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') { $item['body'] = preg_replace("/(\[zrl=".preg_quote($old,'/')."\/(photo|photos|gallery)\/".$channel['channel_address'].".+\]\[zmg=\d+x\d+\])".preg_quote($old,'/')."\/(.+\[\/zmg\])/", '${1}'.$new.'/${3}', $item['body']); $item['body'] = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']); - $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); + $item['sig'] = base64url_encode(Crypto::sign($item['body'],$channel['channel_prvkey'])); $item['item_verified'] = 1; $item['plink'] = str_replace($old,$new,$item['plink']); @@ -3682,7 +3691,7 @@ function get_forum_channels($uid) { if(! $uid) return; - if(App::$data['forum_channels']) + if(isset(App::$data['forum_channels'])) return App::$data['forum_channels']; $xf = ''; @@ -3881,6 +3890,14 @@ function unserialise($x) { return ((is_array($y)) ? $y : $x); } +function obscurify($s) { + return str_rot47(base64url_encode($s)); +} + +function unobscurify($s) { + return base64url_decode(str_rot47($s)); +} + /** * @brief Remove new lines and tabs from strings. * diff --git a/include/xchan.php b/include/xchan.php index 5de828e7f..07fdb8b47 100644 --- a/include/xchan.php +++ b/include/xchan.php @@ -1,5 +1,6 @@ <?php +use Zotlabs\Lib\Crypto; use Zotlabs\Web\HTTPSig; use Zotlabs\Lib\Libzot; @@ -85,7 +86,7 @@ function xchan_store($arr) { } if($arr['network'] === 'zot') { - if((! $arr['key']) || (! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key']))) { + if((! $arr['key']) || (! Crypto::verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key']))) { logger('Unable to verify signature for ' . $arr['hash']); return false; } @@ -102,7 +103,7 @@ function xchan_store($arr) { if($k === 'photo') { continue; } - + if(in_array($columns,'xchan_' . $k)) $x['xchan_' . $k] = escape_tags($v); } @@ -112,7 +113,7 @@ function xchan_store($arr) { $x['xchan_system'] = false; $result = xchan_store_lowlevel($x); - + if(! $result) return $result; } @@ -207,9 +208,9 @@ function xchan_keychange_acl($table,$column,$oldxchan,$newxchan) { if($r) { foreach($r as $rv) { $z = q("update $table set $allow = '%s', $deny = '%s' where $column = %d", - dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', + dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', $rv[$allow])), - dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', + dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', $rv[$deny])), intval($rv[$column]) ); @@ -243,7 +244,7 @@ function xchan_change_key($oldx,$newx,$data) { 'xprof' => 'xprof_hash', 'xtag' => 'xtag_hash' ]; - + $acls = [ 'channel' => 'channel_id', diff --git a/include/zid.php b/include/zid.php index e24b0035d..75414a691 100644 --- a/include/zid.php +++ b/include/zid.php @@ -58,7 +58,7 @@ function zid($s, $address = '') { $mine_parsed = parse_url($mine); $s_parsed = parse_url($s); - if($mine_parsed['host'] === $s_parsed['host']) + if(isset($mine_parsed['host']) && isset($s_parsed['host']) && $mine_parsed['host'] === $s_parsed['host']) $url_match = true; if ($mine && $myaddr && (! $url_match)) @@ -209,21 +209,21 @@ function red_zrl_callback($matches) { // Catch and exclude trailing punctuation preg_match("/[.,;:!?)]*$/i", $matches[2], $pts); $matches[2] = substr($matches[2], 0, strlen($matches[2])-strlen($pts[0])); - + $zrl = is_matrix_url($matches[2]); - + $t = strip_zids($matches[2]); if($t !== $matches[2]) { $zrl = true; $matches[2] = $t; } - + if($matches[1] === '#^') $matches[1] = ''; - + if($zrl) return $matches[1] . '#^[zrl=' . $matches[2] . ']' . $matches[2] . '[/zrl]' . $pts[0]; - + return $matches[1] . '#^[url=' . $matches[2] . ']' . $matches[2] . '[/url]' . $pts[0]; } diff --git a/include/zot.php b/include/zot.php index d61873ba2..634561fa3 100644 --- a/include/zot.php +++ b/include/zot.php @@ -8,6 +8,7 @@ * */ +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\DReport; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Activity; @@ -123,15 +124,15 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot 'type' => $type, 'sender' => [ 'guid' => $channel['channel_guid'], - 'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), + 'guid_sig' => base64url_encode(Crypto::sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), 'url' => z_root(), - 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)), + 'url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'],$sig_method)), 'sitekey' => get_config('system','pubkey') ], 'callback' => '/post', 'version' => Zotlabs\Lib\System::get_zot_revision(), - 'encryption' => crypto_methods(), - 'signing' => signing_methods() + 'encryption' => Crypto::methods(), + 'signing' => Crypto::signing_methods() ]; if ($recipients) { @@ -143,7 +144,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot if ($secret) { $data['secret'] = preg_replace('/[^0-9a-fA-F]/','',$secret); - $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method)); + $data['secret_sig'] = base64url_encode(Crypto::sign($secret,$channel['channel_prvkey'],$sig_method)); } if ($extra) { @@ -157,7 +158,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot if($remote_key) { $algorithm = zot_best_algorithm($methods); - $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + $data = Crypto::encapsulate(json_encode($data),$remote_key, $algorithm); } return json_encode($data); @@ -197,15 +198,15 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg 'type' => $type, 'sender' => [ 'guid' => $channel['channel_guid'], - 'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), + 'guid_sig' => base64url_encode(Crypto::sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), 'url' => z_root(), - 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)), + 'url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'],$sig_method)), 'sitekey' => get_config('system','pubkey') ], 'callback' => '/post', 'version' => Zotlabs\Lib\System::get_zot_revision(), - 'encryption' => crypto_methods(), - 'signing' => signing_methods() + 'encryption' => Crypto::methods(), + 'signing' => Crypto::signing_methods() ]; if ($recipients) { @@ -221,7 +222,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg if ($secret) { $data['secret'] = preg_replace('/[^0-9a-fA-F]/','',$secret); - $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method)); + $data['secret_sig'] = base64url_encode(Crypto::sign($secret,$channel['channel_prvkey'],$sig_method)); } if ($extra) { @@ -235,7 +236,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg if($remote_key) { $algorithm = zot_best_algorithm($methods); - $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + $data = Crypto::encapsulate(json_encode($data),$remote_key, $algorithm); } return json_encode($data); @@ -249,7 +250,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg * * @param string $methods * comma separated list of encryption methods - * @return string first match from our site method preferences crypto_methods() array + * @return string first match from our site method preferences Crypto::methods() array * of a method which is common to both sites; or 'aes256cbc' if no matches are found. */ function zot_best_algorithm($methods) { @@ -272,7 +273,7 @@ function zot_best_algorithm($methods) { if($methods) { $x = explode(',', $methods); if($x) { - $y = crypto_methods(); + $y = Crypto::methods(); if($y) { foreach($y as $yv) { $yv = trim($yv); @@ -443,7 +444,7 @@ function zot_refresh($them, $channel = null, $force = false) { $signed_token = ((is_array($j) && array_key_exists('signed_token',$j)) ? $j['signed_token'] : null); if($signed_token) { - $valid = rsa_verify('token.' . $token,base64url_decode($signed_token),$j['key']); + $valid = Crypto::verify('token.' . $token,base64url_decode($signed_token),$j['key']); if(! $valid) { logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_ERR); return false; @@ -461,16 +462,18 @@ function zot_refresh($them, $channel = null, $force = false) { if($channel) { if($j['permissions']['data']) { - $permissions = crypto_unencapsulate( + $permissions = Crypto::unencapsulate( [ + 'encrypted' => true, 'data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], 'iv' => $j['permissions']['iv'], 'alg' => $j['permissions']['alg'] ], $channel['channel_prvkey']); - if($permissions) + if($permissions) { $permissions = json_decode($permissions,true); + } logger('decrypted permissions: ' . print_r($permissions,true), LOGGER_DATA, LOG_DEBUG); } else @@ -719,8 +722,8 @@ function zot_register_hub($arr) { */ foreach($sig_methods as $method) { - if((rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key'],$method)) - && (rsa_verify($arr['url'],base64url_decode($arr['url_sig']),$record['key'],$method)) + if((Crypto::verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key'],$method)) + && (Crypto::verify($arr['url'],base64url_decode($arr['url_sig']),$record['key'],$method)) && ($arr['guid'] === $record['guid']) && ($arr['guid_sig'] === $record['guid_sig'])) { $c = import_xchan($record); @@ -790,7 +793,7 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $verified = false; foreach($sig_methods as $method) { - if(! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'],$method)) { + if(! Crypto::verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'],$method)) { logger('Unable to verify channel signature for ' . $arr['address'] . ' using ' . $method); continue; } @@ -925,28 +928,28 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $local = q("select channel_account_id, channel_id from channel where channel_portable_id = '%s' limit 1", dbesc($xchan_hash) ); - + if($local) { - // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied + // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied // on most hubs in the network // <--- $ph = z_fetch_url($arr['photo'], true); - + if($ph['success']) { - + // Do not fetch already received thumbnails $x = q("SELECT resource_id FROM photo WHERE uid = %d AND imgscale = %d AND filesize = %d LIMIT 1", intval($local[0]['channel_id']), intval(PHOTO_RES_PROFILE_300), strlen($ph['body']) - ); + ); if($x) $hash = $x[0]['resource_id']; else $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']); } - + if($hash) { // unless proven otherwise $is_default_profile = 1; @@ -972,7 +975,7 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { } } // ---> - + // reset the names in case they got messed up when we had a bug in this function $photos = array( z_root() . '/photo/profile/l/' . $local[0]['channel_id'], @@ -1128,7 +1131,8 @@ function zot_process_response($hub, $arr, $outq) { if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) { if(array_key_exists('iv',$x['delivery_report'])) { - $j = crypto_unencapsulate($x['delivery_report'],get_config('system','prvkey')); + $x['delivery_report']['encrypted'] = true; + $j = Crypto::unencapsulate($x['delivery_report'],get_config('system','prvkey')); if($j) { $x['delivery_report'] = json_decode($j,true); } @@ -1253,14 +1257,14 @@ function zot_fetch($arr) { $data = [ 'type' => 'pickup', 'url' => z_root(), - 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post', get_config('system','prvkey'))), + 'callback_sig' => base64url_encode(Crypto::sign(z_root() . '/post', get_config('system','prvkey'))), 'callback' => z_root() . '/post', 'secret' => $secret, - 'secret_sig' => base64url_encode(rsa_sign($secret, get_config('system','prvkey'))) + 'secret_sig' => base64url_encode(Crypto::sign($secret, get_config('system','prvkey'))) ]; $algorithm = zot_best_algorithm($hub['site_crypto']); - $datatosend = json_encode(crypto_encapsulate(json_encode($data),$hub['hubloc_sitekey'], $algorithm)); + $datatosend = json_encode(Crypto::encapsulate(json_encode($data),$hub['hubloc_sitekey'], $algorithm)); $import = zot_zot($url,$datatosend); @@ -1272,7 +1276,7 @@ function zot_fetch($arr) { $result = zot_import($import, $arr['sender']['url']); if($result) { - $result = crypto_encapsulate(json_encode($result),$hub['hubloc_sitekey'], $algorithm); + $result = Crypto::encapsulate(json_encode($result),$hub['hubloc_sitekey'], $algorithm); return $result; } @@ -1314,7 +1318,8 @@ function zot_import($arr, $sender_url) { } if(array_key_exists('iv', $data)) { - $data = json_decode(crypto_unencapsulate($data,get_config('system','prvkey')),true); + $data['encrypted'] = true; + $data = json_decode(Crypto::unencapsulate($data,get_config('system','prvkey')),true); } if(! is_array($data)) { @@ -1342,7 +1347,8 @@ function zot_import($arr, $sender_url) { $result = null; if(array_key_exists('iv',$i['notify'])) { - $i['notify'] = json_decode(crypto_unencapsulate($i['notify'],get_config('system','prvkey')),true); + $i['notify']['encrypted'] = true; + $i['notify'] = json_decode(Crypto::unencapsulate($i['notify'],get_config('system','prvkey')),true); } logger('Notify: ' . print_r($i['notify'],true), LOGGER_DATA, LOG_DEBUG); @@ -2466,7 +2472,7 @@ function process_rating_delivery($sender, $arr) { dbesc($sender['hash']) ); - if((! $z) || (! rsa_verify($arr['target'] . '.' . $arr['rating'] . '.' . $arr['rating_text'], base64url_decode($arr['signature']),$z[0]['xchan_pubkey']))) { + if((! $z) || (! Crypto::verify($arr['target'] . '.' . $arr['rating'] . '.' . $arr['rating_text'], base64url_decode($arr['signature']),$z[0]['xchan_pubkey']))) { logger('failed to verify rating'); return; } @@ -2652,7 +2658,7 @@ function sync_locations($sender, $arr, $absolute = false) { $arr['locations'][0]['primary'] = true; foreach($arr['locations'] as $location) { - if(! rsa_verify($location['url'],base64url_decode($location['url_sig']),$sender['key'])) { + if(! Crypto::verify($location['url'],base64url_decode($location['url_sig']),$sender['key'])) { logger('Unable to verify site signature for ' . $location['url']); $ret['message'] .= sprintf( t('Unable to verify site signature for %s'), $location['url']) . EOL; continue; @@ -3126,7 +3132,7 @@ function import_site($arr, $pubkey) { if( (! is_array($arr)) || (! $arr['url']) || (! $arr['url_sig'])) return false; - if(! rsa_verify($arr['url'], base64url_decode($arr['url_sig']), $pubkey)) { + if(! Crypto::verify($arr['url'], base64url_decode($arr['url_sig']), $pubkey)) { logger('Bad url_sig'); return false; } @@ -3509,12 +3515,12 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if($keychange) { // verify the keychange operation - if(! rsa_verify($arr['channel']['channel_pubkey'],base64url_decode($arr['keychange']['new_sig']),$channel['channel_prvkey'])) { + if(! Crypto::verify($arr['channel']['channel_pubkey'],base64url_decode($arr['keychange']['new_sig']),$channel['channel_prvkey'])) { logger('sync keychange: verification failed'); continue; } - $sig = base64url_encode(rsa_sign($channel['channel_guid'],$arr['channel']['channel_prvkey'])); + $sig = base64url_encode(Crypto::sign($channel['channel_guid'],$arr['channel']['channel_prvkey'])); $hash = make_xchan_hash($channel['channel_guid'],$sig); @@ -3551,7 +3557,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { foreach($h as $hv) { $hv['hubloc_guid_sig'] = $sig; $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])); + $hv['hubloc_url_sig'] = base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])); hubloc_store_lowlevel($hv); } } @@ -4329,7 +4335,7 @@ function zot_rekey_request($sender,$data) { $xchan = $r[0]; - if(! rsa_verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) { + if(! Crypto::verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) { json_return_and_die($ret); } @@ -4367,7 +4373,7 @@ function zotinfo($arr) { $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0); if($ztarget) { - if((! $zkey) || (! $zsig) || (! rsa_verify($ztarget,base64url_decode($zsig),$zkey))) { + if((! $zkey) || (! $zsig) || (! Crypto::verify($ztarget,base64url_decode($zsig),$zkey))) { logger('zfinger: invalid target signature'); $ret['message'] = t("invalid target signature"); return($ret); @@ -4531,7 +4537,7 @@ function zotinfo($arr) { // Communication details if($token) - $ret['signed_token'] = base64url_encode(rsa_sign('token.' . $token,$e['channel_prvkey'],$sig_method)); + $ret['signed_token'] = base64url_encode(Crypto::sign('token.' . $token,$e['channel_prvkey'],$sig_method)); $ret['guid'] = $e['xchan_guid']; @@ -4587,7 +4593,7 @@ function zotinfo($arr) { // because ztarget refers to an xchan and we don't necessarily know the origination // location. - $ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions); + $ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey,) : $permissions); if($permissions['view_profile']) $ret['profile'] = $profile; @@ -4622,9 +4628,9 @@ function zot_site_info($channel_key = '') { $ret['site'] = []; $ret['site']['url'] = z_root(); if($channel_key) { - $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$channel_key,$sig_method)); + $ret['site']['url_sig'] = base64url_encode(Crypto::sign(z_root(),$channel_key,$sig_method)); } - $ret['site']['url_site_sig'] = base64url_encode(rsa_sign(z_root(),$signing_key,$sig_method)); + $ret['site']['url_site_sig'] = base64url_encode(Crypto::sign(z_root(),$signing_key,$sig_method)); $ret['site']['post'] = z_root() . '/post'; $ret['site']['openWebAuth'] = z_root() . '/owa'; $ret['site']['authRedirect'] = z_root() . '/magic'; @@ -4644,8 +4650,8 @@ function zot_site_info($channel_key = '') { $ret['site']['directory_url'] = z_root() . '/dirsearch'; - $ret['site']['encryption'] = crypto_methods(); - $ret['site']['signing'] = signing_methods(); + $ret['site']['encryption'] = Crypto::methods(); + $ret['site']['signing'] = Crypto::signing_methods(); $ret['site']['zot'] = Zotlabs\Lib\System::get_zot_revision(); // hide detailed site information if you're off the grid @@ -4724,7 +4730,7 @@ function check_zotinfo($channel, $locations, &$ret) { // the sys channel must have a location (hubloc) $valid_location = false; if((count($locations) === 1) && ($locations[0]['primary']) && (! $locations[0]['deleted'])) { - if((rsa_verify($locations[0]['url'],base64url_decode($locations[0]['url_sig']),$channel['channel_pubkey'])) + if((Crypto::verify($locations[0]['url'],base64url_decode($locations[0]['url_sig']),$channel['channel_pubkey'])) && ($locations[0]['sitekey'] === get_config('system','pubkey')) && ($locations[0]['url'] === z_root())) $valid_location = true; @@ -4752,7 +4758,7 @@ function check_zotinfo($channel, $locations, &$ret) { 'hubloc_network' => 'zot', 'hubloc_primary' => 1, 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])), 'hubloc_host' => App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => get_config('system','pubkey'), @@ -4931,7 +4937,7 @@ function zot_reply_ping() { $ret['success'] = true; $ret['site'] = array(); $ret['site']['url'] = z_root(); - $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),get_config('system','prvkey'))); + $ret['site']['url_sig'] = base64url_encode(Crypto::sign(z_root(),get_config('system','prvkey'))); $ret['site']['sitekey'] = get_config('system','pubkey'); json_return_and_die($ret); @@ -4979,10 +4985,10 @@ function zot_reply_pickup($data) { logger('mod_zot: Checking sitekey: ' . $sitekey, LOGGER_DATA, LOG_DEBUG); - if(rsa_verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { + if(Crypto::verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { $forgery = false; } - if(rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { + if(Crypto::verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { $secret_fail = false; } if((! $forgery) && (! $secret_fail)) @@ -5076,7 +5082,7 @@ function zot_reply_pickup($data) { ); $algorithm = zot_best_algorithm(($x) ? $x[0]['site_crypto'] : ''); - $encrypted = crypto_encapsulate(json_encode($ret),$sitekey,$algorithm); + $encrypted = Crypto::encapsulate(json_encode($ret),$sitekey,$algorithm); json_return_and_die($encrypted); // @FIXME: There is a possibility that the transmission will get interrupted @@ -5133,7 +5139,7 @@ function zot_reply_auth_check($data,$encrypted_packet) { // First verify their signature. We will have obtained a zot-info packet from them as part of the sender // verification. - if ((! $y) || (! rsa_verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) { + if ((! $y) || (! Crypto::verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) { logger('mod_zot: auth_check: sender not found or secret_sig invalid.'); $ret['message'] .= 'sender not found or sig invalid ' . print_r($y,true) . EOL; @@ -5158,7 +5164,7 @@ function zot_reply_auth_check($data,$encrypted_packet) { json_return_and_die($ret); } - $confirm = base64url_encode(rsa_sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey'])); + $confirm = base64url_encode(Crypto::sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey'])); // This additionally checks for forged sites since we already stored the expected result in meta // and we've already verified that this is them via zot_gethub() and that their key signed our token |