diff --git a/boot.php b/boot.php index 1f465d110..032c05a50 100644 --- a/boot.php +++ b/boot.php @@ -11,7 +11,7 @@ require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_VERSION', '2.3.1187' ); define ( 'DFRN_PROTOCOL_VERSION', '2.22' ); -define ( 'DB_UPDATE_VERSION', 1110 ); +define ( 'DB_UPDATE_VERSION', 1111 ); define ( 'EOL', "
\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); diff --git a/database.sql b/database.sql index cdbc8a93b..1d57b9c6c 100644 --- a/database.sql +++ b/database.sql @@ -279,11 +279,19 @@ CREATE TABLE IF NOT EXISTS `mail` ( `title` char(255) NOT NULL, `body` mediumtext NOT NULL, `seen` tinyint(1) NOT NULL, + `reply` tinyint(1) NOT NULL DEFAULT '0', `replied` tinyint(1) NOT NULL, `uri` char(255) NOT NULL, `parent-uri` char(255) NOT NULL, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + KEY `uid` (`uid`), + KEY `guid` (`guid`), + KEY `convid` (`convid`), + KEY `reply` (`reply`), + KEY `uri` (`uri`), + KEY `parent-uri` (`parent-uri`), + KEY `created` (`created`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- diff --git a/include/diaspora.php b/include/diaspora.php index 4f0df1944..7f1e4a8e3 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -77,6 +77,9 @@ function diaspora_dispatch($importer,$msg) { elseif($xmlbase->conversation) { $ret = diaspora_conversation($importer,$xmlbase->conversation,$msg); } + elseif($xmlbase->message) { + $ret = diaspora_message($importer,$xmlbase->message,$msg); + } else { logger('diaspora_dispatch: unknown message type: ' . print_r($xmlbase,true)); } @@ -1127,7 +1130,6 @@ function diaspora_conversation($importer,$xml,$msg) { return; } - foreach($messages as $mesg) { $reply = 0; @@ -1145,16 +1147,10 @@ function diaspora_conversation($importer,$xml,$msg) { continue; } - // Is this right? - - if($msg_parent_guid != $guid) - $reply = 1; - $body = diaspora2bb($msg_text); $message_id = $msg_diaspora_handle . ':' . $msg_guid; $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($mesg->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid; -// $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . $msg_diaspora_handle; $author_signature = base64_decode($msg_author_signature); @@ -1199,7 +1195,7 @@ function diaspora_conversation($importer,$xml,$msg) { continue; } - q("insert into mail ( `uid`, `guid`, `convid`, `from-name`,`from-photo`,`from-url`,`contact-id`,`title`,`body`,`seen`,`replied`,`uri`,`parent-uri`,`created`) values ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, '%s','%s','%s')", + q("insert into mail ( `uid`, `guid`, `convid`, `from-name`,`from-photo`,`from-url`,`contact-id`,`title`,`body`,`seen`,`reply`,`uri`,`parent-uri`,`created`) values ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, '%s','%s','%s')", intval($importer['uid']), dbesc($msg_guid), intval($conversation['id']), @@ -1210,13 +1206,13 @@ function diaspora_conversation($importer,$xml,$msg) { dbesc($subject), dbesc($body), 0, - intval($reply), + 0, dbesc($message_id), dbesc($parent_uri), dbesc($msg_created_at) ); - q("updated conv set updated = '%s' where id = %d limit 1", + q("update conv set updated = '%s' where id = %d limit 1", dbesc(datetime_convert()), intval($conversation['id']) ); @@ -1225,9 +1221,101 @@ function diaspora_conversation($importer,$xml,$msg) { return; } +function diaspora_message($importer,$xml,$msg) { + + $a = get_app(); + + $msg_guid = notags(unxmlify($xml->guid)); + $msg_parent_guid = notags(unxmlify($xml->parent_guid)); + $msg_parent_author_signature = notags(unxmlify($xml->parent_author_signature)); + $msg_author_signature = notags(unxmlify($xml->author_signature)); + $msg_text = unxmlify($xml->text); + $msg_created_at = datetime_convert('UTC','UTC',notags(unxmlify($xml->created_at))); + $msg_diaspora_handle = notags(unxmlify($xml->diaspora_handle)); + $msg_conversation_guid = notags(unxmlify($xml->conversation_guid)); + + $parent_uri = $diaspora_handle . ':' . $msg_parent_guid; + + $contact = diaspora_get_contact_by_handle($importer['uid'],$msg_diaspora_handle); + if(! $contact) { + logger('diaspora_message: cannot find contact: ' . $msg_diaspora_handle); + return; + } + + if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) { + logger('diaspora_message: Ignoring this author.'); + return 202; + } + + $conversation = null; + + $c = q("select * from conv where uid = %d and guid = '%s' limit 1", + intval($importer['uid']), + dbesc($msg_conversation_guid) + ); + if(count($c)) + $conversation = $c[0]; + else { + logger('diaspora_message: conversation not available.'); + return; + } + + $reply = 0; + + $body = diaspora2bb($msg_text); + $message_id = $msg_diaspora_handle . ':' . $msg_guid; + + $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($xml->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid; + $author_signature = base64_decode($msg_author_signature); + $person = find_diaspora_person_by_handle($msg_diaspora_handle); + if(is_array($person) && x($person,'pubkey')) + $key = $person['pubkey']; + else { + logger('diaspora_message: unable to find author details'); + return; + } + + if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) { + logger('diaspora_message: verification failed.'); + return; + } + + $r = q("select id from mail where `uri` = '%s' and uid = %d limit 1", + dbesc($message_id), + intval($importer['uid']) + ); + if(count($r)) { + logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG); + return; + } + + q("insert into mail ( `uid`, `guid`, `convid`, `from-name`,`from-photo`,`from-url`,`contact-id`,`title`,`body`,`seen`,`reply`,`uri`,`parent-uri`,`created`) values ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, '%s','%s','%s')", + intval($importer['uid']), + dbesc($msg_guid), + intval($conversation['id']), + dbesc($person['name']), + dbesc($person['photo']), + dbesc($person['url']), + intval($contact['id']), + dbesc($conversation['subject']), + dbesc($body), + 0, + 1, + dbesc($message_id), + dbesc($parent_uri), + dbesc($msg_created_at) + ); + + q("update conv set updated = '%s' where id = %d limit 1", + dbesc(datetime_convert()), + intval($conversation['id']) + ); + + return; +} function diaspora_photo($importer,$xml,$msg) { @@ -1976,16 +2064,6 @@ function diaspora_send_mail($item,$owner,$contact) { } $cnv = $r[0]; - $parent = null; - - if($item['parent-uri'] != $item['uri']) { - $r = q("select * from mail where uri = '%s' and uid = %d limit 1", - dbesc($item['parent-uri']), - intval($item['uid']) - ); - $parent = $r[0]; - } - $conv = array( 'guid' => xmlify($cnv['guid']), 'subject' => xmlify($cnv['subject']), @@ -1996,17 +2074,16 @@ function diaspora_send_mail($item,$owner,$contact) { $body = bb2diaspora($item['body']); $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C'); - $parent_guid = (($item['parent-uri'] == $item['uri']) ? $cnv['guid'] : $parent['guid']); - $signed_text = $item['guid'] . ';' . $parent_guid . ';' . $body . ';' + $signed_text = $item['guid'] . ';' . $cnv['guid'] . ';' . $body . ';' . $created . ';' . $myaddr . ';' . $cnv['guid']; $sig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256')); $msg = array( 'guid' => xmlify($item['guid']), - 'parent_guid' => (($item['parent-uri'] == $item['uri']) ? xmlify($cnv['guid']) : xmlify($parent['guid'])), - 'parent_author_signature' => (($item['parent-uri'] == $item['uri']) ? xmlify($sig) : null), + 'parent_guid' => xmlify($cnv['guid']), + 'parent_author_signature' => (($item['reply']) ? null : xmlify($sig)), 'author_signature' => xmlify($sig), 'text' => xmlify($body), 'created_at' => xmlify($created), @@ -2014,14 +2091,19 @@ function diaspora_send_mail($item,$owner,$contact) { 'conversation_guid' => xmlify($cnv['guid']) ); - $conv['messages'] = array($msg); + if($item['reply']) { + $tpl = get_markup_template('diaspora_message.tpl'); + $xmsg = replace_macros($tpl, array('$msg' => $msg)); + } + else { + $conv['messages'] = array($msg); + $tpl = get_markup_template('diaspora_conversation.tpl'); + $xmsg = replace_macros($tpl, array('$conv' => $conv)); + } - $tpl = get_markup_template('diaspora_conversation.tpl'); - $msg = replace_macros($tpl, array('$conv' => $conv)); + logger('diaspora_conversation: ' . print_r($xmsg,true), LOGGER_DATA); - logger('diaspora_conversation: ' . print_r($msg,true)); - - $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],false))); + $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($xmsg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],false))); return(diaspora_transmit($owner,$contact,$slap,false)); diff --git a/include/message.php b/include/message.php index 58789d688..7ad80ae9c 100644 --- a/include/message.php +++ b/include/message.php @@ -5,6 +5,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){ + $a = get_app(); if(! $recipient) return -1; @@ -28,22 +29,21 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){ $uri = 'urn:X-dfrn:' . $a->get_baseurl() . ':' . local_user() . ':' . $hash ; $convid = 0; + $reply = false; // look for any existing conversation structure if(strlen($replyto)) { - $r = q("select convid from mail where uid = %d and uri = '%s' limit 1", + $reply = true; + $r = q("select convid from mail where uid = %d and ( uri = '%s' or `parent-uri` = '%s' ) limit 1", intval(local_user()), + dbesc($replyto), dbesc($replyto) ); if(count($r)) $convid = $r[0]['convid']; } - if(! strlen($replyto)) - $replyto = $uri; - - if(! $convid) { // create a new conversation @@ -81,9 +81,14 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){ return -4; } + if(! strlen($replyto)) { + $replyto = $uri; + } + + $r = q("INSERT INTO `mail` ( `uid`, `guid`, `convid`, `from-name`, `from-photo`, `from-url`, - `contact-id`, `title`, `body`, `seen`, `replied`, `uri`, `parent-uri`, `created`) - VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, '%s', '%s', '%s' )", + `contact-id`, `title`, `body`, `seen`, `reply`, `replied`, `uri`, `parent-uri`, `created`) + VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, %d, '%s', '%s', '%s' )", intval(local_user()), dbesc(get_guid()), intval($convid), @@ -94,11 +99,14 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){ dbesc($subject), dbesc($body), 1, + intval($reply), 0, dbesc($uri), dbesc($replyto), datetime_convert() ); + + $r = q("SELECT * FROM `mail` WHERE `uri` = '%s' and `uid` = %d LIMIT 1", dbesc($uri), intval(local_user()) diff --git a/mod/message.php b/mod/message.php index 172a1ca98..7a3b870b3 100644 --- a/mod/message.php +++ b/mod/message.php @@ -217,11 +217,19 @@ function message_content(&$a) { ); if(count($r)) { $contact_id = $r[0]['contact-id']; + $convid = $r[0]['convid']; + + $sql_extra = sprintf(" and `mail`.`parent-uri` = '%s' ", dbesc($r[0]['parent-uri'])); + if($convid) + $sql_extra = sprintf(" and ( `mail`.`parent-uri` = '%s' OR `mail`.`convid` = '%d' ) ", + dbesc($r[0]['parent-uri']), + intval($convid) + ); + $messages = q("SELECT `mail`.*, `contact`.`name`, `contact`.`url`, `contact`.`thumb` FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id` - WHERE `mail`.`uid` = %d AND `mail`.`parent-uri` = '%s' ORDER BY `mail`.`created` ASC", - intval(local_user()), - dbesc($r[0]['parent-uri']) + WHERE `mail`.`uid` = %d $sql_extra ORDER BY `mail`.`created` ASC", + intval(local_user()) ); } if(! count($messages)) { diff --git a/update.php b/update.php index ca8874e82..61a9a80ed 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@
- $from_name + $from_name
$from_name
diff --git a/view/mail_list.tpl b/view/mail_list.tpl index 8c95e1250..b284ffb0e 100644 --- a/view/mail_list.tpl +++ b/view/mail_list.tpl @@ -1,6 +1,6 @@
- $from_name + $from_name
$from_name