X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=jappixmini%2Fjappixmini.php;h=faac6a815477a45712baa2c9835628948f3a0991;hb=d9330e3b05c71bbd172293fb223271033d3b19f7;hp=889594486061455d47e837b71aeabfe860b9303c;hpb=60a7952688aa41c25106b2a05cad1f9ecf223e48;p=friendica-addons.git diff --git a/jappixmini/jappixmini.php b/jappixmini/jappixmini.php index 88959448..faac6a81 100644 --- a/jappixmini/jappixmini.php +++ b/jappixmini/jappixmini.php @@ -1,324 +1,618 @@ + * + */ +// +// Copyright 2012 "Leberwurscht" +// +// This file is dual-licensed under the MIT license (see MIT.txt) and the AGPL license (see jappix/COPYING). +// /* -Problem: -* jabber password should not be stored on server -* jabber password should not be sent between server and browser as soon as the user is logged in -* jabber password should not be reconstructible from communication between server and browser as soon as the user is logged in - -Solution: -Only store an encrypted version of the jabber password on the server. The encryption key is only available to the browser -and not to the server (at least as soon as the user is logged in). It can be stored using the jappix setDB function. + Problem: + * jabber password should not be stored on server + * jabber password should not be sent between server and browser as soon as the user is logged in + * jabber password should not be reconstructible from communication between server and browser as soon as the user is logged in + + Solution: + Only store an encrypted version of the jabber password on the server. The encryption key is only available to the browser + and not to the server (at least as soon as the user is logged in). It can be stored using the jappix setDB function. + + This encryption key could be the friendica password, but then this password would be stored in the browser in cleartext. + It is better to use a hash of the password. + The server should not be able to reconstruct the password, so we can't take the same hash the server stores. But we can + use hash("some_prefix"+password). This will however not work with OpenID logins, for this type of login the password must + be queried manually. + + Problem: + How to discover the jabber addresses of the friendica contacts? + + Solution: + Each Friendica site with this addon provides a /jappixmini/ module page. We go through our contacts and retrieve + this information every week using a cron hook. + + Problem: + We do not want to make the jabber address public. + + Solution: + When two friendica users connect using DFRN, the relation gets a DFRN ID and a keypair is generated. + Using this keypair, we can provide the jabber address only to contacts: + + Alice: + signed_address = openssl_*_encrypt(alice_jabber_address) + send signed_address to Bob, who does + trusted_address = openssl_*_decrypt(signed_address) + save trusted_address + encrypted_address = openssl_*_encrypt(bob_jabber_address) + reply with encrypted_address to Alice, who does + decrypted_address = openssl_*_decrypt(encrypted_address) + save decrypted_address + + Interface for this: + GET /jappixmini/?role=%s&signed_address=%s&dfrn_id=%s + + Response: + json({"status":"ok", "encrypted_address":"%s"}) + + */ + +use Friendica\App; +use Friendica\Core\Config; +use Friendica\Core\PConfig; +use Friendica\Model\User; + +function jappixmini_install() +{ + register_hook('plugin_settings', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings'); + register_hook('plugin_settings_post', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings_post'); + + register_hook('page_end', 'addon/jappixmini/jappixmini.php', 'jappixmini_script'); + register_hook('authenticate', 'addon/jappixmini/jappixmini.php', 'jappixmini_login'); + + register_hook('cron', 'addon/jappixmini/jappixmini.php', 'jappixmini_cron'); + + // Jappix source download as required by AGPL + register_hook('about_hook', 'addon/jappixmini/jappixmini.php', 'jappixmini_download_source'); + + // set standard configuration + $info_text = Config::get("jappixmini", "infotext"); + if (!$info_text) + set_confConfig::setig("jappixmini", "infotext", "To get the chat working, you need to know a BOSH host which works with your Jabber account. " . + "An example of a BOSH server that works for all accounts is https://bind.jappix.com/, but keep " . + "in mind that the BOSH server can read along all chat messages. If you know that your Jabber " . + "server also provides an own BOSH server, it is much better to use this one!" + ); -This encryption key could be the friendica password, but then this password would be stored in the browser in cleartext. -It is better to use a hash of the password. -The server should not be able to reconstruct the password, so we can't take the same hash the server stores. But we can - use hash("some_prefix"+password). This will however not work with OpenID logins. + $bosh_proxy = Config::get("jappixmini", "bosh_proxy"); + if ($bosh_proxy === "") { + Config::set("jappixmini", "bosh_proxy", "1"); + } -Problem: -How to discover the jabber addresses of the friendica contacts? + // set addon version so that safe updates are possible later + $addon_version = Config::get("jappixmini", "version"); + if ($addon_version === "") { + Config::set("jappixmini", "version", "1"); + } +} -Solution: -Each Friendica site with this addon provides a /jappixmini/ module page. We go through our contacts and retrieve -this information every week using a cron hook. +function jappixmini_uninstall() +{ + unregister_hook('plugin_settings', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings'); + unregister_hook('plugin_settings_post', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings_post'); -Problem: -We do not want to make the jabber address public. + unregister_hook('page_end', 'addon/jappixmini/jappixmini.php', 'jappixmini_script'); + unregister_hook('authenticate', 'addon/jappixmini/jappixmini.php', 'jappixmini_login'); -Solution: -When two friendica users connect using DFRN, the relation gets a DFRN ID and a keypair is generated. -Using this keypair, we can provide the jabber address only to contacs: + unregister_hook('cron', 'addon/jappixmini/jappixmini.php', 'jappixmini_cron'); -Case 1: Alice has prvkey, Bob has pubkey. - Alice encrypts request - Bob decrypts the request, send jabber address unencrypted - Alice reads address + unregister_hook('about_hook', 'addon/jappixmini/jappixmini.php', 'jappixmini_download_source'); +} -Case 2: Alice has prvkey, Bob has pubkey - Alice send request - Bob encrypts jabber address - Alice decrypts jabber address +function jappixmini_plugin_admin(App $a, &$o) +{ + // display instructions and warnings on addon settings page for admin + if (!file_exists("addon/jappixmini.tgz")) { + $o .= '

