2012-04-13 15:05:16 +00:00
< ? php
/**
* Name : jappixmini
2012-04-17 23:13:18 +00:00
* Description : Provides a Facebook - like chat using Jappix Mini
2012-08-28 08:02:46 +00:00
* Version : 1.0 . 1
2012-04-17 23:13:18 +00:00
* Author : leberwurscht < leberwurscht @ hoegners . de >
2012-04-13 15:05:16 +00:00
*
*/
2012-04-17 23:13:18 +00:00
//
// Copyright 2012 "Leberwurscht" <leberwurscht@hoegners.de>
//
// This file is dual-licensed under the MIT license (see MIT.txt) and the AGPL license (see jappix/COPYING).
//
2012-04-13 15:05:16 +00:00
/*
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
2012-04-14 16:23:42 +00:00
use hash ( " some_prefix " + password ) . This will however not work with OpenID logins , for this type of login the password must
be queried manually .
2012-04-13 15:05:16 +00:00
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 .
2012-04-14 16:23:42 +00:00
Using this keypair , we can provide the jabber address only to contacts :
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
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
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
Interface for this :
GET / jappixmini / ? role =% s & signed_address =% s & dfrn_id =% s
Response :
json ({ " status " : " ok " , " encrypted_address " : " %s " })
2012-04-13 15:05:16 +00:00
*/
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' );
2012-04-16 17:28:23 +00:00
2012-04-16 19:16:24 +00:00
// set standard configuration
2012-04-16 17:28:23 +00:00
$info_text = get_config ( " jappixmini " , " infotext " );
if ( ! $info_text ) set_config ( " 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! "
);
2012-04-16 19:16:24 +00:00
$bosh_proxy = get_config ( " jappixmini " , " bosh_proxy " );
2012-04-17 22:32:04 +00:00
if ( $bosh_proxy === " " ) set_config ( " jappixmini " , " bosh_proxy " , " 1 " );
// set addon version so that safe updates are possible later
$addon_version = get_config ( " jappixmini " , " version " );
if ( $addon_version === " " ) set_config ( " jappixmini " , " version " , " 1 " );
2012-04-13 15:05:16 +00:00
}
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' );
unregister_hook ( 'page_end' , 'addon/jappixmini/jappixmini.php' , 'jappixmini_script' );
unregister_hook ( 'authenticate' , 'addon/jappixmini/jappixmini.php' , 'jappixmini_login' );
unregister_hook ( 'cron' , 'addon/jappixmini/jappixmini.php' , 'jappixmini_cron' );
unregister_hook ( 'about_hook' , 'addon/jappixmini/jappixmini.php' , 'jappixmini_download_source' );
}
function jappixmini_plugin_admin ( & $a , & $o ) {
2012-04-14 16:23:42 +00:00
// display instructions and warnings on addon settings page for admin
2012-04-17 23:13:18 +00:00
if ( ! file_exists ( " addon/jappixmini.tgz " )) {
$o .= '<p><strong style="color:#fff;background-color:#f00">The source archive jappixmini.tgz does not exist. This is probably a violation of the Jappix License (AGPL).</strong></p>' ;
2012-04-15 10:20:53 +00:00
}
2012-04-16 17:28:23 +00:00
2012-04-16 19:04:45 +00:00
// warn if cron job has not yet been executed
$cron_run = get_config ( " jappixmini " , " last_cron_execution " );
if ( ! $cron_run ) $o .= " <p><strong>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.</strong></p> " ;
2012-04-16 19:16:24 +00:00
// bosh proxy
$bosh_proxy = intval ( get_config ( " jappixmini " , " bosh_proxy " ));
$bosh_proxy = intval ( $bosh_proxy ) ? ' checked="checked"' : '' ;
$o .= '<label for="jappixmini-proxy">Activate BOSH proxy</label>' ;
$o .= ' <input id="jappixmini-proxy" type="checkbox" name="jappixmini-proxy" value="1"' . $bosh_proxy . ' /><br />' ;
2013-06-22 18:05:03 +00:00
// bosh address
$bosh_address = get_config ( " jappixmini " , " bosh_address " );
$o .= '<p><label for="jappixmini-address">Adress of the default BOSH proxy. If enabled it overrides the user settings:</label><br />' ;
$o .= '<input id="jappixmini-address" type="text" name="jappixmini-address" value="' . $bosh_address . '" /></p>' ;
// default server address
$default_server = get_config ( " jappixmini " , " default_server " );
$o .= '<p><label for="jappixmini-server">Adress of the default jabber server:</label><br />' ;
$o .= '<input id="jappixmini-server" type="text" name="jappixmini-server" value="' . $default_server . '" /></p>' ;
// default user name to friendica nickname
$default_user = intval ( get_config ( " jappixmini " , " default_user " ));
$default_user = intval ( $default_user ) ? ' checked="checked"' : '' ;
$o .= '<label for="jappixmini-user">Set the default username to the nickname:</label>' ;
$o .= ' <input id="jappixmini-user" type="checkbox" name="jappixmini-defaultuser" value="1"' . $default_user . ' /><br />' ;
2012-04-16 17:28:23 +00:00
// info text field
$info_text = get_config ( " jappixmini " , " infotext " );
2012-04-16 19:16:24 +00:00
$o .= '<p><label for="jappixmini-infotext">Info text to help users with configuration (important if you want to provide your own BOSH host!):</label><br />' ;
$o .= '<textarea id="jappixmini-infotext" name="jappixmini-infotext" rows="5" cols="50">' . htmlentities ( $info_text ) . '</textarea></p>' ;
// submit button
2012-04-16 17:28:23 +00:00
$o .= '<input type="submit" name="jappixmini-admin-settings" value="OK" />' ;
2012-04-13 15:05:16 +00:00
}
function jappixmini_plugin_admin_post ( & $a ) {
2012-04-16 17:28:23 +00:00
// set info text
$submit = $_REQUEST [ 'jappixmini-admin-settings' ];
if ( $submit ) {
$info_text = $_REQUEST [ 'jappixmini-infotext' ];
2012-04-16 19:16:24 +00:00
$bosh_proxy = intval ( $_REQUEST [ 'jappixmini-proxy' ]);
2013-06-22 18:05:03 +00:00
$default_user = intval ( $_REQUEST [ 'jappixmini-defaultuser' ]);
$bosh_address = $_REQUEST [ 'jappixmini-address' ];
$default_server = $_REQUEST [ 'jappixmini-server' ];
2012-04-16 17:28:23 +00:00
set_config ( " jappixmini " , " infotext " , $info_text );
2012-04-16 19:16:24 +00:00
set_config ( " jappixmini " , " bosh_proxy " , $bosh_proxy );
2013-06-22 18:05:03 +00:00
set_config ( " jappixmini " , " bosh_address " , $bosh_address );
set_config ( " jappixmini " , " default_server " , $default_server );
set_config ( " jappixmini " , " default_user " , $default_user );
2012-04-16 17:28:23 +00:00
}
2012-04-13 15:05:16 +00:00
}
function jappixmini_module () {}
function jappixmini_init ( & $a ) {
2012-04-14 16:23:42 +00:00
// module page where other Friendica sites can submit Jabber addresses to and also can query Jabber addresses
// of local users
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$dfrn_id = $_REQUEST [ " dfrn_id " ];
if ( ! $dfrn_id ) killme ();
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$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 ();
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$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 ();
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$encrypt_func = openssl_private_encrypt ;
$decrypt_func = openssl_private_decrypt ;
$key = $r [ 0 ][ " prvkey " ];
} else {
2012-04-13 15:05:16 +00:00
killme ();
}
2012-04-14 16:23:42 +00:00
$uid = $r [ 0 ][ " uid " ];
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// save the Jabber address we received
try {
$signed_address_hex = $_REQUEST [ " signed_address " ];
$signed_address = hex2bin ( $signed_address_hex );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$trusted_address = " " ;
$decrypt_func ( $signed_address , $trusted_address , $key );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$now = intval ( time ());
set_pconfig ( $uid , " jappixmini " , " id: $dfrn_id " , " $now : $trusted_address " );
} catch ( Exception $e ) {
}
2012-04-13 15:05:16 +00:00
2012-04-15 20:13:18 +00:00
// do not return an address if user deactivated plugin
$activated = get_pconfig ( $uid , 'jappixmini' , 'activate' );
if ( ! $activated ) killme ();
2012-04-14 16:23:42 +00:00
// return the requested Jabber address
try {
$username = get_pconfig ( $uid , 'jappixmini' , 'username' );
$server = get_pconfig ( $uid , 'jappixmini' , 'server' );
$address = " $username @ $server " ;
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$encrypted_address = " " ;
$encrypt_func ( $address , $encrypted_address , $key );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$encrypted_address_hex = bin2hex ( $encrypted_address );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$answer = Array (
" status " => " ok " ,
" encrypted_address " => $encrypted_address_hex
);
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$answer_json = json_encode ( $answer );
echo $answer_json ;
killme ();
} catch ( Exception $e ) {
killme ();
}
2012-04-13 15:05:16 +00:00
}
function jappixmini_settings ( & $a , & $s ) {
2012-04-14 16:23:42 +00:00
// addon settings for a user
$activate = get_pconfig ( local_user (), 'jappixmini' , 'activate' );
$activate = intval ( $activate ) ? ' checked="checked"' : '' ;
2012-08-28 07:56:00 +00:00
$dontinsertchat = get_pconfig ( local_user (), 'jappixmini' , 'dontinsertchat' );
$insertchat = ! ( intval ( $dontinsertchat ) ? ' checked="checked"' : '' );
2012-04-14 16:23:42 +00:00
2013-06-22 18:05:03 +00:00
$defaultbosh = get_config ( " jappixmini " , " bosh_address " );
if ( $defaultbosh != " " )
set_pconfig ( local_user (), 'jappixmini' , 'bosh' , $defaultbosh );
2012-04-13 15:05:16 +00:00
$username = get_pconfig ( local_user (), 'jappixmini' , 'username' );
$username = htmlentities ( $username );
$server = get_pconfig ( local_user (), 'jappixmini' , 'server' );
$server = htmlentities ( $server );
$bosh = get_pconfig ( local_user (), 'jappixmini' , 'bosh' );
$bosh = htmlentities ( $bosh );
2012-04-15 10:20:53 +00:00
$password = get_pconfig ( local_user (), 'jappixmini' , 'password' );
2012-04-13 15:05:16 +00:00
$autosubscribe = get_pconfig ( local_user (), 'jappixmini' , 'autosubscribe' );
$autosubscribe = intval ( $autosubscribe ) ? ' checked="checked"' : '' ;
$autoapprove = get_pconfig ( local_user (), 'jappixmini' , 'autoapprove' );
$autoapprove = intval ( $autoapprove ) ? ' checked="checked"' : '' ;
2012-04-15 10:20:53 +00:00
$encrypt = intval ( get_pconfig ( local_user (), 'jappixmini' , 'encrypt' ));
$encrypt_checked = $encrypt ? ' checked="checked"' : '' ;
$encrypt_disabled = $encrypt ? '' : ' disabled="disabled"' ;
2013-06-22 18:05:03 +00:00
if ( $server == " " )
$server = get_config ( " jappixmini " , " default_server " );
if (( $username == " " ) and get_config ( " jappixmini " , " default_user " ))
$username = $a -> user [ " nickname " ];
2012-04-16 17:28:23 +00:00
$info_text = get_config ( " jappixmini " , " infotext " );
$info_text = htmlentities ( $info_text );
$info_text = str_replace ( " \n " , " <br /> " , $info_text );
2012-04-17 20:17:06 +00:00
// 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 ;
// 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 ;
2012-04-15 10:20:53 +00:00
if ( ! $activate ) {
// load scripts if not yet activated so that password can be saved
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/php/get.php?t=js&g=mini.xml"></script>' . " \r \n " ;
2012-04-16 22:01:30 +00:00
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/php/get.php?t=js&f=presence.js~caps.js~name.js~roster.js"></script>' . " \r \n " ;
2012-04-15 10:20:53 +00:00
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/lib.js"></script>' . " \r \n " ;
}
2012-04-13 15:05:16 +00:00
$s .= '<div class="settings-block">' ;
2012-04-15 11:21:32 +00:00
2012-08-28 07:17:35 +00:00
$s .= '<h3>' . t ( 'Jappix Mini addon settings' ) . '</h3>' ;
2012-04-13 15:05:16 +00:00
$s .= '<div>' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-activate">' . t ( 'Activate addon' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-activate" type="checkbox" name="jappixmini-activate" value="1"' . $activate . ' />' ;
$s .= '<br />' ;
2012-08-28 07:56:00 +00:00
$s .= '<label for"jappixmini-dont-insertchat">' . t ( 'Do <em>not</em> insert the Jappixmini Chat-Widget into the webinterface' ) . '</label>' ;
$s .= '<input id="jappixmini-dont-insertchat" type="checkbox" name="jappixmini-dont-insertchat" value="1"' . $insertchat . ' />' ;
2012-08-28 07:17:35 +00:00
$s .= '<br />' ;
$s .= '<label for="jappixmini-username">' . t ( 'Jabber username' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-username" type="text" name="jappixmini-username" value="' . $username . '" />' ;
$s .= '<br />' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-server">' . t ( 'Jabber server' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-server" type="text" name="jappixmini-server" value="' . $server . '" />' ;
$s .= '<br />' ;
2012-04-15 10:20:53 +00:00
2013-06-22 18:05:03 +00:00
if ( defaultbosh == " " ) {
$s .= '<label for="jappixmini-bosh">' . t ( 'Jabber BOSH host' ) . '</label>' ;
$s .= ' <input id="jappixmini-bosh" type="text" name="jappixmini-bosh" value="' . $bosh . '" />' ;
$s .= '<br />' ;
}
2012-04-15 10:20:53 +00:00
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-password">' . t ( 'Jabber password' ) . '</label>' ;
2012-04-15 10:20:53 +00:00
$s .= ' <input type="hidden" id="jappixmini-password" name="jappixmini-encrypted-password" value="' . $password . '" />' ;
$s .= ' <input id="jappixmini-clear-password" type="password" value="" onchange="jappixmini_set_password();" />' ;
$s .= '<br />' ;
$onchange = " document.getElementById('jappixmini-friendica-password').disabled = !this.checked;jappixmini_set_password(); " ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-encrypt">' . t ( 'Encrypt Jabber password with Friendica password (recommended)' ) . '</label>' ;
2012-04-15 10:20:53 +00:00
$s .= ' <input id="jappixmini-encrypt" type="checkbox" name="jappixmini-encrypt" onchange="' . $onchange . '" value="1"' . $encrypt_checked . ' />' ;
$s .= '<br />' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-friendica-password">' . t ( 'Friendica password' ) . '</label>' ;
2012-04-15 10:20:53 +00:00
$s .= ' <input id="jappixmini-friendica-password" name="jappixmini-friendica-password" type="password" onchange="jappixmini_set_password();" value=""' . $encrypt_disabled . ' />' ;
2012-04-13 15:05:16 +00:00
$s .= '<br />' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-autoapprove">' . t ( 'Approve subscription requests from Friendica contacts automatically' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-autoapprove" type="checkbox" name="jappixmini-autoapprove" value="1"' . $autoapprove . ' />' ;
$s .= '<br />' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-autosubscribe">' . t ( 'Subscribe to Friendica contacts automatically' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-autosubscribe" type="checkbox" name="jappixmini-autosubscribe" value="1"' . $autosubscribe . ' />' ;
$s .= '<br />' ;
2012-08-28 07:17:35 +00:00
$s .= '<label for="jappixmini-purge">' . t ( 'Purge internal list of jabber addresses of contacts' ) . '</label>' ;
2012-04-13 15:05:16 +00:00
$s .= ' <input id="jappixmini-purge" type="checkbox" name="jappixmini-purge" value="1" />' ;
$s .= '<br />' ;
2012-04-16 17:28:23 +00:00
if ( $info_text ) $s .= '<br />Configuration help:<p style="margin-left:2em;">' . $info_text . '</p>' ;
2012-04-17 20:17:06 +00:00
$s .= '<br />Status:<p style="margin-left:2em;">Addon knows ' . $address_cnt . ' Jabber addresses of ' . $contact_cnt . ' Friendica contacts (takes some time, usually 10 minutes, to update).</p>' ;
2012-04-13 15:05:16 +00:00
$s .= '<input type="submit" name="jappixmini-submit" value="' . t ( 'Submit' ) . '" />' ;
2012-08-28 07:17:35 +00:00
$s .= ' <input type="button" value="' . t ( 'Add contact' ) . '" onclick="jappixmini_addon_subscribe();" />' ;
2012-04-13 15:05:16 +00:00
$s .= '</div>' ;
2012-04-15 11:21:32 +00:00
$s .= '</div>' ;
2012-04-13 15:05:16 +00:00
$a -> page [ 'htmlhead' ] .= " <script type= \" text/javascript \" >
2012-04-15 10:20:53 +00:00
function jappixmini_set_password () {
encrypt = document . getElementById ( 'jappixmini-encrypt' ) . checked ;
password = document . getElementById ( 'jappixmini-password' );
clear_password = document . getElementById ( 'jappixmini-clear-password' );
if ( encrypt ) {
friendica_password = document . getElementById ( 'jappixmini-friendica-password' );
2012-04-15 12:31:46 +00:00
if ( friendica_password ) {
jappixmini_addon_set_client_secret ( friendica_password . value );
2012-04-15 20:57:25 +00:00
jappixmini_addon_encrypt_password ( clear_password . value , function ( encrypted_password ){
password . value = encrypted_password ;
});
2012-04-15 12:31:46 +00:00
}
2012-04-15 10:20:53 +00:00
}
else {
password . value = clear_password . value ;
}
}
2012-04-13 15:05:16 +00:00
jQuery ( document ) . ready ( function () {
2012-04-15 10:20:53 +00:00
encrypt = document . getElementById ( 'jappixmini-encrypt' ) . checked ;
password = document . getElementById ( 'jappixmini-password' );
clear_password = document . getElementById ( 'jappixmini-clear-password' );
if ( encrypt ) {
2012-04-15 20:57:25 +00:00
jappixmini_addon_decrypt_password ( password . value , function ( decrypted_password ){
clear_password . value = decrypted_password ;
});
2012-04-15 10:20:53 +00:00
}
else {
clear_password . value = password . value ;
}
2012-04-13 15:05:16 +00:00
});
</ script > " ;
}
function jappixmini_settings_post ( & $a , & $b ) {
2012-04-14 16:23:42 +00:00
// save addon settings for a user
2012-04-13 15:05:16 +00:00
if ( ! local_user ()) return ;
2012-04-14 16:23:42 +00:00
$uid = local_user ();
2012-04-13 15:05:16 +00:00
if ( $_POST [ 'jappixmini-submit' ]) {
2012-04-15 10:20:53 +00:00
$encrypt = intval ( $b [ 'jappixmini-encrypt' ]);
if ( $encrypt ) {
// check that Jabber password was encrypted with correct Friendica password
$friendica_password = trim ( $b [ 'jappixmini-friendica-password' ]);
$encrypted = hash ( 'whirlpool' , $friendica_password );
$r = q ( " SELECT * FROM `user` WHERE `uid`= $uid AND `password`='%s' " ,
dbesc ( $encrypted )
);
if ( ! count ( $r )) {
info ( " Wrong friendica password! " );
return ;
}
}
2012-04-14 16:23:42 +00:00
$purge = intval ( $b [ 'jappixmini-purge' ]);
$username = trim ( $b [ 'jappixmini-username' ]);
$old_username = get_pconfig ( $uid , 'jappixmini' , 'username' );
if ( $username != $old_username ) $purge = 1 ;
$server = trim ( $b [ 'jappixmini-server' ]);
$old_server = get_pconfig ( $uid , 'jappixmini' , 'server' );
if ( $server != $old_server ) $purge = 1 ;
set_pconfig ( $uid , 'jappixmini' , 'username' , $username );
set_pconfig ( $uid , 'jappixmini' , 'server' , $server );
set_pconfig ( $uid , 'jappixmini' , 'bosh' , trim ( $b [ 'jappixmini-bosh' ]));
2012-04-15 10:20:53 +00:00
set_pconfig ( $uid , 'jappixmini' , 'password' , trim ( $b [ 'jappixmini-encrypted-password' ]));
2012-04-14 16:23:42 +00:00
set_pconfig ( $uid , 'jappixmini' , 'autosubscribe' , intval ( $b [ 'jappixmini-autosubscribe' ]));
set_pconfig ( $uid , 'jappixmini' , 'autoapprove' , intval ( $b [ 'jappixmini-autoapprove' ]));
set_pconfig ( $uid , 'jappixmini' , 'activate' , intval ( $b [ 'jappixmini-activate' ]));
2012-08-28 07:56:00 +00:00
set_pconfig ( $uid , 'jappixmini' , 'dontinsertchat' , intval ( $b [ 'jappixmini-dont-insertchat' ]));
2012-04-15 10:20:53 +00:00
set_pconfig ( $uid , 'jappixmini' , 'encrypt' , $encrypt );
2012-04-13 15:05:16 +00:00
info ( 'Jappix Mini settings saved.' );
2012-04-14 16:23:42 +00:00
if ( $purge ) {
2012-04-17 20:17:06 +00:00
q ( " DELETE FROM `pconfig` WHERE `uid`= $uid AND `cat`='jappixmini' AND `k` LIKE 'id:%%' " );
2012-04-13 15:05:16 +00:00
info ( 'List of addresses purged.' );
}
}
}
function jappixmini_script ( & $a , & $s ) {
2012-04-14 16:23:42 +00:00
// adds the script to the page header which starts Jappix Mini
2012-04-13 15:05:16 +00:00
if ( ! local_user ()) return ;
$activate = get_pconfig ( local_user (), 'jappixmini' , 'activate' );
2012-08-28 07:56:00 +00:00
$dontinsertchat = get_pconfig ( local_user (), 'jappixmini' , 'dontinsertchat' );
if ( ! $activate or $dontinsertchat ) return ;
2012-04-13 15:05:16 +00:00
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/php/get.php?t=js&g=mini.xml"></script>' . " \r \n " ;
2012-04-16 22:01:30 +00:00
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/php/get.php?t=js&f=presence.js~caps.js~name.js~roster.js"></script>' . " \r \n " ;
2012-04-13 15:05:16 +00:00
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/lib.js"></script>' . " \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 );
2012-04-15 10:20:53 +00:00
$encrypt = get_pconfig ( local_user (), 'jappixmini' , 'encrypt' );
$encrypt = intval ( $encrypt );
$password = get_pconfig ( local_user (), 'jappixmini' , 'password' );
$password = str_replace ( " ' " , " \\ ' " , $password );
2012-04-13 15:05:16 +00:00
$autoapprove = get_pconfig ( local_user (), 'jappixmini' , 'autoapprove' );
$autoapprove = intval ( $autoapprove );
$autosubscribe = get_pconfig ( local_user (), 'jappixmini' , 'autosubscribe' );
$autosubscribe = intval ( $autosubscribe );
2012-04-16 19:16:24 +00:00
// set proxy if necessary
$use_proxy = get_config ( 'jappixmini' , 'bosh_proxy' );
if ( $use_proxy ) {
2012-04-16 19:40:23 +00:00
$proxy = $a -> get_baseurl () . '/addon/jappixmini/proxy.php' ;
2012-04-16 19:16:24 +00:00
}
else {
$proxy = " " ;
2012-04-15 10:20:53 +00:00
}
2012-04-13 15:05:16 +00:00
// get a list of jabber accounts of the contacts
$contacts = Array ();
$uid = local_user ();
2012-04-17 20:17:06 +00:00
$rows = q ( " SELECT * FROM `pconfig` WHERE `uid`= $uid AND `cat`='jappixmini' AND `k` LIKE 'id:%%' " );
2012-04-13 15:05:16 +00:00
foreach ( $rows as $row ) {
2012-04-14 16:23:42 +00:00
$key = $row [ 'k' ];
$pos = strpos ( $key , " : " );
$dfrn_id = substr ( $key , $pos + 1 );
2012-07-05 18:07:01 +00:00
$r = q ( " SELECT `name` FROM `contact` WHERE `uid`= $uid AND (`dfrn-id`='%s' OR `issued-id`='%s') " ,
2012-04-14 16:23:42 +00:00
dbesc ( $dfrn_id ),
dbesc ( $dfrn_id )
);
$name = $r [ 0 ][ " name " ];
2012-04-13 15:05:16 +00:00
$value = $row [ 'v' ];
$pos = strpos ( $value , " : " );
$address = substr ( $value , $pos + 1 );
2012-04-14 16:23:42 +00:00
if ( ! $address ) continue ;
if ( ! $name ) $name = $address ;
$contacts [ $address ] = $name ;
2012-04-13 15:05:16 +00:00
}
$contacts_json = json_encode ( $contacts );
2012-04-17 19:18:11 +00:00
$contacts_hash = sha1 ( $contacts_json );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// get nickname
$r = q ( " SELECT `username` FROM `user` WHERE `uid`= $uid " );
$nickname = json_encode ( $r [ 0 ][ " username " ]);
2013-09-27 21:33:35 +00:00
$groupchats = get_config ( 'jappixmini' , 'groupchats' );
2012-04-14 16:23:42 +00:00
// add javascript to start Jappix Mini
2012-04-13 15:05:16 +00:00
$a -> page [ 'htmlhead' ] .= " <script type= \" text/javascript \" >
jQuery ( document ) . ready ( function () {
2013-09-27 21:33:35 +00:00
jappixmini_addon_start ( '$server' , '$username' , '$proxy' , '$bosh' , $encrypt , '$password' , $nickname , $contacts_json , '$contacts_hash' , $autoapprove , $autosubscribe , $groupchats );
2012-04-13 15:05:16 +00:00
});
</ script > " ;
return ;
}
function jappixmini_login ( & $a , & $o ) {
2012-04-15 10:20:53 +00:00
// create client secret on login to be able to encrypt jabber passwords
2012-04-16 22:01:30 +00:00
// for setDB and str_sha1, needed by jappixmini_addon_set_client_secret
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/php/get.php?t=js&f=datastore.js~jsjac.js"></script>' . " \r \n " ;
2012-04-14 16:23:42 +00:00
// for jappixmini_addon_set_client_secret
$a -> page [ 'htmlhead' ] .= '<script type="text/javascript" src="' . $a -> get_baseurl () . '/addon/jappixmini/lib.js"></script>' . " \r \n " ;
// save hash of password
2012-04-13 15:05:16 +00:00
$o = str_replace ( " <form " , " <form onsubmit= \" jappixmini_addon_set_client_secret(this.elements['id_password'].value);return true; \" " , $o );
}
function jappixmini_cron ( & $a , $d ) {
// For autosubscribe/autoapprove, we need to maintain a list of jabber addresses of our contacts.
2012-04-16 19:04:45 +00:00
set_config ( " jappixmini " , " last_cron_execution " , $d );
2012-04-13 15:05:16 +00:00
// go through list of users with jabber enabled
$users = q ( " SELECT `uid` FROM `pconfig` WHERE `cat`='jappixmini' AND (`k`='autosubscribe' OR `k`='autoapprove') AND `v`='1' " );
2012-04-16 17:26:44 +00:00
logger ( " jappixmini: Update list of contacts' jabber accounts for " . count ( $users ) . " users. " );
2012-04-13 15:05:16 +00:00
2012-06-29 04:29:10 +00:00
if ( ! count ( $users ))
return ;
2012-04-13 15:05:16 +00:00
foreach ( $users as $row ) {
$uid = $row [ " uid " ];
// for each user, go through list of contacts
$contacts = q ( " SELECT * FROM `contact` WHERE `uid`=%d AND ((LENGTH(`dfrn-id`) AND LENGTH(`pubkey`)) OR (LENGTH(`issued-id`) AND LENGTH(`prvkey`))) " , intval ( $uid ));
foreach ( $contacts as $contact_row ) {
$request = $contact_row [ " request " ];
if ( ! $request ) continue ;
$dfrn_id = $contact_row [ " dfrn-id " ];
2012-04-14 16:23:42 +00:00
if ( $dfrn_id ) {
$key = $contact_row [ " pubkey " ];
$encrypt_func = openssl_public_encrypt ;
$decrypt_func = openssl_public_decrypt ;
$role = " prv " ;
} else {
2012-04-13 15:05:16 +00:00
$dfrn_id = $contact_row [ " issued-id " ];
2012-04-14 16:23:42 +00:00
$key = $contact_row [ " prvkey " ];
$encrypt_func = openssl_private_encrypt ;
$decrypt_func = openssl_private_decrypt ;
$role = " pub " ;
2012-04-13 15:05:16 +00:00
}
// check if jabber address already present
$present = get_pconfig ( $uid , " jappixmini " , " id: " . $dfrn_id );
$now = intval ( time ());
if ( $present ) {
// $present has format "timestamp:jabber_address"
$p = strpos ( $present , " : " );
$timestamp = intval ( substr ( $present , 0 , $p ));
// do not re-retrieve jabber address if last retrieval
// is not older than a week
if ( $now - $timestamp < 3600 * 24 * 7 ) continue ;
}
// construct base retrieval address
$pos = strpos ( $request , " /dfrn_request/ " );
if ( $pos === false ) continue ;
2012-04-14 16:23:42 +00:00
$base = substr ( $request , 0 , $pos ) . " /jappixmini?role= $role " ;
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// construct own address
$username = get_pconfig ( $uid , 'jappixmini' , 'username' );
if ( ! $username ) continue ;
$server = get_pconfig ( $uid , 'jappixmini' , 'server' );
if ( ! $server ) continue ;
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
$address = $username . " @ " . $server ;
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// sign address
$signed_address = " " ;
$encrypt_func ( $address , $signed_address , $key );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// construct request url
$signed_address_hex = bin2hex ( $signed_address );
$url = $base . " &signed_address= $signed_address_hex &dfrn_id= " . urlencode ( $dfrn_id );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
try {
// send request
$answer_json = fetch_url ( $url );
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// parse answer
2012-04-13 15:05:16 +00:00
$answer = json_decode ( $answer_json );
2012-04-14 16:23:42 +00:00
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 ();
2012-04-13 15:05:16 +00:00
2012-04-14 16:23:42 +00:00
// decrypt address
$decrypted_address = " " ;
$decrypt_func ( $encrypted_address , $decrypted_address , $key );
if ( ! $decrypted_address ) throw new Exception ();
} catch ( Exception $e ) {
$decrypted_address = " " ;
2012-04-13 15:05:16 +00:00
}
// save address
2012-04-14 16:23:42 +00:00
set_pconfig ( $uid , " jappixmini " , " id: $dfrn_id " , " $now : $decrypted_address " );
2012-04-13 15:05:16 +00:00
}
}
}
function jappixmini_download_source ( & $a , & $b ) {
2012-04-14 16:23:42 +00:00
// Jappix Mini source download link on About page
2012-04-13 15:05:16 +00:00
$b .= '<h1>Jappix Mini</h1>' ;
2012-04-17 23:13:18 +00:00
$b .= '<p>This site uses the jappixmini addon, which includes Jappix Mini by the <a href="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/AUTHORS">Jappix authors</a> and is distributed under the terms of the <a href="' . $a -> get_baseurl () . '/addon/jappixmini/jappix/COPYING">GNU Affero General Public License</a>.</p>' ;
$b .= '<p>You can download the <a href="' . $a -> get_baseurl () . '/addon/jappixmini.tgz">source code of the addon</a>. The rest of Friendica is distributed under compatible licenses and can be retrieved from <a href="https://github.com/friendica/friendica">https://github.com/friendica/friendica</a> and <a href="https://github.com/friendica/friendica-addons">https://github.com/friendica/friendica-addons</a></p>' ;
2012-04-13 15:05:16 +00:00
}