Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

884 lines
25 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
  1. <?php
  2. /**
  3. *
  4. * Module: dfrn_request
  5. *
  6. * Purpose: Handles communication associated with the issuance of
  7. * friend requests.
  8. *
  9. */
  10. require_once('include/enotify.php');
  11. require_once('include/Scrape.php');
  12. require_once('include/Probe.php');
  13. require_once('include/group.php');
  14. if(! function_exists('dfrn_request_init')) {
  15. function dfrn_request_init(&$a) {
  16. if($a->argc > 1)
  17. $which = $a->argv[1];
  18. profile_load($a,$which);
  19. return;
  20. }}
  21. /**
  22. * Function: dfrn_request_post
  23. *
  24. * Purpose:
  25. * Handles multiple scenarios.
  26. *
  27. * Scenario 1:
  28. * Clicking 'submit' on a friend request page.
  29. *
  30. * Scenario 2:
  31. * Following Scenario 1, we are brought back to our home site
  32. * in order to link our friend request with our own server cell.
  33. * After logging in, we click 'submit' to approve the linkage.
  34. *
  35. */
  36. if(! function_exists('dfrn_request_post')) {
  37. function dfrn_request_post(&$a) {
  38. if(($a->argc != 2) || (! count($a->profile))) {
  39. logger('Wrong count of argc or profiles: argc=' . $a->argc . ',profile()=' . count($a->profile));
  40. return;
  41. }
  42. if(x($_POST, 'cancel')) {
  43. goaway(z_root());
  44. }
  45. /**
  46. *
  47. * Scenario 2: We've introduced ourself to another cell, then have been returned to our own cell
  48. * to confirm the request, and then we've clicked submit (perhaps after logging in).
  49. * That brings us here:
  50. *
  51. */
  52. if((x($_POST,'localconfirm')) && ($_POST['localconfirm'] == 1)) {
  53. /**
  54. * Ensure this is a valid request
  55. */
  56. if(local_user() && ($a->user['nickname'] == $a->argv[1]) && (x($_POST,'dfrn_url'))) {
  57. $dfrn_url = notags(trim($_POST['dfrn_url']));
  58. $aes_allow = (((x($_POST,'aes_allow')) && ($_POST['aes_allow'] == 1)) ? 1 : 0);
  59. $confirm_key = ((x($_POST,'confirm_key')) ? $_POST['confirm_key'] : "");
  60. $hidden = ((x($_POST,'hidden-contact')) ? intval($_POST['hidden-contact']) : 0);
  61. $contact_record = null;
  62. if(x($dfrn_url)) {
  63. /**
  64. * Lookup the contact based on their URL (which is the only unique thing we have at the moment)
  65. */
  66. $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND (`url` = '%s' OR `nurl` = '%s') AND `self` = 0 LIMIT 1",
  67. intval(local_user()),
  68. dbesc($dfrn_url),
  69. dbesc(normalise_link($dfrn_url))
  70. );
  71. if(count($r)) {
  72. if(strlen($r[0]['dfrn-id'])) {
  73. /**
  74. * We don't need to be here. It has already happened.
  75. */
  76. notice( t("This introduction has already been accepted.") . EOL );
  77. return;
  78. }
  79. else
  80. $contact_record = $r[0];
  81. }
  82. if(is_array($contact_record)) {
  83. $r = q("UPDATE `contact` SET `ret-aes` = %d, hidden = %d WHERE `id` = %d",
  84. intval($aes_allow),
  85. intval($hidden),
  86. intval($contact_record['id'])
  87. );
  88. }
  89. else {
  90. /**
  91. * Scrape the other site's profile page to pick up the dfrn links, key, fn, and photo
  92. */
  93. $parms = Probe::profile($dfrn_url);
  94. if(! count($parms)) {
  95. notice( t('Profile location is not valid or does not contain profile information.') . EOL );
  96. return;
  97. }
  98. else {
  99. if(! x($parms,'fn'))
  100. notice( t('Warning: profile location has no identifiable owner name.') . EOL );
  101. if(! x($parms,'photo'))
  102. notice( t('Warning: profile location has no profile photo.') . EOL );
  103. $invalid = Probe::valid_dfrn($parms);
  104. if($invalid) {
  105. notice( sprintf( tt("%d required parameter was not found at the given location",
  106. "%d required parameters were not found at the given location",
  107. $invalid), $invalid) . EOL );
  108. return;
  109. }
  110. }
  111. $dfrn_request = $parms['dfrn-request'];
  112. $photo = $parms["photo"];
  113. /********* Escape the entire array ********/
  114. dbesc_array($parms);
  115. /******************************************/
  116. /**
  117. * Create a contact record on our site for the other person
  118. */
  119. $r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `addr`, `name`, `nick`, `photo`, `site-pubkey`,
  120. `request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)
  121. VALUES ( %d, '%s', '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
  122. intval(local_user()),
  123. datetime_convert(),
  124. dbesc($dfrn_url),
  125. dbesc(normalise_link($dfrn_url)),
  126. $parms['addr'],
  127. $parms['fn'],
  128. $parms['nick'],
  129. $parms['photo'],
  130. $parms['key'],
  131. $parms['dfrn-request'],
  132. $parms['dfrn-confirm'],
  133. $parms['dfrn-notify'],
  134. $parms['dfrn-poll'],
  135. $parms['dfrn-poco'],
  136. dbesc(NETWORK_DFRN),
  137. intval($aes_allow),
  138. intval($hidden)
  139. );
  140. }
  141. if($r) {
  142. info( t("Introduction complete.") . EOL);
  143. }
  144. $r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1",
  145. intval(local_user()),
  146. dbesc($dfrn_url),
  147. $parms['key'] // this was already escaped
  148. );
  149. if(count($r)) {
  150. $def_gid = get_default_group(local_user(), $r[0]["network"]);
  151. if(intval($def_gid))
  152. group_add_member(local_user(), '', $r[0]['id'], $def_gid);
  153. if (isset($photo))
  154. update_contact_avatar($photo, local_user(), $r[0]["id"], true);
  155. $forwardurl = $a->get_baseurl()."/contacts/".$r[0]['id'];
  156. } else
  157. $forwardurl = $a->get_baseurl()."/contacts";
  158. /**
  159. * Allow the blocked remote notification to complete
  160. */
  161. if(is_array($contact_record))
  162. $dfrn_request = $contact_record['request'];
  163. if(strlen($dfrn_request) && strlen($confirm_key))
  164. $s = fetch_url($dfrn_request . '?confirm_key=' . $confirm_key);
  165. // (ignore reply, nothing we can do it failed)
  166. // Old: goaway(zrl($dfrn_url));
  167. goaway($forwardurl);
  168. return; // NOTREACHED
  169. }
  170. }
  171. // invalid/bogus request
  172. notice( t('Unrecoverable protocol error.') . EOL );
  173. goaway(z_root());
  174. return; // NOTREACHED
  175. }
  176. /**
  177. * Otherwise:
  178. *
  179. * Scenario 1:
  180. * We are the requestee. A person from a remote cell has made an introduction
  181. * on our profile web page and clicked submit. We will use their DFRN-URL to
  182. * figure out how to contact their cell.
  183. *
  184. * Scrape the originating DFRN-URL for everything we need. Create a contact record
  185. * and an introduction to show our user next time he/she logs in.
  186. * Finally redirect back to the requestor so that their site can record the request.
  187. * If our user (the requestee) later confirms this request, a record of it will need
  188. * to exist on the requestor's cell in order for the confirmation process to complete..
  189. *
  190. * It's possible that neither the requestor or the requestee are logged in at the moment,
  191. * and the requestor does not yet have any credentials to the requestee profile.
  192. *
  193. * Who is the requestee? We've already loaded their profile which means their nickname should be
  194. * in $a->argv[1] and we should have their complete info in $a->profile.
  195. *
  196. */
  197. if(! (is_array($a->profile) && count($a->profile))) {
  198. notice( t('Profile unavailable.') . EOL);
  199. return;
  200. }
  201. $nickname = $a->profile['nickname'];
  202. $notify_flags = $a->profile['notify-flags'];
  203. $uid = $a->profile['uid'];
  204. $maxreq = intval($a->profile['maxreq']);
  205. $contact_record = null;
  206. $failed = false;
  207. $parms = null;
  208. if( x($_POST,'dfrn_url')) {
  209. /**
  210. * Block friend request spam
  211. */
  212. if($maxreq) {
  213. $r = q("SELECT * FROM `intro` WHERE `datetime` > '%s' AND `uid` = %d",
  214. dbesc(datetime_convert('UTC','UTC','now - 24 hours')),
  215. intval($uid)
  216. );
  217. if(count($r) > $maxreq) {
  218. notice( sprintf( t('%s has received too many connection requests today.'), $a->profile['name']) . EOL);
  219. notice( t('Spam protection measures have been invoked.') . EOL);
  220. notice( t('Friends are advised to please try again in 24 hours.') . EOL);
  221. return;
  222. }
  223. }
  224. /**
  225. *
  226. * Cleanup old introductions that remain blocked.
  227. * Also remove the contact record, but only if there is no existing relationship
  228. * Do not remove email contacts as these may be awaiting email verification
  229. */
  230. $r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
  231. FROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`
  232. WHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0
  233. AND `contact`.`network` != '%s'
  234. AND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 30 MINUTE ",
  235. dbesc(NETWORK_MAIL2)
  236. );
  237. if(count($r)) {
  238. foreach($r as $rr) {
  239. if(! $rr['rel']) {
  240. q("DELETE FROM `contact` WHERE `id` = %d",
  241. intval($rr['cid'])
  242. );
  243. }
  244. q("DELETE FROM `intro` WHERE `id` = %d",
  245. intval($rr['iid'])
  246. );
  247. }
  248. }
  249. /**
  250. *
  251. * Cleanup any old email intros - which will have a greater lifetime
  252. */
  253. $r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
  254. FROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`
  255. WHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0
  256. AND `contact`.`network` = '%s'
  257. AND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 3 DAY ",
  258. dbesc(NETWORK_MAIL2)
  259. );
  260. if(count($r)) {
  261. foreach($r as $rr) {
  262. if(! $rr['rel']) {
  263. q("DELETE FROM `contact` WHERE `id` = %d",
  264. intval($rr['cid'])
  265. );
  266. }
  267. q("DELETE FROM `intro` WHERE `id` = %d",
  268. intval($rr['iid'])
  269. );
  270. }
  271. }
  272. $email_follow = (x($_POST,'email_follow') ? intval($_POST['email_follow']) : 0);
  273. $real_name = (x($_POST,'realname') ? notags(trim($_POST['realname'])) : '');
  274. $url = trim($_POST['dfrn_url']);
  275. if(! strlen($url)) {
  276. notice( t("Invalid locator") . EOL );
  277. return;
  278. }
  279. $hcard = '';
  280. if($email_follow) {
  281. if(! validate_email($url)) {
  282. notice( t('Invalid email address.') . EOL);
  283. return;
  284. }
  285. $addr = $url;
  286. $name = ($realname) ? $realname : $addr;
  287. $nick = substr($addr,0,strpos($addr,'@'));
  288. $url = 'http://' . substr($addr,strpos($addr,'@') + 1);
  289. $nurl = normalise_url($host);
  290. $poll = 'email ' . random_string();
  291. $notify = 'smtp ' . random_string();
  292. $blocked = 1;
  293. $pending = 1;
  294. $network = NETWORK_MAIL2;
  295. $rel = CONTACT_IS_FOLLOWER;
  296. $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
  297. if(get_config('system','dfrn_only'))
  298. $mail_disabled = 1;
  299. if(! $mail_disabled) {
  300. $failed = false;
  301. $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
  302. intval($uid)
  303. );
  304. if(! count($r)) {
  305. notice( t('This account has not been configured for email. Request failed.') . EOL);
  306. return;
  307. }
  308. }
  309. $r = q("insert into contact ( uid, created, addr, name, nick, url, nurl, poll, notify, blocked, pending, network, rel )
  310. values( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d ) ",
  311. intval($uid),
  312. dbesc(datetime_convert()),
  313. dbesc($addr),
  314. dbesc($name),
  315. dbesc($nick),
  316. dbesc($url),
  317. dbesc($nurl),
  318. dbesc($poll),
  319. dbesc($notify),
  320. intval($blocked),
  321. intval($pending),
  322. dbesc($network),
  323. intval($rel)
  324. );
  325. $r = q("SELECT `id`, `network` FROM `contact` WHERE `poll` = '%s' AND `uid` = %d LIMIT 1",
  326. dbesc($poll),
  327. intval($uid)
  328. );
  329. if(count($r)) {
  330. $contact_id = $r[0]['id'];
  331. $def_gid = get_default_group($uid, $r[0]["network"]);
  332. if (intval($def_gid))
  333. group_add_member($uid, '', $contact_id, $def_gid);
  334. $photo = avatar_img($addr);
  335. $r = q("UPDATE `contact` SET
  336. `photo` = '%s',
  337. `thumb` = '%s',
  338. `micro` = '%s',
  339. `name-date` = '%s',
  340. `uri-date` = '%s',
  341. `avatar-date` = '%s',
  342. `hidden` = 0,
  343. WHERE `id` = %d
  344. ",
  345. dbesc($photos[0]),
  346. dbesc($photos[1]),
  347. dbesc($photos[2]),
  348. dbesc(datetime_convert()),
  349. dbesc(datetime_convert()),
  350. dbesc(datetime_convert()),
  351. intval($contact_id)
  352. );
  353. }
  354. // contact is created. Now create an introduction
  355. $hash = random_string();
  356. $r = q("insert into intro ( uid, `contact-id`, knowyou, note, hash, datetime, blocked )
  357. values( %d , %d, %d, '%s', '%s', '%s', %d ) ",
  358. intval($uid),
  359. intval($contact_id),
  360. ((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
  361. dbesc(notags(trim($_POST['dfrn-request-message']))),
  362. dbesc($hash),
  363. dbesc(datetime_convert()),
  364. 1
  365. );
  366. // Next send an email verify form to the requestor.
  367. } else {
  368. // Detect the network
  369. $data = probe_url($url);
  370. $network = $data["network"];
  371. // Canonicalise email-style profile locator
  372. $url = Probe::webfinger_dfrn($url,$hcard);
  373. if (substr($url,0,5) === 'stat:') {
  374. // Every time we detect the remote subscription we define this as OStatus.
  375. // We do this even if it is not OStatus.
  376. // we only need to pass this through another section of the code.
  377. if ($network != NETWORK_DIASPORA)
  378. $network = NETWORK_OSTATUS;
  379. $url = substr($url,5);
  380. } else
  381. $network = NETWORK_DFRN;
  382. }
  383. logger('dfrn_request: url: ' . $url . ',network=' . $network, LOGGER_DEBUG);
  384. if($network === NETWORK_DFRN) {
  385. $ret = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1",
  386. intval($uid),
  387. dbesc($url)
  388. );
  389. if(count($ret)) {
  390. if(strlen($ret[0]['issued-id'])) {
  391. notice( t('You have already introduced yourself here.') . EOL );
  392. return;
  393. }
  394. elseif($ret[0]['rel'] == CONTACT_IS_FRIEND) {
  395. notice( sprintf( t('Apparently you are already friends with %s.'), $a->profile['name']) . EOL);
  396. return;
  397. }
  398. else {
  399. $contact_record = $ret[0];
  400. $parms = array('dfrn-request' => $ret[0]['request']);
  401. }
  402. }
  403. $issued_id = random_string();
  404. if(is_array($contact_record)) {
  405. // There is a contact record but no issued-id, so this
  406. // is a reciprocal introduction from a known contact
  407. $r = q("UPDATE `contact` SET `issued-id` = '%s' WHERE `id` = %d",
  408. dbesc($issued_id),
  409. intval($contact_record['id'])
  410. );
  411. }
  412. else {
  413. if(! validate_url($url)) {
  414. notice( t('Invalid profile URL.') . EOL);
  415. goaway($a->get_baseurl() . '/' . $a->cmd);
  416. return; // NOTREACHED
  417. }
  418. if(! allowed_url($url)) {
  419. notice( t('Disallowed profile URL.') . EOL);
  420. goaway($a->get_baseurl() . '/' . $a->cmd);
  421. return; // NOTREACHED
  422. }
  423. require_once('include/Scrape.php');
  424. $parms = Probe::profile(($hcard) ? $hcard : $url);
  425. if(! count($parms)) {
  426. notice( t('Profile location is not valid or does not contain profile information.') . EOL );
  427. goaway($a->get_baseurl() . '/' . $a->cmd);
  428. }
  429. else {
  430. if(! x($parms,'fn'))
  431. notice( t('Warning: profile location has no identifiable owner name.') . EOL );
  432. if(! x($parms,'photo'))
  433. notice( t('Warning: profile location has no profile photo.') . EOL );
  434. $invalid = Probe::valid_dfrn($parms);
  435. if($invalid) {
  436. notice( sprintf( tt("%d required parameter was not found at the given location",
  437. "%d required parameters were not found at the given location",
  438. $invalid), $invalid) . EOL );
  439. return;
  440. }
  441. }
  442. $parms['url'] = $url;
  443. $parms['issued-id'] = $issued_id;
  444. $photo = $parms["photo"];
  445. dbesc_array($parms);
  446. $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `name`, `nick`, `issued-id`, `photo`, `site-pubkey`,
  447. `request`, `confirm`, `notify`, `poll`, `poco`, `network` )
  448. VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
  449. intval($uid),
  450. dbesc(datetime_convert()),
  451. $parms['url'],
  452. dbesc(normalise_link($url)),
  453. $parms['addr'],
  454. $parms['fn'],
  455. $parms['nick'],
  456. $parms['issued-id'],
  457. $parms['photo'],
  458. $parms['key'],
  459. $parms['dfrn-request'],
  460. $parms['dfrn-confirm'],
  461. $parms['dfrn-notify'],
  462. $parms['dfrn-poll'],
  463. $parms['dfrn-poco'],
  464. dbesc(NETWORK_DFRN)
  465. );
  466. // find the contact record we just created
  467. if($r) {
  468. $r = q("SELECT `id` FROM `contact`
  469. WHERE `uid` = %d AND `url` = '%s' AND `issued-id` = '%s' LIMIT 1",
  470. intval($uid),
  471. $parms['url'],
  472. $parms['issued-id']
  473. );
  474. if(count($r)) {
  475. $contact_record = $r[0];
  476. update_contact_avatar($photo, $uid, $contact_record["id"], true);
  477. }
  478. }
  479. }
  480. if($r === false) {
  481. notice( t('Failed to update contact record.') . EOL );
  482. return;
  483. }
  484. $hash = random_string() . (string) time(); // Generate a confirm_key
  485. if(is_array($contact_record)) {
  486. $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
  487. VALUES ( %d, %d, 1, %d, '%s', '%s', '%s' )",
  488. intval($uid),
  489. intval($contact_record['id']),
  490. ((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
  491. dbesc(notags(trim($_POST['dfrn-request-message']))),
  492. dbesc($hash),
  493. dbesc(datetime_convert())
  494. );
  495. }
  496. // This notice will only be seen by the requestor if the requestor and requestee are on the same server.
  497. if(! $failed)
  498. info( t('Your introduction has been sent.') . EOL );
  499. // "Homecoming" - send the requestor back to their site to record the introduction.
  500. $dfrn_url = bin2hex($a->get_baseurl() . '/profile/' . $nickname);
  501. $aes_allow = ((function_exists('openssl_encrypt')) ? 1 : 0);
  502. goaway($parms['dfrn-request'] . "?dfrn_url=$dfrn_url"
  503. . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
  504. . '&confirm_key=' . $hash
  505. . (($aes_allow) ? "&aes_allow=1" : "")
  506. );
  507. // NOTREACHED
  508. // END $network === NETWORK_DFRN
  509. } elseif (($network != NETWORK_PHANTOM) AND ($url != "")) {
  510. /**
  511. *
  512. * Substitute our user's feed URL into $url template
  513. * Send the subscriber home to subscribe
  514. *
  515. */
  516. // Diaspora needs the uri in the format user@domain.tld
  517. // Diaspora will support the remote subscription in a future version
  518. if ($network == NETWORK_DIASPORA) {
  519. $uri = $nickname.'@'.$a->get_hostname();
  520. if ($a->get_path())
  521. $uri .= '/'.$a->get_path();
  522. $uri = urlencode($uri);
  523. } else
  524. $uri = $a->get_baseurl().'/profile/'.$nickname;
  525. $url = str_replace('{uri}', $uri, $url);
  526. goaway($url);
  527. // NOTREACHED
  528. // END $network != NETWORK_PHANTOM
  529. } else {
  530. notice(t("Remote subscription can't be done for your network. Please subscribe directly on your system.").EOL);
  531. return;
  532. }
  533. } return;
  534. }}
  535. if(! function_exists('dfrn_request_content')) {
  536. function dfrn_request_content(&$a) {
  537. if(($a->argc != 2) || (! count($a->profile)))
  538. return "";
  539. // "Homecoming". Make sure we're logged in to this site as the correct user. Then offer a confirm button
  540. // to send us to the post section to record the introduction.
  541. if(x($_GET,'dfrn_url')) {
  542. if(! local_user()) {
  543. info( t("Please login to confirm introduction.") . EOL );
  544. /* setup the return URL to come back to this page if they use openid */
  545. $_SESSION['return_url'] = $a->query_string;
  546. return login();
  547. }
  548. // Edge case, but can easily happen in the wild. This person is authenticated,
  549. // but not as the person who needs to deal with this request.
  550. if ($a->user['nickname'] != $a->argv[1]) {
  551. notice( t("Incorrect identity currently logged in. Please login to <strong>this</strong> profile.") . EOL);
  552. return login();
  553. }
  554. $dfrn_url = notags(trim(hex2bin($_GET['dfrn_url'])));
  555. $aes_allow = (((x($_GET,'aes_allow')) && ($_GET['aes_allow'] == 1)) ? 1 : 0);
  556. $confirm_key = (x($_GET,'confirm_key') ? $_GET['confirm_key'] : "");
  557. // Checking fastlane for validity
  558. if (x($_SESSION, "fastlane") AND (normalise_link($_SESSION["fastlane"]) == normalise_link($dfrn_url))) {
  559. $_POST["dfrn_url"] = $dfrn_url;
  560. $_POST["confirm_key"] = $confirm_key;
  561. $_POST["localconfirm"] = 1;
  562. $_POST["hidden-contact"] = 0;
  563. $_POST["submit"] = t('Confirm');
  564. dfrn_request_post($a);
  565. killme();
  566. return; // NOTREACHED
  567. }
  568. $tpl = get_markup_template("dfrn_req_confirm.tpl");
  569. $o = replace_macros($tpl,array(
  570. '$dfrn_url' => $dfrn_url,
  571. '$aes_allow' => (($aes_allow) ? '<input type="hidden" name="aes_allow" value="1" />' : "" ),
  572. '$hidethem' => t('Hide this contact'),
  573. '$hidechecked' => '',
  574. '$confirm_key' => $confirm_key,
  575. '$welcome' => sprintf( t('Welcome home %s.'), $a->user['username']),
  576. '$please' => sprintf( t('Please confirm your introduction/connection request to %s.'), $dfrn_url),
  577. '$submit' => t('Confirm'),
  578. '$uid' => $_SESSION['uid'],
  579. '$nickname' => $a->user['nickname'],
  580. 'dfrn_rawurl' => $_GET['dfrn_url']
  581. ));
  582. return $o;
  583. }
  584. elseif((x($_GET,'confirm_key')) && strlen($_GET['confirm_key'])) {
  585. // we are the requestee and it is now safe to send our user their introduction,
  586. // We could just unblock it, but first we have to jump through a few hoops to
  587. // send an email, or even to find out if we need to send an email.
  588. $intro = q("SELECT * FROM `intro` WHERE `hash` = '%s' LIMIT 1",
  589. dbesc($_GET['confirm_key'])
  590. );
  591. if(count($intro)) {
  592. $r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
  593. WHERE `contact`.`id` = %d LIMIT 1",
  594. intval($intro[0]['contact-id'])
  595. );
  596. $auto_confirm = false;
  597. if(count($r)) {
  598. if(($r[0]['page-flags'] != PAGE_NORMAL) && ($r[0]['page-flags'] != PAGE_PRVGROUP))
  599. $auto_confirm = true;
  600. if(! $auto_confirm) {
  601. notification(array(
  602. 'type' => NOTIFY_INTRO,
  603. 'notify_flags' => $r[0]['notify-flags'],
  604. 'language' => $r[0]['language'],
  605. 'to_name' => $r[0]['username'],
  606. 'to_email' => $r[0]['email'],
  607. 'uid' => $r[0]['uid'],
  608. 'link' => $a->get_baseurl() . '/notifications/intros',
  609. 'source_name' => ((strlen(stripslashes($r[0]['name']))) ? stripslashes($r[0]['name']) : t('[Name Withheld]')),
  610. 'source_link' => $r[0]['url'],
  611. 'source_photo' => $r[0]['photo'],
  612. 'verb' => ACTIVITY_REQ_FRIEND,
  613. 'otype' => 'intro'
  614. ));
  615. }
  616. if($auto_confirm) {
  617. require_once('mod/dfrn_confirm.php');
  618. $handsfree = array(
  619. 'uid' => $r[0]['uid'],
  620. 'node' => $r[0]['nickname'],
  621. 'dfrn_id' => $r[0]['issued-id'],
  622. 'intro_id' => $intro[0]['id'],
  623. 'duplex' => (($r[0]['page-flags'] == PAGE_FREELOVE) ? 1 : 0),
  624. 'activity' => intval(get_pconfig($r[0]['uid'],'system','post_newfriend'))
  625. );
  626. dfrn_confirm_post($a,$handsfree);
  627. }
  628. }
  629. if(! $auto_confirm) {
  630. // If we are auto_confirming, this record will have already been nuked
  631. // in dfrn_confirm_post()
  632. $r = q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s'",
  633. dbesc($_GET['confirm_key'])
  634. );
  635. }
  636. }
  637. killme();
  638. return; // NOTREACHED
  639. }
  640. else {
  641. /**
  642. * Normal web request. Display our user's introduction form.
  643. */
  644. if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
  645. if(! get_config('system','local_block')) {
  646. notice( t('Public access denied.') . EOL);
  647. return;
  648. }
  649. }
  650. /**
  651. * Try to auto-fill the profile address
  652. */
  653. // At first look if an address was provided
  654. // Otherwise take the local address
  655. if (x($_GET,'addr') AND ($_GET['addr'] != ""))
  656. $myaddr = hex2bin($_GET['addr']);
  657. elseif (x($_GET,'address') AND ($_GET['address'] != ""))
  658. $myaddr = $_GET['address'];
  659. elseif(local_user()) {
  660. if(strlen($a->path)) {
  661. $myaddr = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
  662. }
  663. else {
  664. $myaddr = $a->user['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );
  665. }
  666. } else // last, try a zrl
  667. $myaddr = get_my_url();
  668. $target_addr = $a->profile['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );
  669. /**
  670. *
  671. * The auto_request form only has the profile address
  672. * because nobody is going to read the comments and
  673. * it doesn't matter if they know you or not.
  674. *
  675. */
  676. if($a->profile['page-flags'] == PAGE_NORMAL)
  677. $tpl = get_markup_template('dfrn_request.tpl');
  678. else
  679. $tpl = get_markup_template('auto_request.tpl');
  680. $page_desc = t("Please enter your 'Identity Address' from one of the following supported communications networks:");
  681. // see if we are allowed to have NETWORK_MAIL2 contacts
  682. $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
  683. if(get_config('system','dfrn_only'))
  684. $mail_disabled = 1;
  685. if(! $mail_disabled) {
  686. $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
  687. intval($a->profile['uid'])
  688. );
  689. if(! count($r))
  690. $mail_disabled = 1;
  691. }
  692. // "coming soon" is disabled for now
  693. //$emailnet = (($mail_disabled) ? '' : t("<strike>Connect as an email follower</strike> \x28Coming soon\x29"));
  694. $emailnet = "";
  695. $invite_desc = sprintf(
  696. 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>.'),
  697. get_server()
  698. );
  699. $o = replace_macros($tpl,array(
  700. '$header' => t('Friend/Connection Request'),
  701. '$desc' => t('Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca'),
  702. '$pls_answer' => t('Please answer the following:'),
  703. '$does_know_you' => array('knowyou', sprintf(t('Does %s know you?'),$a->profile['name']), false, '', array(t('No'),t('Yes'))),
  704. /*'$does_know' => sprintf( t('Does %s know you?'),$a->profile['name']),
  705. '$yes' => t('Yes'),
  706. '$no' => t('No'), */
  707. '$add_note' => t('Add a personal note:'),
  708. '$page_desc' => $page_desc,
  709. '$friendica' => t('Friendica'),
  710. '$statusnet' => t('StatusNet/Federated Social Web'),
  711. '$diaspora' => t('Diaspora'),
  712. '$diasnote' => sprintf (t(' - please do not use this form. Instead, enter %s into your Diaspora search bar.'),$target_addr),
  713. '$your_address' => t('Your Identity Address:'),
  714. '$invite_desc' => $invite_desc,
  715. '$emailnet' => $emailnet,
  716. '$submit' => t('Submit Request'),
  717. '$cancel' => t('Cancel'),
  718. '$nickname' => $a->argv[1],
  719. '$name' => $a->profile['name'],
  720. '$myaddr' => $myaddr
  721. ));
  722. return $o;
  723. }
  724. return; // Somebody is fishing.
  725. }}