The source archive jappixmini.tgz does not exist. This is probably a violation of the Jappix License (AGPL).

'; + } -*/ + // warn if cron job has not yet been executed + $cron_run = Config::get("jappixmini", "last_cron_execution"); + if (!$cron_run) { + $o .= "

Warning: The cron job has not yet been executed. If this message is still there after some time (usually 10 minutes), this means that autosubscribe and autoaccept will not work.

"; + } -function jappixmini_install() { -register_hook('plugin_settings', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings'); -register_hook('plugin_settings_post', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings_post'); + // bosh proxy + $bosh_proxy = intval(Config::get("jappixmini", "bosh_proxy")); + $bosh_proxy = intval($bosh_proxy) ? ' checked="checked"' : ''; + $o .= ''; + $o .= '
'; + + // bosh address + $bosh_address = Config::get("jappixmini", "bosh_address"); + $o .= '


'; + $o .= '

'; + + // default server address + $default_server = Config::get("jappixmini", "default_server"); + $o .= '


'; + $o .= '

'; + + // default user name to friendica nickname + $default_user = intval(Config::get("jappixmini", "default_user")); + $default_user = intval($default_user) ? ' checked="checked"' : ''; + $o .= ''; + $o .= '
'; + + // info text field + $info_text = Config::get("jappixmini", "infotext"); + $o .= '


'; + $o .= '

