2010-07-01 19:48:07 -04:00
< ? php
2010-12-14 19:34:49 -05:00
/**
2016-11-27 19:13:47 -05:00
* @ file mod / dfrn_request . php
* @ brief Module : dfrn_request
2010-12-14 19:34:49 -05:00
*
* Purpose : Handles communication associated with the issuance of
* friend requests .
*
2016-11-27 19:13:47 -05:00
* @ see PDF with dfrn specs : https :// github . com / friendica / friendica / blob / master / spec / dfrn2 . pdf
2016-11-29 13:57:30 -05:00
* You also find a graphic which describes the confirmation process at
* https :// github . com / friendica / friendica / blob / master / spec / dfrn2_contact_request . png
2010-12-14 19:34:49 -05:00
*/
2017-04-30 00:07:00 -04:00
use Friendica\App ;
2017-11-06 21:22:52 -05:00
use Friendica\Core\Config ;
use Friendica\Core\PConfig ;
2017-08-26 02:04:21 -04:00
use Friendica\Core\System ;
2017-11-07 22:57:46 -05:00
use Friendica\Database\DBM ;
2017-12-07 09:04:24 -05:00
use Friendica\Model\Contact ;
2017-05-07 14:44:30 -04:00
use Friendica\Network\Probe ;
2017-05-07 14:45:19 -04:00
2017-05-07 14:40:23 -04:00
require_once 'include/enotify.php' ;
require_once 'include/group.php' ;
2014-09-06 11:28:46 -04:00
2017-11-29 12:17:12 -05:00
function dfrn_request_init ( App $a )
{
if ( $a -> argc > 1 )
2010-07-01 19:48:07 -04:00
$which = $a -> argv [ 1 ];
2017-11-29 12:17:12 -05:00
profile_load ( $a , $which );
2010-07-01 19:48:07 -04:00
return ;
2016-11-27 19:13:47 -05:00
}
2010-07-01 19:48:07 -04:00
2010-12-14 19:34:49 -05:00
/**
* Function : dfrn_request_post
*
* Purpose :
* Handles multiple scenarios .
*
* Scenario 1 :
* Clicking 'submit' on a friend request page .
*
* Scenario 2 :
* Following Scenario 1 , we are brought back to our home site
* in order to link our friend request with our own server cell .
* After logging in , we click 'submit' to approve the linkage .
*
*/
2017-01-09 07:12:54 -05:00
function dfrn_request_post ( App $a ) {
2010-07-01 19:48:07 -04:00
2017-03-21 12:02:59 -04:00
if (( $a -> argc != 2 ) || ( ! count ( $a -> profile ))) {
2016-03-01 08:42:55 -05:00
logger ( 'Wrong count of argc or profiles: argc=' . $a -> argc . ',profile()=' . count ( $a -> profile ));
2010-07-01 19:48:07 -04:00
return ;
2016-03-01 08:42:55 -05:00
}
2010-07-01 19:48:07 -04:00
2017-03-21 12:02:59 -04:00
if ( x ( $_POST , 'cancel' )) {
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl ());
2014-09-06 11:28:46 -04:00
}
2010-07-01 19:48:07 -04:00
2010-07-06 00:39:55 -04:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
*
* Scenario 2 : We ' ve introduced ourself to another cell , then have been returned to our own cell
2014-09-06 11:28:46 -04:00
* to confirm the request , and then we ' ve clicked submit ( perhaps after logging in ) .
2010-12-14 19:34:49 -05:00
* That brings us here :
*
*/
2010-07-01 19:48:07 -04:00
2017-03-21 12:02:59 -04:00
if (( x ( $_POST , 'localconfirm' )) && ( $_POST [ 'localconfirm' ] == 1 )) {
2010-07-06 00:39:55 -04:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Ensure this is a valid request
*/
2017-03-21 12:02:59 -04:00
if ( local_user () && ( $a -> user [ 'nickname' ] == $a -> argv [ 1 ]) && ( x ( $_POST , 'dfrn_url' ))) {
2010-07-06 00:39:55 -04:00
2010-07-01 19:48:07 -04:00
2010-12-14 19:34:49 -05:00
$dfrn_url = notags ( trim ( $_POST [ 'dfrn_url' ]));
$aes_allow = ((( x ( $_POST , 'aes_allow' )) && ( $_POST [ 'aes_allow' ] == 1 )) ? 1 : 0 );
2010-07-22 05:13:39 -04:00
$confirm_key = (( x ( $_POST , 'confirm_key' )) ? $_POST [ 'confirm_key' ] : " " );
2012-05-29 21:43:56 -04:00
$hidden = (( x ( $_POST , 'hidden-contact' )) ? intval ( $_POST [ 'hidden-contact' ]) : 0 );
2010-07-22 05:13:39 -04:00
$contact_record = null ;
2016-11-28 21:08:46 -05:00
$blocked = 1 ;
$pending = 1 ;
2014-03-11 18:52:32 -04:00
2017-03-21 12:02:59 -04:00
if ( x ( $dfrn_url )) {
2010-12-14 19:34:49 -05:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Lookup the contact based on their URL ( which is the only unique thing we have at the moment )
*/
2014-03-11 18:52:32 -04:00
2016-11-27 19:13:47 -05:00
$r = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND NOT `self` LIMIT 1 " ,
2016-11-28 09:30:36 -05:00
intval ( local_user ()),
2012-03-15 00:58:54 -04:00
dbesc ( normalise_link ( $dfrn_url ))
2010-07-06 00:39:55 -04:00
);
2014-03-11 18:52:32 -04:00
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r )) {
2017-03-21 12:02:59 -04:00
if ( strlen ( $r [ 0 ][ 'dfrn-id' ])) {
2010-12-14 19:34:49 -05:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* We don ' t need to be here . It has already happened .
*/
2010-07-27 22:27:14 -04:00
notice ( t ( " This introduction has already been accepted. " ) . EOL );
2010-07-22 05:13:39 -04:00
return ;
}
else
$contact_record = $r [ 0 ];
}
2013-12-02 14:30:24 -05:00
2017-03-21 12:02:59 -04:00
if ( is_array ( $contact_record )) {
2013-12-02 14:30:24 -05:00
$r = q ( " UPDATE `contact` SET `ret-aes` = %d, hidden = %d WHERE `id` = %d " ,
2010-07-22 05:13:39 -04:00
intval ( $aes_allow ),
2012-05-29 21:43:56 -04:00
intval ( $hidden ),
2010-07-22 05:13:39 -04:00
intval ( $contact_record [ 'id' ])
);
2010-07-06 00:39:55 -04:00
}
else {
2013-12-02 14:30:24 -05:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Scrape the other site ' s profile page to pick up the dfrn links , key , fn , and photo
*/
2016-07-04 02:05:30 -04:00
$parms = Probe :: profile ( $dfrn_url );
2014-08-20 18:56:21 -04:00
2016-12-20 11:43:46 -05:00
if ( ! count ( $parms )) {
2010-07-27 22:27:14 -04:00
notice ( t ( 'Profile location is not valid or does not contain profile information.' ) . EOL );
2010-07-06 00:39:55 -04:00
return ;
}
2010-07-22 05:13:39 -04:00
else {
2016-12-20 11:43:46 -05:00
if ( ! x ( $parms , 'fn' )) {
2010-07-27 22:27:14 -04:00
notice ( t ( 'Warning: profile location has no identifiable owner name.' ) . EOL );
2016-12-20 11:43:46 -05:00
}
if ( ! x ( $parms , 'photo' )) {
2010-07-27 22:27:14 -04:00
notice ( t ( 'Warning: profile location has no profile photo.' ) . EOL );
2016-12-20 11:43:46 -05:00
}
2017-05-08 10:19:10 -04:00
$invalid = Probe :: validDfrn ( $parms );
2016-12-20 11:43:46 -05:00
if ( $invalid ) {
2011-03-10 18:22:21 -05:00
notice ( sprintf ( tt ( " %d required parameter was not found at the given location " ,
" %d required parameters were not found at the given location " ,
$invalid ), $invalid ) . EOL );
2010-07-22 05:13:39 -04:00
return ;
}
}
2010-07-01 19:48:07 -04:00
2010-07-22 05:13:39 -04:00
$dfrn_request = $parms [ 'dfrn-request' ];
2010-07-06 00:39:55 -04:00
2016-06-25 07:56:55 -04:00
$photo = $parms [ " photo " ];
2016-11-27 19:13:47 -05:00
// Escape the entire array
2017-11-07 22:57:46 -05:00
DBM :: esc_array ( $parms );
2010-12-14 19:34:49 -05:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Create a contact record on our site for the other person
*/
2010-07-06 00:39:55 -04:00
2015-11-25 12:46:02 -05:00
$r = q ( " INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `addr`, `name`, `nick`, `photo`, `site-pubkey`,
2016-11-28 21:08:46 -05:00
`request` , `confirm` , `notify` , `poll` , `poco` , `network` , `aes_allow` , `hidden` , `blocked` , `pending` )
2016-11-29 09:52:12 -05:00
VALUES ( % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % d , % d , % d , % d ) " ,
2010-10-18 17:34:59 -04:00
intval ( local_user ()),
2010-07-22 05:13:39 -04:00
datetime_convert (),
dbesc ( $dfrn_url ),
2011-11-01 19:08:07 -04:00
dbesc ( normalise_link ( $dfrn_url )),
2015-11-25 12:46:02 -05:00
$parms [ 'addr' ],
2010-07-22 05:13:39 -04:00
$parms [ 'fn' ],
2010-10-23 04:20:26 -04:00
$parms [ 'nick' ],
2010-07-22 05:13:39 -04:00
$parms [ 'photo' ],
$parms [ 'key' ],
$parms [ 'dfrn-request' ],
$parms [ 'dfrn-confirm' ],
$parms [ 'dfrn-notify' ],
$parms [ 'dfrn-poll' ],
2011-10-31 23:39:04 -04:00
$parms [ 'dfrn-poco' ],
2011-08-18 19:47:45 -04:00
dbesc ( NETWORK_DFRN ),
2012-05-29 21:43:56 -04:00
intval ( $aes_allow ),
2016-11-28 21:08:46 -05:00
intval ( $hidden ),
intval ( $blocked ),
intval ( $pending )
2010-07-22 05:13:39 -04:00
);
}
2010-07-06 00:39:55 -04:00
2016-12-20 15:15:53 -05:00
if ( $r ) {
2011-05-23 05:39:57 -04:00
info ( t ( " Introduction complete. " ) . EOL );
2010-07-22 05:13:39 -04:00
}
2016-03-06 07:15:27 -05:00
$r = q ( " SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1 " ,
2012-06-12 04:13:09 -04:00
intval ( local_user ()),
2012-06-12 19:17:34 -04:00
dbesc ( $dfrn_url ),
2012-06-12 04:13:09 -04:00
$parms [ 'key' ] // this was already escaped
);
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r )) {
2016-03-06 07:15:27 -05:00
$def_gid = get_default_group ( local_user (), $r [ 0 ][ " network " ]);
2017-03-21 12:02:59 -04:00
if ( intval ( $def_gid ))
2016-03-06 07:15:27 -05:00
group_add_member ( local_user (), '' , $r [ 0 ][ 'id' ], $def_gid );
2016-04-13 16:21:23 -04:00
2016-06-25 07:56:55 -04:00
if ( isset ( $photo ))
2017-11-29 17:29:11 -05:00
Contact :: updateAvatar ( $photo , local_user (), $r [ 0 ][ " id " ], true );
2016-06-25 07:56:55 -04:00
2017-08-26 03:32:10 -04:00
$forwardurl = System :: baseUrl () . " /contacts/ " . $r [ 0 ][ 'id' ];
2016-12-20 04:44:27 -05:00
} else {
2017-08-26 03:32:10 -04:00
$forwardurl = System :: baseUrl () . " /contacts " ;
2016-12-20 04:44:27 -05:00
}
2012-06-12 04:13:09 -04:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Allow the blocked remote notification to complete
*/
2010-07-01 19:48:07 -04:00
2016-12-20 04:44:27 -05:00
if ( is_array ( $contact_record )) {
2010-07-22 05:13:39 -04:00
$dfrn_request = $contact_record [ 'request' ];
2016-12-20 04:44:27 -05:00
}
2010-07-01 19:48:07 -04:00
2016-12-20 04:44:27 -05:00
if ( strlen ( $dfrn_request ) && strlen ( $confirm_key )) {
2011-03-30 18:04:18 -04:00
$s = fetch_url ( $dfrn_request . '?confirm_key=' . $confirm_key );
2016-12-20 04:44:27 -05:00
}
2014-08-20 18:56:21 -04:00
2010-12-14 19:34:49 -05:00
// (ignore reply, nothing we can do it failed)
2014-09-01 10:55:16 -04:00
// Old: goaway(zrl($dfrn_url));
goaway ( $forwardurl );
2010-07-22 05:13:39 -04:00
return ; // NOTREACHED
2010-07-06 00:39:55 -04:00
2010-07-22 05:13:39 -04:00
}
2010-07-06 00:39:55 -04:00
2010-07-01 19:48:07 -04:00
}
2010-07-22 05:13:39 -04:00
// invalid/bogus request
2010-09-13 20:12:54 -04:00
notice ( t ( 'Unrecoverable protocol error.' ) . EOL );
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl ());
2010-07-22 05:13:39 -04:00
return ; // NOTREACHED
2010-07-01 19:48:07 -04:00
}
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
* Otherwise :
2014-09-06 11:28:46 -04:00
*
2010-12-14 19:34:49 -05:00
* Scenario 1 :
2014-09-06 11:28:46 -04:00
* We are the requestee . A person from a remote cell has made an introduction
* on our profile web page and clicked submit . We will use their DFRN - URL to
* figure out how to contact their cell .
2010-12-14 19:34:49 -05:00
*
* Scrape the originating DFRN - URL for everything we need . Create a contact record
* and an introduction to show our user next time he / she logs in .
* Finally redirect back to the requestor so that their site can record the request .
2014-09-06 11:28:46 -04:00
* If our user ( the requestee ) later confirms this request , a record of it will need
* to exist on the requestor ' s cell in order for the confirmation process to complete ..
2010-12-14 19:34:49 -05:00
*
* It ' s possible that neither the requestor or the requestee are logged in at the moment ,
* and the requestor does not yet have any credentials to the requestee profile .
*
* Who is the requestee ? We ' ve already loaded their profile which means their nickname should be
* in $a -> argv [ 1 ] and we should have their complete info in $a -> profile .
*
*/
2010-07-01 19:48:07 -04:00
2017-03-21 12:02:59 -04:00
if ( ! ( is_array ( $a -> profile ) && count ( $a -> profile ))) {
2010-09-01 20:26:02 -04:00
notice ( t ( 'Profile unavailable.' ) . EOL );
2010-07-22 05:13:39 -04:00
return ;
}
2010-12-20 03:27:00 -05:00
$nickname = $a -> profile [ 'nickname' ];
$notify_flags = $a -> profile [ 'notify-flags' ];
$uid = $a -> profile [ 'uid' ];
$maxreq = intval ( $a -> profile [ 'maxreq' ]);
2010-07-06 00:39:55 -04:00
$contact_record = null ;
2010-12-20 03:27:00 -05:00
$failed = false ;
$parms = null ;
2016-11-29 09:52:12 -05:00
$blocked = 1 ;
$pending = 1 ;
2010-07-01 19:48:07 -04:00
2017-03-21 12:02:59 -04:00
if ( x ( $_POST , 'dfrn_url' )) {
2010-07-01 19:48:07 -04:00
2016-11-27 19:13:47 -05:00
/*
2010-12-20 03:27:00 -05:00
* Block friend request spam
*/
2017-03-21 12:02:59 -04:00
if ( $maxreq ) {
2010-12-20 03:27:00 -05:00
$r = q ( " SELECT * FROM `intro` WHERE `datetime` > '%s' AND `uid` = %d " ,
dbesc ( datetime_convert ( 'UTC' , 'UTC' , 'now - 24 hours' )),
intval ( $uid )
);
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r ) && count ( $r ) > $maxreq ) {
2011-03-10 18:22:21 -05:00
notice ( sprintf ( t ( '%s has received too many connection requests today.' ), $a -> profile [ 'name' ]) . EOL );
2010-12-20 03:27:00 -05:00
notice ( t ( 'Spam protection measures have been invoked.' ) . EOL );
notice ( t ( 'Friends are advised to please try again in 24 hours.' ) . EOL );
return ;
2014-09-06 11:28:46 -04:00
}
2010-12-20 03:27:00 -05:00
}
2016-11-27 19:13:47 -05:00
/*
2011-01-07 03:24:08 -05:00
*
2014-09-06 11:28:46 -04:00
* Cleanup old introductions that remain blocked .
2011-01-07 03:24:08 -05:00
* Also remove the contact record , but only if there is no existing relationship
2011-12-12 02:33:56 -05:00
*/
2014-09-06 11:28:46 -04:00
$r = q ( " SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
2011-12-12 02:33:56 -05:00
FROM `intro` LEFT JOIN `contact` on `intro` . `contact-id` = `contact` . `id`
2014-09-06 11:28:46 -04:00
WHERE `intro` . `blocked` = 1 AND `contact` . `self` = 0
2017-12-03 04:19:58 -05:00
AND `intro` . `datetime` < UTC_TIMESTAMP () - INTERVAL 30 MINUTE "
2011-12-12 02:33:56 -05:00
);
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r )) {
2016-12-20 15:15:53 -05:00
foreach ( $r as $rr ) {
2017-03-21 12:02:59 -04:00
if ( ! $rr [ 'rel' ]) {
2017-01-29 08:57:03 -05:00
q ( " DELETE FROM `contact` WHERE `id` = %d AND NOT `self` " ,
2011-12-12 02:33:56 -05:00
intval ( $rr [ 'cid' ])
);
}
2014-03-11 18:52:32 -04:00
q ( " DELETE FROM `intro` WHERE `id` = %d " ,
2011-12-12 02:33:56 -05:00
intval ( $rr [ 'iid' ])
);
}
}
2012-04-10 22:15:52 -04:00
$real_name = ( x ( $_POST , 'realname' ) ? notags ( trim ( $_POST [ 'realname' ])) : '' );
2011-12-12 02:33:56 -05:00
2010-07-01 19:48:07 -04:00
$url = trim ( $_POST [ 'dfrn_url' ]);
2017-03-21 12:02:59 -04:00
if ( ! strlen ( $url )) {
2010-07-27 22:27:14 -04:00
notice ( t ( " Invalid locator " ) . EOL );
2010-07-06 00:39:55 -04:00
return ;
}
2011-09-06 21:06:19 -04:00
$hcard = '' ;
2010-07-19 22:09:58 -04:00
2017-12-03 04:19:58 -05:00
// Detect the network
$data = Probe :: uri ( $url );
$network = $data [ " network " ];
2012-04-10 22:15:52 -04:00
2017-12-03 04:19:58 -05:00
// Canonicalise email-style profile locator
$url = Probe :: webfingerDfrn ( $url , $hcard );
2012-04-10 22:15:52 -04:00
2017-12-03 04:19:58 -05:00
if ( substr ( $url , 0 , 5 ) === 'stat:' ) {
2012-12-23 05:47:14 -05:00
2017-12-03 04:19:58 -05:00
// Every time we detect the remote subscription we define this as OStatus.
// We do this even if it is not OStatus.
// we only need to pass this through another section of the code.
if ( $network != NETWORK_DIASPORA ) {
$network = NETWORK_OSTATUS ;
2012-04-10 22:15:52 -04:00
}
2017-12-03 04:19:58 -05:00
$url = substr ( $url , 5 );
2016-01-01 11:49:07 -05:00
} else {
2017-12-03 04:19:58 -05:00
$network = NETWORK_DFRN ;
2010-07-08 10:03:25 -04:00
}
2010-07-06 00:39:55 -04:00
2016-12-14 10:36:32 -05:00
logger ( 'dfrn_request: url: ' . $url . ',network=' . $network , LOGGER_DEBUG );
2017-03-21 12:02:59 -04:00
if ( $network === NETWORK_DFRN ) {
2014-09-06 11:28:46 -04:00
$ret = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1 " ,
2010-10-12 22:32:15 -04:00
intval ( $uid ),
dbesc ( $url )
2010-07-06 00:39:55 -04:00
);
2010-09-13 20:12:54 -04:00
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $ret )) {
2017-03-21 12:02:59 -04:00
if ( strlen ( $ret [ 0 ][ 'issued-id' ])) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'You have already introduced yourself here.' ) . EOL );
return ;
}
2017-03-21 12:02:59 -04:00
elseif ( $ret [ 0 ][ 'rel' ] == CONTACT_IS_FRIEND ) {
2011-03-10 18:22:21 -05:00
notice ( sprintf ( t ( 'Apparently you are already friends with %s.' ), $a -> profile [ 'name' ]) . EOL );
2010-10-17 23:04:17 -04:00
return ;
}
2010-10-12 22:32:15 -04:00
else {
$contact_record = $ret [ 0 ];
$parms = array ( 'dfrn-request' => $ret [ 0 ][ 'request' ]);
}
2010-09-13 20:12:54 -04:00
}
2010-10-17 23:04:17 -04:00
2010-10-12 22:32:15 -04:00
$issued_id = random_string ();
2017-03-21 12:02:59 -04:00
if ( is_array ( $contact_record )) {
2010-10-12 22:32:15 -04:00
// There is a contact record but no issued-id, so this
// is a reciprocal introduction from a known contact
2013-12-02 14:30:24 -05:00
$r = q ( " UPDATE `contact` SET `issued-id` = '%s' WHERE `id` = %d " ,
2010-10-12 22:32:15 -04:00
dbesc ( $issued_id ),
intval ( $contact_record [ 'id' ])
);
2010-07-01 19:48:07 -04:00
}
else {
2016-12-20 11:43:46 -05:00
if ( ! validate_url ( $url )) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Invalid profile URL.' ) . EOL );
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl () . '/' . $a -> cmd );
2010-10-12 22:32:15 -04:00
return ; // NOTREACHED
}
2010-07-01 19:48:07 -04:00
2016-12-20 11:43:46 -05:00
if ( ! allowed_url ( $url )) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Disallowed profile URL.' ) . EOL );
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl () . '/' . $a -> cmd );
2010-10-12 22:32:15 -04:00
return ; // NOTREACHED
2010-07-01 19:48:07 -04:00
}
2014-09-06 11:28:46 -04:00
2017-04-26 00:23:01 -04:00
if ( blocked_url ( $url )) {
2017-04-25 22:45:56 -04:00
notice ( t ( 'Blocked domain' ) . EOL );
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl () . '/' . $a -> cmd );
2017-04-25 22:45:56 -04:00
return ; // NOTREACHED
}
2010-07-01 19:48:07 -04:00
2016-07-04 02:05:30 -04:00
$parms = Probe :: profile (( $hcard ) ? $hcard : $url );
2010-10-12 22:32:15 -04:00
2016-12-20 11:43:46 -05:00
if ( ! count ( $parms )) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Profile location is not valid or does not contain profile information.' ) . EOL );
2017-08-26 03:32:10 -04:00
goaway ( System :: baseUrl () . '/' . $a -> cmd );
2010-10-12 22:32:15 -04:00
}
else {
2016-12-20 11:43:46 -05:00
if ( ! x ( $parms , 'fn' )) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Warning: profile location has no identifiable owner name.' ) . EOL );
2016-12-20 11:43:46 -05:00
}
if ( ! x ( $parms , 'photo' )) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Warning: profile location has no profile photo.' ) . EOL );
2016-12-20 11:43:46 -05:00
}
2017-05-08 10:19:10 -04:00
$invalid = Probe :: validDfrn ( $parms );
2016-12-20 11:43:46 -05:00
if ( $invalid ) {
2011-03-10 18:22:21 -05:00
notice ( sprintf ( tt ( " %d required parameter was not found at the given location " ,
" %d required parameters were not found at the given location " ,
$invalid ), $invalid ) . EOL );
2014-09-06 11:28:46 -04:00
2010-10-12 22:32:15 -04:00
return ;
}
}
2010-07-01 19:48:07 -04:00
2010-10-12 22:32:15 -04:00
$parms [ 'url' ] = $url ;
$parms [ 'issued-id' ] = $issued_id ;
2016-06-25 07:56:55 -04:00
$photo = $parms [ " photo " ];
2010-07-06 00:39:55 -04:00
2017-11-07 22:57:46 -05:00
DBM :: esc_array ( $parms );
2015-11-25 12:46:02 -05:00
$r = q ( " INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `name`, `nick`, `issued-id`, `photo`, `site-pubkey`,
2016-11-29 09:52:12 -05:00
`request` , `confirm` , `notify` , `poll` , `poco` , `network` , `blocked` , `pending` )
VALUES ( % d , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % d , % d ) " ,
2010-07-06 00:39:55 -04:00
intval ( $uid ),
2011-11-01 19:08:07 -04:00
dbesc ( datetime_convert ()),
2010-07-06 00:39:55 -04:00
$parms [ 'url' ],
2016-06-25 07:56:55 -04:00
dbesc ( normalise_link ( $url )),
2015-11-25 12:46:02 -05:00
$parms [ 'addr' ],
2010-10-12 22:32:15 -04:00
$parms [ 'fn' ],
2010-10-23 04:20:26 -04:00
$parms [ 'nick' ],
2010-10-12 22:32:15 -04:00
$parms [ 'issued-id' ],
$parms [ 'photo' ],
$parms [ 'key' ],
$parms [ 'dfrn-request' ],
$parms [ 'dfrn-confirm' ],
$parms [ 'dfrn-notify' ],
2011-08-18 19:47:45 -04:00
$parms [ 'dfrn-poll' ],
2011-10-31 23:39:04 -04:00
$parms [ 'dfrn-poco' ],
2016-11-29 09:52:12 -05:00
dbesc ( NETWORK_DFRN ),
intval ( $blocked ),
intval ( $pending )
2010-07-06 00:39:55 -04:00
);
2010-07-01 19:48:07 -04:00
2010-10-12 22:32:15 -04:00
// find the contact record we just created
2016-12-20 04:44:27 -05:00
if ( $r ) {
2014-03-11 18:52:32 -04:00
$r = q ( " SELECT `id` FROM `contact`
2010-10-12 22:32:15 -04:00
WHERE `uid` = % d AND `url` = '%s' AND `issued-id` = '%s' LIMIT 1 " ,
intval ( $uid ),
$parms [ 'url' ],
$parms [ 'issued-id' ]
);
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r )) {
2010-10-12 22:32:15 -04:00
$contact_record = $r [ 0 ];
2017-11-29 17:29:11 -05:00
Contact :: updateAvatar ( $photo , $uid , $contact_record [ " id " ], true );
2016-06-25 07:56:55 -04:00
}
2010-10-12 22:32:15 -04:00
}
2013-12-02 14:30:24 -05:00
2010-10-12 22:32:15 -04:00
}
2016-12-20 04:44:27 -05:00
if ( $r === false ) {
2010-10-12 22:32:15 -04:00
notice ( t ( 'Failed to update contact record.' ) . EOL );
return ;
}
2010-07-01 19:48:07 -04:00
2010-10-12 22:32:15 -04:00
$hash = random_string () . ( string ) time (); // Generate a confirm_key
2013-12-02 14:30:24 -05:00
2016-12-20 04:44:27 -05:00
if ( is_array ( $contact_record )) {
2010-10-12 22:32:15 -04:00
$ret = q ( " INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
VALUES ( % d , % d , 1 , % d , '%s' , '%s' , '%s' ) " ,
intval ( $uid ),
intval ( $contact_record [ 'id' ]),
(( x ( $_POST , 'knowyou' ) && ( $_POST [ 'knowyou' ] == 1 )) ? 1 : 0 ),
dbesc ( notags ( trim ( $_POST [ 'dfrn-request-message' ]))),
dbesc ( $hash ),
dbesc ( datetime_convert ())
);
}
2014-08-20 18:56:21 -04:00
2010-10-17 23:04:17 -04:00
// This notice will only be seen by the requestor if the requestor and requestee are on the same server.
2010-07-01 19:48:07 -04:00
2016-12-20 04:44:27 -05:00
if ( ! $failed ) {
2011-05-23 05:39:57 -04:00
info ( t ( 'Your introduction has been sent.' ) . EOL );
2016-12-20 04:44:27 -05:00
}
2010-07-01 19:48:07 -04:00
2010-10-12 22:32:15 -04:00
// "Homecoming" - send the requestor back to their site to record the introduction.
2010-07-01 19:48:07 -04:00
2017-08-26 03:32:10 -04:00
$dfrn_url = bin2hex ( System :: baseUrl () . '/profile/' . $nickname );
2010-10-12 22:32:15 -04:00
$aes_allow = (( function_exists ( 'openssl_encrypt' )) ? 1 : 0 );
2010-07-01 19:48:07 -04:00
2014-09-06 11:28:46 -04:00
goaway ( $parms [ 'dfrn-request' ] . " ?dfrn_url= $dfrn_url "
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
. '&confirm_key=' . $hash
2010-10-12 22:32:15 -04:00
. (( $aes_allow ) ? " &aes_allow=1 " : " " )
);
// NOTREACHED
2011-08-18 19:47:45 -04:00
// END $network === NETWORK_DFRN
2017-06-07 22:00:59 -04:00
} elseif (( $network != NETWORK_PHANTOM ) && ( $url != " " )) {
2014-09-06 11:28:46 -04:00
2016-11-27 19:13:47 -05:00
/*
2010-12-14 19:34:49 -05:00
*
* Substitute our user ' s feed URL into $url template
* Send the subscriber home to subscribe
*
*/
2010-10-12 22:32:15 -04:00
2015-12-27 21:14:38 -05:00
// Diaspora needs the uri in the format user@domain.tld
// Diaspora will support the remote subscription in a future version
if ( $network == NETWORK_DIASPORA ) {
$uri = $nickname . '@' . $a -> get_hostname ();
if ( $a -> get_path ())
$uri .= '/' . $a -> get_path ();
$uri = urlencode ( $uri );
2016-12-20 04:44:27 -05:00
} else {
2017-08-26 03:32:10 -04:00
$uri = System :: baseUrl () . '/profile/' . $nickname ;
2016-12-20 04:44:27 -05:00
}
2015-12-27 21:14:38 -05:00
$url = str_replace ( '{uri}' , $uri , $url );
2010-10-12 22:32:15 -04:00
goaway ( $url );
// NOTREACHED
2015-12-27 21:14:38 -05:00
// END $network != NETWORK_PHANTOM
} else {
notice ( t ( " Remote subscription can't be done for your network. Please subscribe directly on your system. " ) . EOL );
return ;
2010-10-12 22:32:15 -04:00
}
2010-07-01 19:48:07 -04:00
2010-10-12 22:32:15 -04:00
} return ;
2016-11-27 19:13:47 -05:00
}
2010-07-22 05:13:39 -04:00
2017-01-09 07:12:54 -05:00
function dfrn_request_content ( App $a ) {
2010-07-01 19:48:07 -04:00
2016-12-20 04:44:27 -05:00
if (( $a -> argc != 2 ) || ( ! count ( $a -> profile ))) {
2010-07-01 19:48:07 -04:00
return " " ;
2016-12-20 04:44:27 -05:00
}
2010-07-01 19:48:07 -04:00
// "Homecoming". Make sure we're logged in to this site as the correct user. Then offer a confirm button
// to send us to the post section to record the introduction.
2016-12-20 04:44:27 -05:00
if ( x ( $_GET , 'dfrn_url' )) {
2010-07-01 19:48:07 -04:00
2016-12-20 04:44:27 -05:00
if ( ! local_user ()) {
2011-05-23 05:39:57 -04:00
info ( t ( " Please login to confirm introduction. " ) . EOL );
2011-01-07 02:41:14 -05:00
/* setup the return URL to come back to this page if they use openid */
2014-10-22 03:32:24 -04:00
$_SESSION [ 'return_url' ] = $a -> query_string ;
2010-07-01 19:48:07 -04:00
return login ();
}
2014-09-06 11:28:46 -04:00
// Edge case, but can easily happen in the wild. This person is authenticated,
2010-07-01 19:48:07 -04:00
// but not as the person who needs to deal with this request.
2010-07-22 05:13:39 -04:00
if ( $a -> user [ 'nickname' ] != $a -> argv [ 1 ]) {
2010-07-27 22:27:14 -04:00
notice ( t ( " Incorrect identity currently logged in. Please login to <strong>this</strong> profile. " ) . EOL );
2010-07-01 19:48:07 -04:00
return login ();
}
2010-07-22 05:13:39 -04:00
$dfrn_url = notags ( trim ( hex2bin ( $_GET [ 'dfrn_url' ])));
2010-07-01 19:48:07 -04:00
$aes_allow = ((( x ( $_GET , 'aes_allow' )) && ( $_GET [ 'aes_allow' ] == 1 )) ? 1 : 0 );
$confirm_key = ( x ( $_GET , 'confirm_key' ) ? $_GET [ 'confirm_key' ] : " " );
2015-04-08 18:10:21 -04:00
// Checking fastlane for validity
2017-06-07 22:00:59 -04:00
if ( x ( $_SESSION , " fastlane " ) && ( normalise_link ( $_SESSION [ " fastlane " ]) == normalise_link ( $dfrn_url ))) {
2015-04-08 18:10:21 -04:00
$_POST [ " dfrn_url " ] = $dfrn_url ;
$_POST [ " confirm_key " ] = $confirm_key ;
$_POST [ " localconfirm " ] = 1 ;
$_POST [ " hidden-contact " ] = 0 ;
$_POST [ " submit " ] = t ( 'Confirm' );
dfrn_request_post ( $a );
killme ();
return ; // NOTREACHED
}
2011-05-11 07:37:13 -04:00
$tpl = get_markup_template ( " dfrn_req_confirm.tpl " );
$o = replace_macros ( $tpl , array (
2010-07-01 19:48:07 -04:00
'$dfrn_url' => $dfrn_url ,
'$aes_allow' => (( $aes_allow ) ? '<input type="hidden" name="aes_allow" value="1" />' : " " ),
2012-05-29 21:43:56 -04:00
'$hidethem' => t ( 'Hide this contact' ),
'$hidechecked' => '' ,
2010-07-01 19:48:07 -04:00
'$confirm_key' => $confirm_key ,
2011-04-07 02:03:54 -04:00
'$welcome' => sprintf ( t ( 'Welcome home %s.' ), $a -> user [ 'username' ]),
'$please' => sprintf ( t ( 'Please confirm your introduction/connection request to %s.' ), $dfrn_url ),
'$submit' => t ( 'Confirm' ),
2010-07-01 19:48:07 -04:00
'$uid' => $_SESSION [ 'uid' ],
2010-07-20 23:48:08 -04:00
'$nickname' => $a -> user [ 'nickname' ],
2010-07-01 19:48:07 -04:00
'dfrn_rawurl' => $_GET [ 'dfrn_url' ]
));
return $o ;
}
2017-03-21 12:02:59 -04:00
elseif (( x ( $_GET , 'confirm_key' )) && strlen ( $_GET [ 'confirm_key' ])) {
2010-07-22 05:13:39 -04:00
// we are the requestee and it is now safe to send our user their introduction,
2014-09-06 11:28:46 -04:00
// We could just unblock it, but first we have to jump through a few hoops to
// send an email, or even to find out if we need to send an email.
2010-07-22 05:13:39 -04:00
$intro = q ( " SELECT * FROM `intro` WHERE `hash` = '%s' LIMIT 1 " ,
dbesc ( $_GET [ 'confirm_key' ])
);
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $intro )) {
2016-05-01 08:24:44 -04:00
2010-07-22 05:13:39 -04:00
$r = q ( " SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
WHERE `contact` . `id` = % d LIMIT 1 " ,
intval ( $intro [ 0 ][ 'contact-id' ])
);
2010-10-17 23:04:17 -04:00
$auto_confirm = false ;
2017-11-07 22:57:46 -05:00
if ( DBM :: is_result ( $r )) {
2017-03-21 12:02:59 -04:00
if (( $r [ 0 ][ 'page-flags' ] != PAGE_NORMAL ) && ( $r [ 0 ][ 'page-flags' ] != PAGE_PRVGROUP ))
2014-03-11 18:52:32 -04:00
$auto_confirm = true ;
2011-12-26 18:47:40 -05:00
2017-03-21 12:02:59 -04:00
if ( ! $auto_confirm ) {
2014-09-06 11:28:46 -04:00
2011-12-26 18:47:40 -05:00
notification ( array (
'type' => NOTIFY_INTRO ,
'notify_flags' => $r [ 0 ][ 'notify-flags' ],
'language' => $r [ 0 ][ 'language' ],
'to_name' => $r [ 0 ][ 'username' ],
'to_email' => $r [ 0 ][ 'email' ],
2012-02-18 05:57:42 -05:00
'uid' => $r [ 0 ][ 'uid' ],
2017-08-26 03:32:10 -04:00
'link' => System :: baseUrl () . '/notifications/intros' ,
2011-12-26 18:47:40 -05:00
'source_name' => (( strlen ( stripslashes ( $r [ 0 ][ 'name' ]))) ? stripslashes ( $r [ 0 ][ 'name' ]) : t ( '[Name Withheld]' )),
'source_link' => $r [ 0 ][ 'url' ],
2012-01-03 23:26:20 -05:00
'source_photo' => $r [ 0 ][ 'photo' ],
'verb' => ACTIVITY_REQ_FRIEND ,
'otype' => 'intro'
2010-07-22 05:13:39 -04:00
));
}
2011-12-26 18:47:40 -05:00
2017-03-21 12:02:59 -04:00
if ( $auto_confirm ) {
2017-05-07 14:40:23 -04:00
require_once 'mod/dfrn_confirm.php' ;
2010-10-17 23:04:17 -04:00
$handsfree = array (
2016-12-14 03:56:27 -05:00
'uid' => $r [ 0 ][ 'uid' ],
'node' => $r [ 0 ][ 'nickname' ],
'dfrn_id' => $r [ 0 ][ 'issued-id' ],
2010-10-17 23:04:17 -04:00
'intro_id' => $intro [ 0 ][ 'id' ],
2016-12-14 03:56:27 -05:00
'duplex' => (( $r [ 0 ][ 'page-flags' ] == PAGE_FREELOVE ) ? 1 : 0 ),
2017-11-06 21:22:52 -05:00
'activity' => intval ( PConfig :: get ( $r [ 0 ][ 'uid' ], 'system' , 'post_newfriend' ))
2010-10-17 23:04:17 -04:00
);
dfrn_confirm_post ( $a , $handsfree );
}
2010-07-22 05:13:39 -04:00
}
2017-03-21 12:02:59 -04:00
if ( ! $auto_confirm ) {
2010-07-01 19:48:07 -04:00
2010-10-17 23:04:17 -04:00
// If we are auto_confirming, this record will have already been nuked
// in dfrn_confirm_post()
2013-12-02 14:30:24 -05:00
$r = q ( " UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s' " ,
2010-10-17 23:04:17 -04:00
dbesc ( $_GET [ 'confirm_key' ])
);
}
2010-07-22 05:13:39 -04:00
}
2011-08-18 19:47:45 -04:00
2010-07-22 05:13:39 -04:00
killme ();
return ; // NOTREACHED
}
else {
2011-01-01 16:12:31 -05:00
2016-11-27 19:13:47 -05:00
/*
2011-01-01 16:12:31 -05:00
* Normal web request . Display our user ' s introduction form .
*/
2014-09-06 11:28:46 -04:00
2017-11-06 21:22:52 -05:00
if (( Config :: get ( 'system' , 'block_public' )) && ( ! local_user ()) && ( ! remote_user ())) {
if ( ! Config :: get ( 'system' , 'local_block' )) {
2012-09-06 23:17:50 -04:00
notice ( t ( 'Public access denied.' ) . EOL );
return ;
}
2011-04-21 22:12:22 -04:00
}
2016-11-27 19:13:47 -05:00
/*
2011-01-01 16:12:31 -05:00
* Try to auto - fill the profile address
*/
2014-08-20 18:56:21 -04:00
// At first look if an address was provided
// Otherwise take the local address
2017-06-07 22:00:59 -04:00
if ( x ( $_GET , 'addr' ) && ( $_GET [ 'addr' ] != " " )) {
2014-08-20 18:56:21 -04:00
$myaddr = hex2bin ( $_GET [ 'addr' ]);
2017-06-07 22:00:59 -04:00
} elseif ( x ( $_GET , 'address' ) && ( $_GET [ 'address' ] != " " )) {
2014-08-20 18:56:21 -04:00
$myaddr = $_GET [ 'address' ];
2016-12-19 08:26:13 -05:00
} elseif ( local_user ()) {
2016-12-20 11:43:46 -05:00
if ( strlen ( $a -> path )) {
2017-08-26 03:32:10 -04:00
$myaddr = System :: baseUrl () . '/profile/' . $a -> user [ 'nickname' ];
2016-12-19 08:26:13 -05:00
} else {
2017-08-26 03:32:10 -04:00
$myaddr = $a -> user [ 'nickname' ] . '@' . substr ( System :: baseUrl (), strpos ( System :: baseUrl (), '://' ) + 3 );
2011-01-01 16:12:31 -05:00
}
2016-12-19 08:26:13 -05:00
} else {
2016-12-20 11:43:46 -05:00
// last, try a zrl
2012-04-27 19:23:25 -04:00
$myaddr = get_my_url ();
2016-12-20 11:43:46 -05:00
}
2012-04-27 19:23:25 -04:00
2017-08-26 03:32:10 -04:00
$target_addr = $a -> profile [ 'nickname' ] . '@' . substr ( System :: baseUrl (), strpos ( System :: baseUrl (), '://' ) + 3 );
2011-09-05 21:34:30 -04:00
2016-11-27 19:13:47 -05:00
/*
2011-01-01 16:12:31 -05:00
*
* The auto_request form only has the profile address
2014-09-06 11:28:46 -04:00
* because nobody is going to read the comments and
2011-01-01 16:12:31 -05:00
* it doesn ' t matter if they know you or not .
*
*/
2016-12-20 11:43:46 -05:00
if ( $a -> profile [ 'page-flags' ] == PAGE_NORMAL ) {
2011-05-11 07:37:13 -04:00
$tpl = get_markup_template ( 'dfrn_request.tpl' );
2016-12-19 08:26:13 -05:00
} else {
2011-05-11 07:37:13 -04:00
$tpl = get_markup_template ( 'auto_request.tpl' );
2016-12-20 11:43:46 -05:00
}
2011-01-01 16:12:31 -05:00
2016-03-01 12:28:06 -05:00
$page_desc = t ( " Please enter your 'Identity Address' from one of the following supported communications networks: " );
2012-03-13 18:40:16 -04:00
2015-08-26 13:17:41 -04:00
$invite_desc = sprintf (
t ( 'If you are not yet a member of the free social web, <a href="%s/siteinfo">follow this link to find a public Friendica site and join us today</a>.' ),
get_server ()
);
2011-09-05 21:34:30 -04:00
2016-03-01 12:28:06 -05:00
$o = replace_macros ( $tpl , array (
2010-12-16 22:38:52 -05:00
'$header' => t ( 'Friend/Connection Request' ),
2017-12-03 08:26:52 -05:00
'$desc' => t ( 'Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@gnusocial.de' ),
2010-12-16 22:38:52 -05:00
'$pls_answer' => t ( 'Please answer the following:' ),
2017-04-08 10:57:24 -04:00
'$does_know_you' => array ( 'knowyou' , sprintf ( t ( 'Does %s know you?' ), $a -> profile [ 'name' ]), false , '' , array ( t ( 'No' ), t ( 'Yes' ))),
2014-08-20 18:56:21 -04:00
/* '$does_know' => sprintf ( t ( 'Does %s know you?' ), $a -> profile [ 'name' ]),
2010-12-16 22:38:52 -05:00
'$yes' => t ( 'Yes' ),
2014-08-20 18:56:21 -04:00
'$no' => t ( 'No' ), */
2010-12-16 22:38:52 -05:00
'$add_note' => t ( 'Add a personal note:' ),
2011-09-05 21:34:30 -04:00
'$page_desc' => $page_desc ,
2012-02-19 13:44:30 -05:00
'$friendica' => t ( 'Friendica' ),
2017-12-03 08:26:52 -05:00
'$statusnet' => t ( 'GNU Social (Pleroma, Mastodon)' ),
'$diaspora' => t ( 'Diaspora (Socialhome, Hubzilla)' ),
2012-04-01 19:18:03 -04:00
'$diasnote' => sprintf ( t ( ' - please do not use this form. Instead, enter %s into your Diaspora search bar.' ), $target_addr ),
2011-04-14 23:37:42 -04:00
'$your_address' => t ( 'Your Identity Address:' ),
2012-03-13 18:40:16 -04:00
'$invite_desc' => $invite_desc ,
2010-12-16 22:38:52 -05:00
'$submit' => t ( 'Submit Request' ),
'$cancel' => t ( 'Cancel' ),
2010-10-26 00:52:30 -04:00
'$nickname' => $a -> argv [ 1 ],
'$name' => $a -> profile [ 'name' ],
'$myaddr' => $myaddr
));
2010-07-22 05:13:39 -04:00
return $o ;
2010-07-01 19:48:07 -04:00
}
2010-07-27 22:27:14 -04:00
2010-07-22 05:13:39 -04:00
return ; // Somebody is fishing.
2016-11-27 19:13:47 -05:00
}