'; + + // submit button + $o .= ''; +} -register_hook('page_end', 'addon/jappixmini/jappixmini.php', 'jappixmini_script'); -register_hook('authenticate', 'addon/jappixmini/jappixmini.php', 'jappixmini_login'); +function jappixmini_plugin_admin_post(App $a) +{ + // set info text + $submit = $_REQUEST['jappixmini-admin-settings']; + if ($submit) { + $info_text = $_REQUEST['jappixmini-infotext']; + $bosh_proxy = intval($_REQUEST['jappixmini-proxy']); + $default_user = intval($_REQUEST['jappixmini-defaultuser']); + $bosh_address = $_REQUEST['jappixmini-address']; + $default_server = $_REQUEST['jappixmini-server']; + Config::set("jappixmini", "infotext", $info_text); + Config::set("jappixmini", "bosh_proxy", $bosh_proxy); + Config::set("jappixmini", "bosh_address", $bosh_address); + Config::set("jappixmini", "default_server", $default_server); + Config::set("jappixmini", "default_user", $default_user); + } +} -register_hook('cron', 'addon/jappixmini/jappixmini.php', 'jappixmini_cron'); +function jappixmini_module() +{ -// Jappix source download as required by AGPL -register_hook('about_hook', 'addon/jappixmini/jappixmini.php', 'jappixmini_download_source'); } +function jappixmini_init() +{ + // module page where other Friendica sites can submit Jabber addresses to and also can query Jabber addresses + // of local users + $dfrn_id = $_REQUEST["dfrn_id"]; + if (!$dfrn_id) { + killme(); + } -function jappixmini_uninstall() { -unregister_hook('plugin_settings', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings'); -unregister_hook('plugin_settings_post', 'addon/jappixmini/jappixmini.php', 'jappixmini_settings_post'); + $role = $_REQUEST["role"]; + if ($role == "pub") { + $r = q("SELECT * FROM `contact` WHERE LENGTH(`pubkey`) AND `dfrn-id`='%s' LIMIT 1", dbesc($dfrn_id)); + if (!count($r)) { + killme(); + } -unregister_hook('page_end', 'addon/jappixmini/jappixmini.php', 'jappixmini_script'); -unregister_hook('authenticate', 'addon/jappixmini/jappixmini.php', 'jappixmini_login'); + $encrypt_func = openssl_public_encrypt; + $decrypt_func = openssl_public_decrypt; + $key = $r[0]["pubkey"]; + } else if ($role == "prv") { + $r = q("SELECT * FROM `contact` WHERE LENGTH(`prvkey`) AND `issued-id`='%s' LIMIT 1", dbesc($dfrn_id)); + if (!count($r)) { + killme(); + } -unregister_hook('cron', 'addon/jappixmini/jappixmini.php', 'jappixmini_cron'); + $encrypt_func = openssl_private_encrypt; + $decrypt_func = openssl_private_decrypt; + $key = $r[0]["prvkey"]; + } else { + killme(); + } -unregister_hook('about_hook', 'addon/jappixmini/jappixmini.php', 'jappixmini_download_source'); -} + $uid = $r[0]["uid"]; -function jappixmini_plugin_admin(&$a, &$o) { - if (!file_exists("addon/jappixmini/jappix")) { - $o .= '

You need to install the Jappix application, adapted for Friendica (see README).

'; - } - else if (!file_exists("addon/jappixmini/jappix.zip")) { - $o .= '

The source archive jappix.zip does not exist. This is probably a violation of the Jappix License (see README).

'; - } -} + // save the Jabber address we received + try { + $signed_address_hex = $_REQUEST["signed_address"]; + $signed_address = hex2bin($signed_address_hex); -function jappixmini_plugin_admin_post(&$a) { -} + $trusted_address = ""; + $decrypt_func($signed_address, $trusted_address, $key); -function jappixmini_module() {} -function jappixmini_init(&$a) { - // Here, other friendica sites can fetch the jabber address of local users. - // Because we do not want to publish the addresses publicly, they are encrypted so - // that only contacts can read it. - $encrypt_for = $_REQUEST["encrypt_for"]; - if ($encrypt_for) { - $r = q("SELECT * FROM `contact` WHERE LENGTH(`pubkey`) AND `dfrn-id` = '%s' LIMIT 1", - dbesc($encrypt_for) - ); - if (!count($r)) killme(); + $now = intval(time()); + PConfig::set($uid, "jappixmini", "id:$dfrn_id", "$now:$trusted_address"); + } catch (Exception $e) { - // get public key to encrypt address - $pubkey = $r[0]['pubkey']; + } - // get jabber address - $uid = $r[0]['uid']; - $username = get_pconfig($uid, 'jappixmini', 'username'); - if (!$username) killme(); - $server = get_pconfig($uid, 'jappixmini', 'server'); - if (!$server) killme(); + // do not return an address if user deactivated plugin + $activated = PConfig::get($uid, 'jappixmini', 'activate'); + if (!$activated) { + killme(); + } - $address = $username."@".$server; + // return the requested Jabber address + try { + $username = PConfig::get($uid, 'jappixmini', 'username'); + $server = PConfig::get($uid, 'jappixmini', 'server'); + $address = "$username@$server"; - // encrypt address - $encrypted = ""; - openssl_public_encrypt($address,$encrypted,$pubkey); + $encrypted_address = ""; + $encrypt_func($address, $encrypted_address, $key); - // calculate hex representation of encrypted address - $hex = bin2hex($encrypted); + $encrypted_address_hex = bin2hex($encrypted_address); - // construct answer - $answer = Array("status"=>"ok", "encrypted_address"=>$hex); + $answer = Array( + "status" => "ok", + "encrypted_address" => $encrypted_address_hex + ); - // return answer as json - echo json_encode($answer); + $answer_json = json_encode($answer); + echo $answer_json; + killme(); + } catch (Exception $e) { killme(); } +} - // If we have only a private key, other site sends encrypted request, we answer unencrypted. - $encrypted_for = $_REQUEST["encrypted_for"]; - if (!$encrypted_for) killme(); +function jappixmini_settings(App $a, &$s) +{ + // addon settings for a user + $activate = PConfig::get(local_user(), 'jappixmini', 'activate'); + $activate = intval($activate) ? ' checked="checked"' : ''; + $dontinsertchat = PConfig::get(local_user(), 'jappixmini', 'dontinsertchat'); + $insertchat = !(intval($dontinsertchat) ? ' checked="checked"' : ''); - $encrypted_request_hex = $_REQUEST["encrypted_request"]; - if (!$encrypted_request_hex) killme(); - $encrypted_request = hex2bin($encrypted_request_hex); + $defaultbosh = Config::get("jappixmini", "bosh_address"); - $r = q("SELECT * FROM `contact` WHERE LENGTH(`prvkey`) AND `issued-id` = '%s' LIMIT 1", - dbesc($encrypted_for) - ); - if (!count($r)) killme(); + if ($defaultbosh != "") { + PConfig::set(local_user(), 'jappixmini', 'bosh', $defaultbosh); + } - // decrypt request, validate it - $prvkey = $r[0]['prvkey']; - $decrypted_request = ""; - openssl_private_decrypt($encrypted_request, $decrypted_request, $prvkey); + $username = PConfig::get(local_user(), 'jappixmini', 'username'); + $username = htmlentities($username); + $server = PConfig::get(local_user(), 'jappixmini', 'server'); + $server = htmlentities($server); + $bosh = PConfig::get(local_user(), 'jappixmini', 'bosh'); + $bosh = htmlentities($bosh); + $password = PConfig::get(local_user(), 'jappixmini', 'password'); + $autosubscribe = PConfig::get(local_user(), 'jappixmini', 'autosubscribe'); + $autosubscribe = intval($autosubscribe) ? ' checked="checked"' : ''; + $autoapprove = PConfig::get(local_user(), 'jappixmini', 'autoapprove'); + $autoapprove = intval($autoapprove) ? ' checked="checked"' : ''; + $encrypt = intval(PConfig::get(local_user(), 'jappixmini', 'encrypt')); + $encrypt_checked = $encrypt ? ' checked="checked"' : ''; + $encrypt_disabled = $encrypt ? '' : ' disabled="disabled"'; + + if ($server == "") { + $server = Config::get("jappixmini", "default_server"); + } - if ($decrypted_request!=$encrypted_for) killme(); + if (($username == "") && Config::get("jappixmini", "default_user")) { + $username = $a->user["nickname"]; + } - // get jabber address - $uid = $r[0]['uid']; - $username = get_pconfig($uid, 'jappixmini', 'username'); - if (!$username) killme(); - $server = get_pconfig($uid, 'jappixmini', 'server'); - if (!$server) killme(); + $info_text = Config::get("jappixmini", "infotext"); + $info_text = htmlentities($info_text); + $info_text = str_replace("\n", "
", $info_text); - $address = $username."@".$server; + // count contacts + $r = q("SELECT COUNT(1) as `cnt` FROM `pconfig` WHERE `uid`=%d AND `cat`='jappixmini' AND `k` LIKE 'id:%%'", local_user()); + if (count($r)) { + $contact_cnt = $r[0]["cnt"]; + } else { + $contact_cnt = 0; + } - // construct answer - $answer = Array("status"=>"ok", "address"=>$address); + // count jabber addresses + $r = q("SELECT COUNT(1) as `cnt` FROM `pconfig` WHERE `uid`=%d AND `cat`='jappixmini' AND `k` LIKE 'id:%%' AND `v` LIKE '%%@%%'", local_user()); + if (count($r)) { + $address_cnt = $r[0]["cnt"]; + } else { + $address_cnt = 0; + } - // return answer as json - echo json_encode($answer); - killme(); -} + if (!$activate) { + // load scripts if not yet activated so that password can be saved + $a->page['htmlhead'] .= '' . "\r\n"; + $a->page['htmlhead'] .= '' . "\r\n"; + + $a->page['htmlhead'] .= '' . "\r\n"; + } + + $s .= ''; + $s .= '

' . t('Jappix Mini') . '

'; + $s .= '
'; + $s .= ''; + + $a->page['htmlhead'] .= ""; } -function jappixmini_settings_post(&$a,&$b) { - if(! local_user()) return; - - if($_POST['jappixmini-submit']) { - set_pconfig(local_user(),'jappixmini','username',trim($b['jappixmini-username'])); - set_pconfig(local_user(),'jappixmini','server',trim($b['jappixmini-server'])); - set_pconfig(local_user(),'jappixmini','bosh',trim($b['jappixmini-bosh'])); - set_pconfig(local_user(),'jappixmini','encrypted-password',trim($b['jappixmini-encrypted-password'])); - set_pconfig(local_user(),'jappixmini','autosubscribe',intval($b['jappixmini-autosubscribe'])); - set_pconfig(local_user(),'jappixmini','autoapprove',intval($b['jappixmini-autoapprove'])); - set_pconfig(local_user(),'jappixmini','activate',intval($b['jappixmini-activate'])); - info( 'Jappix Mini settings saved.' ); - - if (intval($b['jappixmini-purge'])) { - $uid = local_user(); - q("DELETE FROM `pconfig` WHERE `uid`=$uid AND `cat`='jappixmini' and `k` LIKE 'id%%'"); - info( 'List of addresses purged.' ); +function jappixmini_settings_post(App $a, &$b) +{ + // save addon settings for a user + if (!local_user()) { + return; + } + $uid = local_user(); + + if ($_POST['jappixmini-submit']) { + $encrypt = intval($b['jappixmini-encrypt']); + if ($encrypt) { + // check that Jabber password was encrypted with correct Friendica password + $friendica_password = trim($b['jappixmini-friendica-password']); + if (!User::authenticate((int) $uid, $friendica_password)) { + info("Wrong friendica password!"); + return; + } + } + + $purge = intval($b['jappixmini-purge']); + + $username = trim($b['jappixmini-username']); + $old_username = PConfig::get($uid, 'jappixmini', 'username'); + if ($username != $old_username) { + $purge = 1; + } + + $server = trim($b['jappixmini-server']); + $old_server = PConfig::get($uid, 'jappixmini', 'server'); + if ($server != $old_server) { + $purge = 1; + } + + PConfig::set($uid, 'jappixmini', 'username' , $username); + PConfig::set($uid, 'jappixmini', 'server' , $server); + PConfig::set($uid, 'jappixmini', 'bosh' , trim($b['jappixmini-bosh'])); + PConfig::set($uid, 'jappixmini', 'password' , trim($b['jappixmini-encrypted-password'])); + PConfig::set($uid, 'jappixmini', 'autosubscribe' , intval($b['jappixmini-autosubscribe'])); + PConfig::set($uid, 'jappixmini', 'autoapprove' , intval($b['jappixmini-autoapprove'])); + PConfig::set($uid, 'jappixmini', 'activate' , intval($b['jappixmini-activate'])); + PConfig::set($uid, 'jappixmini', 'dontinsertchat', intval($b['jappixmini-dont-insertchat'])); + PConfig::set($uid, 'jappixmini', 'encrypt' , $encrypt); + info('Jappix Mini settings saved.'); + + if ($purge) { + q("DELETE FROM `pconfig` WHERE `uid`=$uid AND `cat`='jappixmini' AND `k` LIKE 'id:%%'"); + info('List of addresses purged.'); } } } -function jappixmini_script(&$a,&$s) { - if(! local_user()) return; - - $activate = get_pconfig(local_user(),'jappixmini','activate'); - if (!$activate) return; - - $a->page['htmlhead'] .= ''."\r\n"; - $a->page['htmlhead'] .= ''."\r\n"; - - $a->page['htmlhead'] .= ''."\r\n"; - $a->page['htmlhead'] .= ''."\r\n"; - - $a->page['htmlhead'] .= ''."\r\n"; - - $username = get_pconfig(local_user(),'jappixmini','username'); - $username = str_replace("'", "\\'", $username); - $server = get_pconfig(local_user(),'jappixmini','server'); - $server = str_replace("'", "\\'", $server); - $bosh = get_pconfig(local_user(),'jappixmini','bosh'); - $bosh = str_replace("'", "\\'", $bosh); - $encrypted_password = get_pconfig(local_user(),'jappixmini','encrypted-password'); - $encrypted_password = str_replace("'", "\\'", $encrypted_password); - - $autoapprove = get_pconfig(local_user(),'jappixmini','autoapprove'); - $autoapprove = intval($autoapprove); - $autosubscribe = get_pconfig(local_user(),'jappixmini','autosubscribe'); - $autosubscribe = intval($autosubscribe); - - // get a list of jabber accounts of the contacts - $contacts = Array(); - $uid = local_user(); - $rows = q("SELECT `v` FROM `pconfig` WHERE `uid`=$uid AND `cat`='jappixmini' and `k` LIKE 'id%%'"); - foreach ($rows as $row) { - $value = $row['v']; - $pos = strpos($value, ":"); - $address = substr($value, $pos+1); - $contacts[] = $address; - } - $contacts_json = json_encode($contacts); - - $a->page['htmlhead'] .= "' . "\r\n"; + $a->page['htmlhead'] .= '' . "\r\n"; + + $a->page['htmlhead'] .= '' . "\r\n"; + + $username = PConfig::get(local_user(), 'jappixmini', 'username'); + $username = str_replace("'", "\\'", $username); + $server = PConfig::get(local_user(), 'jappixmini', 'server'); + $server = str_replace("'", "\\'", $server); + $bosh = PConfig::get(local_user(), 'jappixmini', 'bosh'); + $bosh = str_replace("'", "\\'", $bosh); + $encrypt = PConfig::get(local_user(), 'jappixmini', 'encrypt'); + $encrypt = intval($encrypt); + $password = PConfig::get(local_user(), 'jappixmini', 'password'); + $password = str_replace("'", "\\'", $password); + + $autoapprove = PConfig::get(local_user(), 'jappixmini', 'autoapprove'); + $autoapprove = intval($autoapprove); + $autosubscribe = PConfig::get(local_user(), 'jappixmini', 'autosubscribe'); + $autosubscribe = intval($autosubscribe); + + // set proxy if necessary + $use_proxy = Config::get('jappixmini', 'bosh_proxy'); + if ($use_proxy) { + $proxy = $a->get_baseurl() . '/addon/jappixmini/proxy.php'; + } else { + $proxy = ""; + } + + // get a list of jabber accounts of the contacts + $contacts = Array(); + $uid = local_user(); + $rows = q("SELECT * FROM `pconfig` WHERE `uid`=$uid AND `cat`='jappixmini' AND `k` LIKE 'id:%%'"); + foreach ($rows as $row) { + $key = $row['k']; + $pos = strpos($key, ":"); + $dfrn_id = substr($key, $pos + 1); + $r = q("SELECT `name` FROM `contact` WHERE `uid`=$uid AND (`dfrn-id`='%s' OR `issued-id`='%s')", dbesc($dfrn_id), dbesc($dfrn_id)); + if (count($r)) + $name = $r[0]["name"]; + + $value = $row['v']; + $pos = strpos($value, ":"); + $address = substr($value, $pos + 1); + if (!$address) { + continue; + } + if (!$name) { + $name = $address; + } + + $contacts[$address] = $name; + } + $contacts_json = json_encode($contacts); + $contacts_hash = sha1($contacts_json); + + // get nickname + $r = q("SELECT `username` FROM `user` WHERE `uid`=$uid"); + $nickname = json_encode($r[0]["username"]); + $groupchats = Config::get('jappixmini', 'groupchats'); + //if $groupchats has no value jappix_addon_start will produce a syntax error + if (empty($groupchats)) { + $groupchats = "{}"; + } + + // add javascript to start Jappix Mini + $a->page['htmlhead'] .= ""; - return; + return; } -function jappixmini_login(&$a, &$o) { - // save hash of password using setDB - $o = str_replace("
page['htmlhead'] .= '' . "\r\n"; + + // for jappixmini_addon_set_client_secret + $a->page['htmlhead'] .= '' . "\r\n"; + + // save hash of password + $o = str_replace("status != "ok") continue; + // construct own address + $username = PConfig::get($uid, 'jappixmini', 'username'); + if (!$username) { + continue; + } + $server = PConfig::get($uid, 'jappixmini', 'server'); + if (!$server) { + continue; + } - $encrypted_address_hex = $answer->encrypted_address; - if (!$encrypted_address_hex) continue; - $encrypted_address = hex2bin($encrypted_address_hex); + $address = $username . "@" . $server; - $decrypted_address = ""; - openssl_private_decrypt($encrypted_address, $decrypted_address, $prvkey); - if (!$decrypted_address) continue; + // sign address + $signed_address = ""; + $encrypt_func($address, $signed_address, $key); - $address = $decrypted_address; - } else if ($pubkey) { - $encrypted_request = ""; - openssl_public_encrypt($dfrn_id, $encrypted_request, $pubkey); - if (!$encrypted_request) continue; - $encrypted_request_hex = bin2hex($encrypted_request); + // construct request url + $signed_address_hex = bin2hex($signed_address); + $url = $base . "&signed_address=$signed_address_hex&dfrn_id=" . urlencode($dfrn_id); - $retrieval_address = $base."?encrypted_for=".urlencode($dfrn_id)."&encrypted_request=".urlencode($encrypted_request_hex); + try { + // send request + $answer_json = fetch_url($url); - $answer_json = fetch_url($retrieval_address); + // parse answer $answer = json_decode($answer_json); - if ($answer->status != "ok") continue; + if ($answer->status != "ok") { + throw new Exception(); + } + + $encrypted_address_hex = $answer->encrypted_address; + if (!$encrypted_address_hex) { + throw new Exception(); + } + + $encrypted_address = hex2bin($encrypted_address_hex); + if (!$encrypted_address) { + throw new Exception(); + } - $address = $answer->address; - if (!$address) continue; + // decrypt address + $decrypted_address = ""; + $decrypt_func($encrypted_address, $decrypted_address, $key); + if (!$decrypted_address) { + throw new Exception(); + } + } catch (Exception $e) { + $decrypted_address = ""; } // save address - set_pconfig($uid, "jappixmini", "id:$dfrn_id", "$now:$address"); + PConfig::set($uid, "jappixmini", "id:$dfrn_id", "$now:$decrypted_address"); } } } -function jappixmini_download_source(&$a,&$b) { +function jappixmini_download_source(App $a, &$b) +{ + // Jappix Mini source download link on About page $b .= '

Jappix Mini

'; - $b .= '

This site uses Jappix Mini by the Jappix authors, which is distributed under the terms of the GNU Affero General Public License.

'; - $b .= '

You can download the source code.

'; + $b .= '

This site uses the jappixmini addon, which includes Jappix Mini by the Jappix authors and is distributed under the terms of the GNU Affero General Public License.

'; + $b .= '

You can download the source code of the addon. The rest of Friendica is distributed under compatible licenses and can be retrieved from https://github.com/friendica/friendica and https://github.com/friendica/friendica-addons

'; }