]> git.mxchange.org Git - friendica.git/commitdiff
Legacy DFRN transport layer is removed
authorMichael <heluecht@pirati.ca>
Thu, 15 Jul 2021 13:28:32 +0000 (13:28 +0000)
committerMichael <heluecht@pirati.ca>
Thu, 15 Jul 2021 13:28:32 +0000 (13:28 +0000)
27 files changed:
database.sql
doc/API-Friendica.md
doc/database.md
doc/database/db_challenge.md [deleted file]
doc/database/db_contact.md
include/api.php
mod/dfrn_confirm.php [deleted file]
mod/dfrn_notify.php
mod/dfrn_poll.php
mod/dfrn_request.php [deleted file]
mod/follow.php
mod/redir.php
mod/unfollow.php
src/Database/DBStructure.php
src/Model/Contact.php
src/Model/Conversation.php
src/Module/Notifications/Introductions.php
src/Object/Notification/Introduction.php
src/Protocol/DFRN.php
src/Worker/Delivery.php
src/Worker/OptimizeTables.php
static/dbstructure.config.php
static/dbview.config.php
view/lang/C/messages.po
view/templates/dfrn_req_confirm.tpl [deleted file]
view/templates/dfrn_request.tpl [deleted file]
view/theme/frio/templates/dfrn_request.tpl [deleted file]

index 2e7a189b39290ff8be6e8011acaadab30a7c244a..95e96a135a6733013f45145a8f976005aaee960a 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2021.09-dev (Siberian Iris)
--- DB_UPDATE_VERSION 1429
+-- DB_UPDATE_VERSION 1430
 -- ------------------------------------------
 
 
@@ -117,7 +117,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
        `self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self',
        `remote_self` boolean NOT NULL DEFAULT '0' COMMENT '',
        `rel` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'The kind of the relation between the user and the contact',
-       `duplex` boolean NOT NULL DEFAULT '0' COMMENT '',
+       `duplex` boolean NOT NULL DEFAULT '0' COMMENT 'Deprecated',
        `network` char(4) NOT NULL DEFAULT '' COMMENT 'Network of the contact',
        `protocol` char(4) NOT NULL DEFAULT '' COMMENT 'Protocol of the contact',
        `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name that this contact is known by',
@@ -133,9 +133,9 @@ CREATE TABLE IF NOT EXISTS `contact` (
        `thumb` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (thumb size)',
        `micro` varchar(255) DEFAULT '' COMMENT 'Link to the profile photo (micro size)',
        `header` varchar(255) COMMENT 'Header picture',
-       `site-pubkey` text COMMENT '',
-       `issued-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+       `site-pubkey` text COMMENT 'Deprecated',
+       `issued-id` varchar(255) NOT NULL DEFAULT '' COMMENT 'Deprecated',
+       `dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT 'Deprecated',
        `url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the contact url',
@@ -150,8 +150,8 @@ CREATE TABLE IF NOT EXISTS `contact` (
        `confirm` varchar(255) COMMENT '',
        `subscribe` varchar(255) COMMENT '',
        `poco` varchar(255) COMMENT '',
-       `aes_allow` boolean NOT NULL DEFAULT '0' COMMENT '',
-       `ret-aes` boolean NOT NULL DEFAULT '0' COMMENT '',
+       `aes_allow` boolean NOT NULL DEFAULT '0' COMMENT 'Deprecated',
+       `ret-aes` boolean NOT NULL DEFAULT '0' COMMENT 'Deprecated',
        `usehub` boolean NOT NULL DEFAULT '0' COMMENT '',
        `subhub` boolean NOT NULL DEFAULT '0' COMMENT '',
        `hub-verify` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@@ -205,8 +205,6 @@ CREATE TABLE IF NOT EXISTS `contact` (
         INDEX `nurl_uid` (`nurl`(128),`uid`),
         INDEX `nick_uid` (`nick`(128),`uid`),
         INDEX `attag_uid` (`attag`(96),`uid`),
-        INDEX `dfrn-id` (`dfrn-id`(64)),
-        INDEX `issued-id` (`issued-id`(64)),
         INDEX `network_uid_lastupdate` (`network`,`uid`,`last-update`),
         INDEX `uid_network_self_lastupdate` (`uid`,`network`,`self`,`last-update`),
         INDEX `uid_lastitem` (`uid`,`last-item`),
@@ -462,20 +460,6 @@ CREATE TABLE IF NOT EXISTS `cache` (
         INDEX `k_expires` (`k`,`expires`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Stores temporary data';
 
---
--- TABLE challenge
---
-CREATE TABLE IF NOT EXISTS `challenge` (
-       `id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
-       `challenge` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `expire` int unsigned NOT NULL DEFAULT 0 COMMENT '',
-       `type` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `last_update` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-        PRIMARY KEY(`id`),
-        INDEX `expire` (`expire`)
-) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
-
 --
 -- TABLE config
 --
@@ -1684,7 +1668,6 @@ CREATE VIEW `post-user-view` AS SELECT
        `contact`.`uri-date` AS `uri-date`,
        `contact`.`avatar-date` AS `avatar-date`,
        `contact`.`thumb` AS `thumb`,
-       `contact`.`dfrn-id` AS `dfrn-id`,
        `post-user`.`author-id` AS `author-id`,
        `author`.`url` AS `author-link`,
        `author`.`addr` AS `author-addr`,
@@ -1846,7 +1829,6 @@ CREATE VIEW `post-thread-user-view` AS SELECT
        `contact`.`uri-date` AS `uri-date`,
        `contact`.`avatar-date` AS `avatar-date`,
        `contact`.`thumb` AS `thumb`,
-       `contact`.`dfrn-id` AS `dfrn-id`,
        `post-thread-user`.`author-id` AS `author-id`,
        `author`.`url` AS `author-link`,
        `author`.`addr` AS `author-addr`,
@@ -1993,7 +1975,6 @@ CREATE VIEW `post-view` AS SELECT
        `author`.`uri-date` AS `uri-date`,
        `author`.`avatar-date` AS `avatar-date`,
        `author`.`thumb` AS `thumb`,
-       `author`.`dfrn-id` AS `dfrn-id`,
        `post`.`author-id` AS `author-id`,
        `author`.`url` AS `author-link`,
        `author`.`addr` AS `author-addr`,
@@ -2115,7 +2096,6 @@ CREATE VIEW `post-thread-view` AS SELECT
        `author`.`uri-date` AS `uri-date`,
        `author`.`avatar-date` AS `avatar-date`,
        `author`.`thumb` AS `thumb`,
-       `author`.`dfrn-id` AS `dfrn-id`,
        `post-thread`.`author-id` AS `author-id`,
        `author`.`url` AS `author-link`,
        `author`.`addr` AS `author-addr`,
@@ -2270,7 +2250,6 @@ CREATE VIEW `owner-view` AS SELECT
        `contact`.`self` AS `self`,
        `contact`.`remote_self` AS `remote_self`,
        `contact`.`rel` AS `rel`,
-       `contact`.`duplex` AS `duplex`,
        `contact`.`network` AS `network`,
        `contact`.`protocol` AS `protocol`,
        `contact`.`name` AS `name`,
@@ -2286,9 +2265,6 @@ CREATE VIEW `owner-view` AS SELECT
        `contact`.`thumb` AS `thumb`,
        `contact`.`micro` AS `micro`,
        `contact`.`header` AS `header`,
-       `contact`.`site-pubkey` AS `site-pubkey`,
-       `contact`.`issued-id` AS `issued-id`,
-       `contact`.`dfrn-id` AS `dfrn-id`,
        `contact`.`url` AS `url`,
        `contact`.`nurl` AS `nurl`,
        `contact`.`uri-id` AS `uri-id`,
@@ -2302,8 +2278,6 @@ CREATE VIEW `owner-view` AS SELECT
        `contact`.`poll` AS `poll`,
        `contact`.`confirm` AS `confirm`,
        `contact`.`poco` AS `poco`,
-       `contact`.`aes_allow` AS `aes_allow`,
-       `contact`.`ret-aes` AS `ret-aes`,
        `contact`.`usehub` AS `usehub`,
        `contact`.`subhub` AS `subhub`,
        `contact`.`hub-verify` AS `hub-verify`,
@@ -2547,12 +2521,6 @@ CREATE VIEW `account-user-view` AS SELECT
        `ucontact`.`subhub` AS `subhub`,
        `ucontact`.`hub-verify` AS `hub-verify`,
        `ucontact`.`reason` AS `reason`,
-       `ucontact`.`duplex` AS `dfrn-duplex`,
-       `ucontact`.`ret-aes` AS `dfrn-ret-aes`,
-       `ucontact`.`site-pubkey` AS `dfrn-site-pubkey`,
-       `ucontact`.`issued-id` AS `dfrn-issued-id`,
-       `ucontact`.`dfrn-id` AS `dfrn-id`,
-       `ucontact`.`aes_allow` AS `dfrn-aes_allow`,
        `contact`.`request` AS `dfrn-request`,
        `contact`.`notify` AS `dfrn-notify`,
        `contact`.`poll` AS `dfrn-poll`,
index 62a71dc6b1570009780e90464ff280122554e7e0..af47638d2ed4af02a102ed6e48dc8f9cff84d333 100644 (file)
@@ -689,15 +689,6 @@ General description of profile data in API returns:
 
 ---
 
-### GET api/friendica/remoteauth
-
-Similar as /redir, redirects to `url` after DFRN authentication.
-
-#### Parameters
-
-- `c_url`: url of remote contact to auth to
-- `url`: string, url to redirect after auth
-
 ## Deprecated endpoints
 
 - POST api/statuses/mediap
index 51f4ae5c6e83aaa26e7a5fc136ee0a4a55095d04..b2f4e4322511b872738c36b9dbac570a72f236b7 100644 (file)
@@ -15,7 +15,6 @@ Database Tables
 | [attach](help/database/db_attach) | file attachments |
 | [auth_codes](help/database/db_auth_codes) | OAuth usage |
 | [cache](help/database/db_cache) | Stores temporary data |
-| [challenge](help/database/db_challenge) |  |
 | [clients](help/database/db_clients) | OAuth usage |
 | [config](help/database/db_config) | main configuration storage |
 | [contact](help/database/db_contact) | contact table |
diff --git a/doc/database/db_challenge.md b/doc/database/db_challenge.md
deleted file mode 100644 (file)
index 1618389..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-Table challenge
-===========
-
-
-
-Fields
-------
-
-| Field       | Description   | Type         | Null | Key | Default | Extra          |
-| ----------- | ------------- | ------------ | ---- | --- | ------- | -------------- |
-| id          | sequential ID | int unsigned | NO   | PRI | NULL    | auto_increment |
-| challenge   |               | varchar(255) | NO   |     |         |                |
-| dfrn-id     |               | varchar(255) | NO   |     |         |                |
-| expire      |               | int unsigned | NO   |     | 0       |                |
-| type        |               | varchar(255) | NO   |     |         |                |
-| last_update |               | varchar(255) | NO   |     |         |                |
-
-Indexes
-------------
-
-| Name    | Fields |
-| ------- | ------ |
-| PRIMARY | id     |
-| expire  | expire |
-
-
-Return to [database documentation](help/database)
index 5a97c6e4dd70b1876501735545ea64e7744611e3..2d8d292ac4cb3eb5dbf92aefb714f3a0ef37bb23 100644 (file)
@@ -15,7 +15,7 @@ Fields
 | self                      | 1 if the contact is the user him/her self                    | boolean            | NO   |     | 0                   |                |
 | remote_self               |                                                              | boolean            | NO   |     | 0                   |                |
 | rel                       | The kind of the relation between the user and the contact    | tinyint unsigned   | NO   |     | 0                   |                |
-| duplex                    |                                                              | boolean            | NO   |     | 0                   |                |
+| duplex                    | Deprecated                                                   | boolean            | NO   |     | 0                   |                |
 | network                   | Network of the contact                                       | char(4)            | NO   |     |                     |                |
 | protocol                  | Protocol of the contact                                      | char(4)            | NO   |     |                     |                |
 | name                      | Name that this contact is known by                           | varchar(255)       | NO   |     |                     |                |
@@ -31,9 +31,9 @@ Fields
 | thumb                     | Link to the profile photo (thumb size)                       | varchar(255)       | YES  |     |                     |                |
 | micro                     | Link to the profile photo (micro size)                       | varchar(255)       | YES  |     |                     |                |
 | header                    | Header picture                                               | varchar(255)       | YES  |     | NULL                |                |
-| site-pubkey               |                                                              | text               | YES  |     | NULL                |                |
-| issued-id                 |                                                              | varchar(255)       | NO   |     |                     |                |
-| dfrn-id                   |                                                              | varchar(255)       | NO   |     |                     |                |
+| site-pubkey               | Deprecated                                                   | text               | YES  |     | NULL                |                |
+| issued-id                 | Deprecated                                                   | varchar(255)       | NO   |     |                     |                |
+| dfrn-id                   | Deprecated                                                   | varchar(255)       | NO   |     |                     |                |
 | url                       |                                                              | varchar(255)       | NO   |     |                     |                |
 | nurl                      |                                                              | varchar(255)       | NO   |     |                     |                |
 | uri-id                    | Id of the item-uri table entry that contains the contact url | int unsigned       | YES  |     | NULL                |                |
@@ -48,8 +48,8 @@ Fields
 | confirm                   |                                                              | varchar(255)       | YES  |     | NULL                |                |
 | subscribe                 |                                                              | varchar(255)       | YES  |     | NULL                |                |
 | poco                      |                                                              | varchar(255)       | YES  |     | NULL                |                |
-| aes_allow                 |                                                              | boolean            | NO   |     | 0                   |                |
-| ret-aes                   |                                                              | boolean            | NO   |     | 0                   |                |
+| aes_allow                 | Deprecated                                                   | boolean            | NO   |     | 0                   |                |
+| ret-aes                   | Deprecated                                                   | boolean            | NO   |     | 0                   |                |
 | usehub                    |                                                              | boolean            | NO   |     | 0                   |                |
 | subhub                    |                                                              | boolean            | NO   |     | 0                   |                |
 | hub-verify                |                                                              | varchar(255)       | NO   |     |                     |                |
@@ -109,8 +109,6 @@ Indexes
 | nurl_uid                    | nurl(128), uid                       |
 | nick_uid                    | nick(128), uid                       |
 | attag_uid                   | attag(96), uid                       |
-| dfrn-id                     | dfrn-id(64)                          |
-| issued-id                   | issued-id(64)                        |
 | network_uid_lastupdate      | network, uid, last-update            |
 | uid_network_self_lastupdate | uid, network, self, last-update      |
 | uid_lastitem                | uid, last-item                       |
index 951c2b3e582e72f03539b5d1554822415213b48f..1d1cdc8f64074d3c15ef11cbce38b03d026d8376 100644 (file)
@@ -4950,70 +4950,6 @@ function prepare_photo_data($type, $scale, $photo_id)
        return $data;
 }
 
-
-/**
- * Similar as /mod/redir.php
- * redirect to 'url' after dfrn auth
- *
- * Why this when there is mod/redir.php already?
- * This use api_user() and api_login()
- *
- * params
- *             c_url: url of remote contact to auth to
- *             url: string, url to redirect after auth
- */
-function api_friendica_remoteauth()
-{
-       $url = $_GET['url'] ?? '';
-       $c_url = $_GET['c_url'] ?? '';
-
-       if ($url === '' || $c_url === '') {
-               throw new BadRequestException("Wrong parameters.");
-       }
-
-       $c_url = Strings::normaliseLink($c_url);
-
-       // traditional DFRN
-
-       $contact = DBA::selectFirst('contact', [], ['uid' => api_user(), 'nurl' => $c_url]);
-       if (!DBA::isResult($contact)) {
-               throw new BadRequestException("Unknown contact");
-       }
-
-       $cid = $contact['id'];
-
-       $dfrn_id = $contact['issued-id'] ?: $contact['dfrn-id'];
-
-       if (($contact['network'] !== Protocol::DFRN) || empty($dfrn_id)) {
-               System::externalRedirect($url ?: $c_url);
-       }
-
-       if ($contact['duplex'] && $contact['issued-id']) {
-               $orig_id = $contact['issued-id'];
-               $dfrn_id = '1:' . $orig_id;
-       }
-       if ($contact['duplex'] && $contact['dfrn-id']) {
-               $orig_id = $contact['dfrn-id'];
-               $dfrn_id = '0:' . $orig_id;
-       }
-
-       $sec = Strings::getRandomHex();
-
-       $fields = ['uid' => api_user(), 'cid' => $cid, 'dfrn_id' => $dfrn_id,
-               'sec' => $sec, 'expire' => time() + 45];
-       DBA::insert('profile_check', $fields);
-
-       Logger::info(API_LOG_PREFIX . 'for contact {contact}', ['module' => 'api', 'action' => 'friendica_remoteauth', 'contact' => $contact['name'], 'hey' => $sec]);
-       $dest = ($url ? '&destination_url=' . $url : '');
-
-       System::externalRedirect(
-               $contact['poll'] . '?dfrn_id=' . $dfrn_id
-               . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
-               . '&type=profile&sec=' . $sec . $dest
-       );
-}
-api_register_func('api/friendica/remoteauth', 'api_friendica_remoteauth', true);
-
 /**
  * Return an item with announcer data if it had been announced
  *
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
deleted file mode 100644 (file)
index 47cc093..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- * Friendship acceptance for DFRN contacts
- *
- * There are two possible entry points and three scenarios.
- *
- *   1. A form was submitted by our user approving a friendship that originated elsewhere.
- *      This may also be called from dfrn_request to automatically approve a friendship.
- *
- *   2. We may be the target or other side of the conversation to scenario 1, and will
- *      interact with that process on our own user's behalf.
- *
- *  @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
- *    You also find a graphic which describes the confirmation process at
- *    https://github.com/friendica/friendica/blob/stable/spec/dfrn2_contact_confirmation.png
- */
-
-use Friendica\App;
-use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\Group;
-use Friendica\Model\Notification;
-use Friendica\Model\User;
-use Friendica\Protocol\Activity;
-use Friendica\Util\Crypto;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
-use Friendica\Util\XML;
-
-function dfrn_confirm_post(App $a, $handsfree = null)
-{
-       $node = null;
-       if (is_array($handsfree)) {
-               /*
-                * We were called directly from dfrn_request due to automatic friend acceptance.
-                * Any $_POST parameters we may require are supplied in the $handsfree array.
-                *
-                */
-               $node = $handsfree['node'];
-               $a->interactive = false; // notice() becomes a no-op since nobody is there to see it
-       } elseif ($a->argc > 1) {
-               $node = $a->argv[1];
-       }
-
-       /*
-        * Main entry point. Scenario 1. Our user received a friend request notification (perhaps
-        * from another site) and clicked 'Approve'.
-        * $POST['source_url'] is not set. If it is, it indicates Scenario 2.
-        *
-        * We may also have been called directly from dfrn_request ($handsfree != null) due to
-        * this being a page type which supports automatic friend acceptance. That is also Scenario 1
-        * since we are operating on behalf of our registered user to approve a friendship.
-        */
-       if (empty($_POST['source_url'])) {
-               $uid = ($handsfree['uid'] ?? 0) ?: local_user();
-               if (!$uid) {
-                       notice(DI::l10n()->t('Permission denied.'));
-                       return;
-               }
-
-               $user = DBA::selectFirst('user', [], ['uid' => $uid]);
-               if (!DBA::isResult($user)) {
-                       notice(DI::l10n()->t('Profile not found.'));
-                       return;
-               }
-
-               // These data elements may come from either the friend request notification form or $handsfree array.
-               if (is_array($handsfree)) {
-                       Logger::log('Confirm in handsfree mode');
-                       $dfrn_id  = $handsfree['dfrn_id'];
-                       $intro_id = $handsfree['intro_id'];
-                       $duplex   = $handsfree['duplex'];
-                       $cid      = 0;
-                       $hidden   = intval($handsfree['hidden'] ?? 0);
-               } else {
-                       $dfrn_id  = Strings::escapeTags(trim($_POST['dfrn_id'] ?? ''));
-                       $intro_id = intval($_POST['intro_id']   ?? 0);
-                       $duplex   = intval($_POST['duplex']     ?? 0);
-                       $cid      = intval($_POST['contact_id'] ?? 0);
-                       $hidden   = intval($_POST['hidden']     ?? 0);
-               }
-
-               /*
-                * Ensure that dfrn_id has precedence when we go to find the contact record.
-                * We only want to search based on contact id if there is no dfrn_id,
-                * e.g. for OStatus network followers.
-                */
-               if (strlen($dfrn_id)) {
-                       $cid = 0;
-               }
-
-               Logger::log('Confirming request for dfrn_id (issued) ' . $dfrn_id);
-               if ($cid) {
-                       Logger::log('Confirming follower with contact_id: ' . $cid);
-               }
-
-               /*
-                * The other person will have been issued an ID when they first requested friendship.
-                * Locate their record. At this time, their record will have both pending and blocked set to 1.
-                * There won't be any dfrn_id if this is a network follower, so use the contact_id instead.
-                */
-               $r = q("SELECT *
-                       FROM `contact`
-                       WHERE (
-                               (`issued-id` != '' AND `issued-id` = '%s')
-                               OR
-                               (`id` = %d AND `id` != 0)
-                       )
-                       AND `uid` = %d
-                       AND `duplex` = 0
-                       LIMIT 1",
-                       DBA::escape($dfrn_id),
-                       intval($cid),
-                       intval($uid)
-               );
-               if (!DBA::isResult($r)) {
-                       Logger::log('Contact not found in DB.');
-                       notice(DI::l10n()->t('Contact not found.'));
-                       notice(DI::l10n()->t('This may occasionally happen if contact was requested by both persons and it has already been approved.'));
-                       return;
-               }
-
-               $contact = $r[0];
-
-               $contact_id   = $contact['id'];
-               $relation     = $contact['rel'];
-               $site_pubkey  = $contact['site-pubkey'];
-               $dfrn_confirm = $contact['confirm'];
-               $aes_allow    = $contact['aes_allow'];
-               $protocol     = $contact['network'];
-
-               /*
-                * Generate a key pair for all further communications with this person.
-                * We have a keypair for every contact, and a site key for unknown people.
-                * This provides a means to carry on relationships with other people if
-                * any single key is compromised. It is a robust key. We're much more
-                * worried about key leakage than anybody cracking it.
-                */
-               $res = Crypto::newKeypair(4096);
-
-               $private_key = $res['prvkey'];
-               $public_key  = $res['pubkey'];
-
-               // Save the private key. Send them the public key.
-               $fields = ['prvkey' => $private_key, 'protocol' => Protocol::DFRN];
-               DBA::update('contact', $fields, ['id' => $contact_id]);
-
-               $params = [];
-
-               /*
-                * Per the DFRN protocol, we will verify both ends by encrypting the dfrn_id with our
-                * site private key (person on the other end can decrypt it with our site public key).
-                * Then encrypt our profile URL with the other person's site public key. They can decrypt
-                * it with their site private key. If the decryption on the other end fails for either
-                * item, it indicates tampering or key failure on at least one site and we will not be
-                * able to provide a secure communication pathway.
-                *
-                * If other site is willing to accept full encryption, (aes_allow is 1 AND we have php5.3
-                * or later) then we encrypt the personal public key we send them using AES-256-CBC and a
-                * random key which is encrypted with their site public key.
-                */
-
-               $src_aes_key = random_bytes(64);
-
-               $result = '';
-               openssl_private_encrypt($dfrn_id, $result, $user['prvkey']);
-
-               $params['dfrn_id'] = bin2hex($result);
-               $params['public_key'] = $public_key;
-
-               $my_url = DI::baseUrl() . '/profile/' . $user['nickname'];
-
-               openssl_public_encrypt($my_url, $params['source_url'], $site_pubkey);
-               $params['source_url'] = bin2hex($params['source_url']);
-
-               if ($aes_allow && function_exists('openssl_encrypt')) {
-                       openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
-                       $params['aes_key'] = bin2hex($params['aes_key']);
-                       $params['public_key'] = bin2hex(openssl_encrypt($public_key, 'AES-256-CBC', $src_aes_key));
-               }
-
-               $params['dfrn_version'] = DFRN_PROTOCOL_VERSION;
-               if ($duplex == 1) {
-                       $params['duplex'] = 1;
-               }
-
-               if ($user['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
-                       $params['page'] = 1;
-               }
-
-               if ($user['page-flags'] == User::PAGE_FLAGS_PRVGROUP) {
-                       $params['page'] = 2;
-               }
-
-               Logger::debug('Confirm: posting data', ['confirm'  => $dfrn_confirm, 'parameter' => $params]);
-
-               /*
-                *
-                * POST all this stuff to the other site.
-                * Temporarily raise the network timeout to 120 seconds because the default 60
-                * doesn't always give the other side quite enough time to decrypt everything.
-                *
-                */
-
-               $res = DI::httpRequest()->post($dfrn_confirm, $params, [], 120)->getBody();
-
-               Logger::log(' Confirm: received data: ' . $res, Logger::DATA);
-
-               // Now figure out what they responded. Try to be robust if the remote site is
-               // having difficulty and throwing up errors of some kind.
-
-               $leading_junk = substr($res, 0, strpos($res, '<?xml'));
-
-               $res = substr($res, strpos($res, '<?xml'));
-               if (!strlen($res)) {
-                       // No XML at all, this exchange is messed up really bad.
-                       // We shouldn't proceed, because the xml parser might choke,
-                       // and $status is going to be zero, which indicates success.
-                       // We can hardly call this a success.
-                       notice(DI::l10n()->t('Response from remote site was not understood.'));
-                       return;
-               }
-
-               if (strlen($leading_junk) && DI::config()->get('system', 'debugging')) {
-                       // This might be more common. Mixed error text and some XML.
-                       // If we're configured for debugging, show the text. Proceed in either case.
-                       notice(DI::l10n()->t('Unexpected response from remote site: ') . $leading_junk);
-               }
-
-               if (stristr($res, "<status") === false) {
-                       // wrong xml! stop here!
-                       Logger::log('Unexpected response posting to ' . $dfrn_confirm);
-                       notice(DI::l10n()->t('Unexpected response from remote site: ') . EOL . htmlspecialchars($res));
-                       return;
-               }
-
-               $xml = XML::parseString($res);
-               $status = (int) $xml->status;
-               $message = XML::unescape($xml->message);   // human readable text of what may have gone wrong.
-               switch ($status) {
-                       case 0:
-                               info(DI::l10n()->t("Confirmation completed successfully."));
-                               break;
-                       case 1:
-                               // birthday paradox - generate new dfrn-id and fall through.
-                               $new_dfrn_id = Strings::getRandomHex();
-                               q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d AND `uid` = %d",
-                                       DBA::escape($new_dfrn_id),
-                                       intval($contact_id),
-                                       intval($uid)
-                               );
-
-                       case 2:
-                               notice(DI::l10n()->t("Temporary failure. Please wait and try again."));
-                               break;
-                       case 3:
-                               notice(DI::l10n()->t("Introduction failed or was revoked."));
-                               break;
-               }
-
-               if (strlen($message)) {
-                       notice(DI::l10n()->t('Remote site reported: ') . $message);
-               }
-
-               if (($status == 0) && $intro_id) {
-                       $intro = DBA::selectFirst('intro', ['note'], ['id' => $intro_id]);
-                       if (DBA::isResult($intro)) {
-                               DBA::update('contact', ['reason' => $intro['note']], ['id' => $contact_id]);
-                       }
-
-                       // Success. Delete the notification.
-                       DBA::delete('intro', ['id' => $intro_id]);
-               }
-
-               if ($status != 0) {
-                       return;
-               }
-
-               /*
-                * We have now established a relationship with the other site.
-                * Let's make our own personal copy of their profile photo so we don't have
-                * to always load it from their site.
-                *
-                * We will also update the contact record with the nature and scope of the relationship.
-                */
-               Contact::updateAvatar($contact_id, $contact['photo']);
-
-               Logger::log('dfrn_confirm: confirm - imported photos');
-
-               $new_relation = Contact::FOLLOWER;
-
-               if (($relation == Contact::SHARING) || ($duplex)) {
-                       $new_relation = Contact::FRIEND;
-               }
-
-               if (($relation == Contact::SHARING) && ($duplex)) {
-                       $duplex = 0;
-               }
-
-               $r = q("UPDATE `contact` SET `rel` = %d,
-                       `name-date` = '%s',
-                       `uri-date` = '%s',
-                       `blocked` = 0,
-                       `pending` = 0,
-                       `duplex` = %d,
-                       `hidden` = %d,
-                       `network` = '%s' WHERE `id` = %d
-               ",
-                       intval($new_relation),
-                       DBA::escape(DateTimeFormat::utcNow()),
-                       DBA::escape(DateTimeFormat::utcNow()),
-                       intval($duplex),
-                       intval($hidden),
-                       DBA::escape(Protocol::DFRN),
-                       intval($contact_id)
-               );
-
-               // reload contact info
-               $contact = DBA::selectFirst('contact', [], ['id' => $contact_id]);
-
-               Group::addMember(User::getDefaultGroup($uid, $contact["network"]), $contact['id']);
-
-               // Let's send our user to the contact editor in case they want to
-               // do anything special with this new friend.
-               if ($handsfree === null) {
-                       DI::baseUrl()->redirect('contact/' . intval($contact_id));
-               } else {
-                       return;
-               }
-               //NOTREACHED
-       }
-
-       /*
-        * End of Scenario 1. [Local confirmation of remote friend request].
-        *
-        * Begin Scenario 2. This is the remote response to the above scenario.
-        * This will take place on the site that originally initiated the friend request.
-        * In the section above where the confirming party makes a POST and
-        * retrieves xml status information, they are communicating with the following code.
-        */
-       if (!empty($_POST['source_url'])) {
-               // We are processing an external confirmation to an introduction created by our user.
-               $public_key =         $_POST['public_key'] ?? '';
-               $dfrn_id    = hex2bin($_POST['dfrn_id']    ?? '');
-               $source_url = hex2bin($_POST['source_url'] ?? '');
-               $aes_key    =         $_POST['aes_key']    ?? '';
-               $duplex     =  intval($_POST['duplex']     ?? 0);
-               $page       =  intval($_POST['page']       ?? 0);
-
-               $forum = (($page == 1) ? 1 : 0);
-               $prv   = (($page == 2) ? 1 : 0);
-
-               Logger::notice('requestee contacted', ['node' => $node]);
-
-               Logger::debug('request', ['POST' => $_POST]);
-
-               // If $aes_key is set, both of these items require unpacking from the hex transport encoding.
-
-               if (!empty($aes_key)) {
-                       $aes_key = hex2bin($aes_key);
-                       $public_key = hex2bin($public_key);
-               }
-
-               // Find our user's account
-               $user = DBA::selectFirst('user', [], ['nickname' => $node]);
-               if (!DBA::isResult($user)) {
-                       $message = DI::l10n()->t('No user record found for \'%s\' ', $node);
-                       System::xmlExit(3, $message); // failure
-                       // NOTREACHED
-               }
-
-               $my_prvkey = $user['prvkey'];
-               $local_uid = $user['uid'];
-
-
-               if (!strstr($my_prvkey, 'PRIVATE KEY')) {
-                       $message = DI::l10n()->t('Our site encryption key is apparently messed up.');
-                       System::xmlExit(3, $message);
-               }
-
-               // verify everything
-
-               $decrypted_source_url = "";
-               openssl_private_decrypt($source_url, $decrypted_source_url, $my_prvkey);
-
-
-               if (!strlen($decrypted_source_url)) {
-                       $message = DI::l10n()->t('Empty site URL was provided or URL could not be decrypted by us.');
-                       System::xmlExit(3, $message);
-                       // NOTREACHED
-               }
-
-               $contact = DBA::selectFirst('contact', [], ['url' => $decrypted_source_url, 'uid' => $local_uid]);
-               if (!DBA::isResult($contact)) {
-                       if (strstr($decrypted_source_url, 'http:')) {
-                               $newurl = str_replace('http:', 'https:', $decrypted_source_url);
-                       } else {
-                               $newurl = str_replace('https:', 'http:', $decrypted_source_url);
-                       }
-
-                       $contact = DBA::selectFirst('contact', [], ['url' => $newurl, 'uid' => $local_uid]);
-                       if (!DBA::isResult($contact)) {
-                               // this is either a bogus confirmation (?) or we deleted the original introduction.
-                               $message = DI::l10n()->t('Contact record was not found for you on our site.');
-                               System::xmlExit(3, $message);
-                               return; // NOTREACHED
-                       }
-               }
-
-               $relation = $contact['rel'];
-
-               // Decrypt all this stuff we just received
-
-               $foreign_pubkey = $contact['site-pubkey'];
-               $dfrn_record = $contact['id'];
-
-               if (!$foreign_pubkey) {
-                       $message = DI::l10n()->t('Site public key not available in contact record for URL %s.', $decrypted_source_url);
-                       System::xmlExit(3, $message);
-               }
-
-               $decrypted_dfrn_id = "";
-               openssl_public_decrypt($dfrn_id, $decrypted_dfrn_id, $foreign_pubkey);
-
-               if (strlen($aes_key)) {
-                       $decrypted_aes_key = "";
-                       openssl_private_decrypt($aes_key, $decrypted_aes_key, $my_prvkey);
-                       $dfrn_pubkey = openssl_decrypt($public_key, 'AES-256-CBC', $decrypted_aes_key);
-               } else {
-                       $dfrn_pubkey = $public_key;
-               }
-
-               if (DBA::exists('contact', ['dfrn-id' => $decrypted_dfrn_id])) {
-                       $message = DI::l10n()->t('The ID provided by your system is a duplicate on our system. It should work if you try again.');
-                       System::xmlExit(1, $message); // Birthday paradox - duplicate dfrn-id
-                       // NOTREACHED
-               }
-
-               $r = q("UPDATE `contact` SET `dfrn-id` = '%s', `pubkey` = '%s' WHERE `id` = %d",
-                       DBA::escape($decrypted_dfrn_id),
-                       DBA::escape($dfrn_pubkey),
-                       intval($dfrn_record)
-               );
-               if (!DBA::isResult($r)) {
-                       $message = DI::l10n()->t('Unable to set your contact credentials on our system.');
-                       System::xmlExit(3, $message);
-               }
-
-               // It's possible that the other person also requested friendship.
-               // If it is a duplex relationship, ditch the issued-id if one exists.
-
-               if ($duplex) {
-                       q("UPDATE `contact` SET `issued-id` = '' WHERE `id` = %d",
-                               intval($dfrn_record)
-                       );
-               }
-
-               // We're good but now we have to scrape the profile photo and send notifications.
-               $contact = DBA::selectFirst('contact', ['photo'], ['id' => $dfrn_record]);
-               if (DBA::isResult($contact)) {
-                       $photo = $contact['photo'];
-               } else {
-                       $photo = DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO;
-               }
-
-               Contact::updateAvatar($dfrn_record, $photo);
-
-               Logger::log('dfrn_confirm: request - photos imported');
-
-               $new_relation = Contact::SHARING;
-
-               if (($relation == Contact::FOLLOWER) || ($duplex)) {
-                       $new_relation = Contact::FRIEND;
-               }
-
-               if (($relation == Contact::FOLLOWER) && ($duplex)) {
-                       $duplex = 0;
-               }
-
-               $r = q("UPDATE `contact` SET
-                       `rel` = %d,
-                       `name-date` = '%s',
-                       `uri-date` = '%s',
-                       `blocked` = 0,
-                       `pending` = 0,
-                       `duplex` = %d,
-                       `forum` = %d,
-                       `prv` = %d,
-                       `network` = '%s' WHERE `id` = %d
-               ",
-                       intval($new_relation),
-                       DBA::escape(DateTimeFormat::utcNow()),
-                       DBA::escape(DateTimeFormat::utcNow()),
-                       intval($duplex),
-                       intval($forum),
-                       intval($prv),
-                       DBA::escape(Protocol::DFRN),
-                       intval($dfrn_record)
-               );
-               if (!DBA::isResult($r)) {       // indicates schema is messed up or total db failure
-                       $message = DI::l10n()->t('Unable to update your contact profile details on our system');
-                       System::xmlExit(3, $message);
-               }
-
-               // Otherwise everything seems to have worked and we are almost done. Yay!
-               // Send an email notification
-
-               Logger::log('dfrn_confirm: request: info updated');
-
-               $combined = null;
-               $r = q("SELECT `contact`.*, `user`.*
-                       FROM `contact`
-                       LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `contact`.`id` = %d
-                       LIMIT 1",
-                       intval($dfrn_record)
-               );
-               if (DBA::isResult($r)) {
-                       $combined = $r[0];
-
-                       if ($combined['notify-flags'] & Notification\Type::CONFIRM) {
-                               $mutual = ($new_relation == Contact::FRIEND);
-                               notification([
-                                       'type'  => Notification\Type::CONFIRM,
-                                       'otype' => Notification\ObjectType::INTRO,
-                                       'verb'  => ($mutual ? Activity::FRIEND : Activity::FOLLOW),
-                                       'uid'   => $combined['uid'],
-                                       'cid'   => $combined['id'],
-                                       'link'  => DI::baseUrl() . '/contact/' . $dfrn_record,
-                               ]);
-                       }
-               }
-
-               System::xmlExit(0); // Success
-               return; // NOTREACHED
-               ////////////////////// End of this scenario ///////////////////////////////////////////////
-       }
-
-       // somebody arrived here by mistake or they are fishing. Send them to the homepage.
-       DI::baseUrl()->redirect();
-       // NOTREACHED
-}
index f43357fd4ca1bd11ac819a4ce21fabd0d47ca086..f5a1d97bf4586f700391ac2a7c5456efe17ed62f 100644 (file)
@@ -26,14 +26,12 @@ use Friendica\App;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
-use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
-use Friendica\Model\User;
+use Friendica\Network\HTTPException;
 use Friendica\Protocol\DFRN;
 use Friendica\Protocol\Diaspora;
 use Friendica\Util\Network;
-use Friendica\Util\Strings;
 
 function dfrn_notify_post(App $a) {
        $postdata = Network::postdata();
@@ -53,148 +51,7 @@ function dfrn_notify_post(App $a) {
                        salmon_post($a, $postdata);
                }
        }
-
-       $dfrn_id      = (!empty($_POST['dfrn_id'])      ? Strings::escapeTags(trim($_POST['dfrn_id']))   : '');
-       $dfrn_version = (!empty($_POST['dfrn_version']) ? (float) $_POST['dfrn_version']    : 2.0);
-       $challenge    = (!empty($_POST['challenge'])    ? Strings::escapeTags(trim($_POST['challenge'])) : '');
-       $data         = $_POST['data'] ?? '';
-       $key          = $_POST['key'] ?? '';
-       $rino_remote  = (!empty($_POST['rino'])         ? intval($_POST['rino'])            :  0);
-       $dissolve     = (!empty($_POST['dissolve'])     ? intval($_POST['dissolve'])        :  0);
-       $perm         = (!empty($_POST['perm'])         ? Strings::escapeTags(trim($_POST['perm']))      : 'r');
-       $ssl_policy   = (!empty($_POST['ssl_policy'])   ? Strings::escapeTags(trim($_POST['ssl_policy'])): 'none');
-       $page         = (!empty($_POST['page'])         ? intval($_POST['page'])            :  0);
-
-       $forum = (($page == 1) ? 1 : 0);
-       $prv   = (($page == 2) ? 1 : 0);
-
-       $writable = (-1);
-       if ($dfrn_version >= 2.21) {
-               $writable = (($perm === 'rw') ? 1 : 0);
-       }
-
-       $direction = (-1);
-       if (strpos($dfrn_id, ':') == 1) {
-               $direction = intval(substr($dfrn_id, 0, 1));
-               $dfrn_id = substr($dfrn_id, 2);
-       }
-
-       if (!DBA::exists('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge])) {
-               Logger::log('could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
-               System::xmlExit(3, 'Could not match challenge');
-       }
-
-       DBA::delete('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge]);
-
-       $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
-       if (!DBA::isResult($user)) {
-               Logger::log('User not found for nickname ' . $a->argv[1]);
-               System::xmlExit(3, 'User not found');
-       }
-
-       // find the local user who owns this relationship.
-       $condition = [];
-       switch ($direction) {
-               case (-1):
-                       $condition = ["(`issued-id` = ? OR `dfrn-id` = ?) AND `uid` = ?", $dfrn_id, $dfrn_id, $user['uid']];
-                       break;
-               case 0:
-                       $condition = ['issued-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']];
-                       break;
-               case 1:
-                       $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']];
-                       break;
-               default:
-                       System::xmlExit(3, 'Invalid direction');
-                       break; // NOTREACHED
-       }
-
-       $contact = DBA::selectFirst('contact', ['id'], $condition);
-       if (!DBA::isResult($contact)) {
-               Logger::log('contact not found for dfrn_id ' . $dfrn_id);
-               System::xmlExit(3, 'Contact not found');
-       }
-
-       // $importer in this case contains the contact record for the remote contact joined with the user record of our user.
-       $importer = DFRN::getImporter($contact['id'], $user['uid']);
-
-       if ((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
-               $fields = ['writable' => ($writable == (-1)) ? $importer['writable'] : $writable,
-                       'forum' => $forum, 'prv' => $prv];
-               DBA::update('contact', $fields, ['id' => $importer['id']]);
-
-               if ($writable != (-1)) {
-                       $importer['writable'] = $writable;
-               }
-               $importer['forum'] = $page;
-       }
-
-
-       // if contact's ssl policy changed, update our links
-
-       $importer = Contact::updateSslPolicy($importer, $ssl_policy);
-
-       Logger::log('data: ' . $data, Logger::DATA);
-
-       if ($dissolve == 1) {
-               // Relationship is dissolved permanently
-               Contact::remove($importer['id']);
-               Logger::log('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
-               System::xmlExit(0, 'relationship dissolved');
-       }
-
-       $rino = DI::config()->get('system', 'rino_encrypt');
-       $rino = intval($rino);
-
-       if (strlen($key)) {
-
-               // if local rino is lower than remote rino, abort: should not happen!
-               // but only for $remote_rino > 1, because old code did't send rino version
-               if ($rino_remote > 1 && $rino < $rino_remote) {
-                       Logger::log("rino version '$rino_remote' is lower than supported '$rino'");
-                       System::xmlExit(0, "rino version '$rino_remote' is lower than supported '$rino'");
-               }
-
-               $rawkey = hex2bin(trim($key));
-               Logger::log('rino: md5 raw key: ' . md5($rawkey), Logger::DATA);
-
-               $final_key = '';
-
-               if ($dfrn_version >= 2.1) {
-                       if (($importer['duplex'] && strlen($importer['cprvkey'])) || !strlen($importer['cpubkey'])) {
-                               openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
-                       } else {
-                               openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
-                       }
-               } else {
-                       if (($importer['duplex'] && strlen($importer['cpubkey'])) || !strlen($importer['cprvkey'])) {
-                               openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
-                       } else {
-                               openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
-                       }
-               }
-
-               switch ($rino_remote) {
-                       case 0:
-                       case 1:
-                               // we got a key. old code send only the key, without RINO version.
-                               // we assume RINO 1 if key and no RINO version
-                               $data = DFRN::aesDecrypt(hex2bin($data), $final_key);
-                               break;
-                       default:
-                               Logger::log("rino: invalid sent version '$rino_remote'");
-                               System::xmlExit(0, "Invalid sent version '$rino_remote'");
-               }
-
-               Logger::log('rino: decrypted data: ' . $data, Logger::DATA);
-       }
-
-       Logger::log('Importing post from ' . $importer['addr'] . ' to ' . $importer['nickname'] . ' with the RINO ' . $rino_remote . ' encryption.', Logger::DEBUG);
-
-       $ret = DFRN::import($data, $importer, Conversation::PARCEL_LEGACY_DFRN, Conversation::PUSH);
-       System::xmlExit($ret, 'Processed');
-
-       // NOTREACHED
+       throw new HTTPException\BadRequestException();
 }
 
 function dfrn_dispatch_public($postdata)
@@ -261,132 +118,5 @@ function dfrn_dispatch_private($user, $postdata)
 }
 
 function dfrn_notify_content(App $a) {
-
-       if (!empty($_GET['dfrn_id'])) {
-
-               /*
-                * initial communication from external contact, $direction is their direction.
-                * If this is a duplex communication, ours will be the opposite.
-                */
-
-               $dfrn_id = Strings::escapeTags(trim($_GET['dfrn_id']));
-               $rino_remote = (!empty($_GET['rino']) ? intval($_GET['rino']) : 0);
-               $type = "";
-               $last_update = "";
-
-               Logger::log('new notification dfrn_id=' . $dfrn_id);
-
-               $direction = (-1);
-               if (strpos($dfrn_id,':') == 1) {
-                       $direction = intval(substr($dfrn_id,0,1));
-                       $dfrn_id = substr($dfrn_id,2);
-               }
-
-               $hash = Strings::getRandomHex();
-
-               $status = 0;
-
-               DBA::delete('challenge', ["`expire` < ?", time()]);
-
-               $fields = ['challenge' => $hash, 'dfrn-id' => $dfrn_id, 'expire' => time() + 90,
-                       'type' => $type, 'last_update' => $last_update];
-               DBA::insert('challenge', $fields);
-
-               Logger::log('challenge=' . $hash, Logger::DATA);
-
-               $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
-               if (!DBA::isResult($user)) {
-                       Logger::log('User not found for nickname ' . $a->argv[1]);
-                       exit();
-               }
-
-               $condition = [];
-               switch ($direction) {
-                       case (-1):
-                               $condition = ["(`issued-id` = ? OR `dfrn-id` = ?) AND `uid` = ?", $dfrn_id, $dfrn_id, $user['uid']];
-                               $my_id = $dfrn_id;
-                               break;
-                       case 0:
-                               $condition = ['issued-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']];
-                               $my_id = '1:' . $dfrn_id;
-                               break;
-                       case 1:
-                               $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']];
-                               $my_id = '0:' . $dfrn_id;
-                               break;
-                       default:
-                               $status = 1;
-                               $my_id = '';
-                               break;
-               }
-
-               $contact = DBA::selectFirst('contact', ['id'], $condition);
-               if (!DBA::isResult($contact)) {
-                       Logger::log('contact not found for dfrn_id ' . $dfrn_id);
-                       System::xmlExit(3, 'Contact not found');
-               }
-
-               // $importer in this case contains the contact record for the remote contact joined with the user record of our user.
-               $importer = DFRN::getImporter($contact['id'], $user['uid']);
-               if (empty($importer)) {
-                       Logger::log('No importer data found for user ' . $a->argv[1] . ' and contact ' . $dfrn_id);
-                       exit();
-               }
-
-               Logger::log("Remote rino version: ".$rino_remote." for ".$importer["url"], Logger::DATA);
-
-               $challenge    = '';
-               $encrypted_id = '';
-               $id_str       = $my_id . '.' . mt_rand(1000,9999);
-
-               $prv_key = trim($importer['cprvkey']);
-               $pub_key = trim($importer['cpubkey']);
-               $dplx    = intval($importer['duplex']);
-
-               if (($dplx && strlen($prv_key)) || (strlen($prv_key) && !strlen($pub_key))) {
-                       openssl_private_encrypt($hash, $challenge, $prv_key);
-                       openssl_private_encrypt($id_str, $encrypted_id, $prv_key);
-               } elseif (strlen($pub_key)) {
-                       openssl_public_encrypt($hash, $challenge, $pub_key);
-                       openssl_public_encrypt($id_str, $encrypted_id, $pub_key);
-               } else {
-                       /// @TODO these kind of else-blocks are making the code harder to understand
-                       $status = 1;
-               }
-
-               $challenge    = bin2hex($challenge);
-               $encrypted_id = bin2hex($encrypted_id);
-
-
-               $rino = DI::config()->get('system', 'rino_encrypt');
-               $rino = intval($rino);
-
-               Logger::log("Local rino version: ". $rino, Logger::DATA);
-
-               // if requested rino is lower than enabled local rino, lower local rino version
-               // if requested rino is higher than enabled local rino, reply with local rino
-               if ($rino_remote < $rino) {
-                       $rino = $rino_remote;
-               }
-
-               if (($importer['rel'] && ($importer['rel'] != Contact::SHARING)) || ($importer['page-flags'] == User::PAGE_FLAGS_COMMUNITY)) {
-                       $perm = 'rw';
-               } else {
-                       $perm = 'r';
-               }
-
-               header("Content-type: text/xml");
-
-               echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n"
-                       . '<dfrn_notify>' . "\r\n"
-                       . "\t" . '<status>' . $status . '</status>' . "\r\n"
-                       . "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
-                       . "\t" . '<rino>' . $rino . '</rino>' . "\r\n"
-                       . "\t" . '<perm>' . $perm . '</perm>' . "\r\n"
-                       . "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n"
-                       . "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
-                       . '</dfrn_notify>' . "\r\n";
-
-               exit();
-       }
+       throw new HTTPException\NotFoundException();
 }
index f0a8e855e9a3891dfb0677004b55bc7b28c89f89..7fd3abbd91d6af010dbf89f267be921ce94d8d66 100644 (file)
  */
 
 use Friendica\App;
-use Friendica\Core\Logger;
-use Friendica\Core\Session;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Protocol\DFRN;
 use Friendica\Protocol\OStatus;
-use Friendica\Util\Strings;
-use Friendica\Util\XML;
+use Friendica\Network\HTTPException;
 
 function dfrn_poll_init(App $a)
 {
-       DI::auth()->withSession($a);
-
-       $dfrn_id         =  $_GET['dfrn_id']         ?? '';
-       $type            = ($_GET['type']            ?? '') ?: 'data';
-       $last_update     =  $_GET['last_update']     ?? '';
-       $destination_url =  $_GET['destination_url'] ?? '';
-       $challenge       =  $_GET['challenge']       ?? '';
-       $sec             =  $_GET['sec']             ?? '';
-       $dfrn_version    = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
-       $quiet                   = !empty($_GET['quiet']);
-
-       // Possibly it is an OStatus compatible server that requests a user feed
-       $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
-       if (($a->argc > 1) && ($dfrn_id == '') && !strstr($user_agent, 'Friendica')) {
+       if ($a->argc > 1) {
                $nickname = $a->argv[1];
                header("Content-type: application/atom+xml");
+               $last_update = $_GET['last_update'] ?? '';
                echo OStatus::feed($nickname, $last_update, 10);
                exit();
        }
-
-       $direction = -1;
-
-       if (strpos($dfrn_id, ':') == 1) {
-               $direction = intval(substr($dfrn_id, 0, 1));
-               $dfrn_id = substr($dfrn_id, 2);
-       }
-
-       $hidewall = false;
-
-       if (($dfrn_id === '') && empty($_POST['dfrn_id'])) {
-               if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
-                       throw new \Friendica\Network\HTTPException\ForbiddenException();
-               }
-
-               $user = '';
-               if ($a->argc > 1) {
-                       $r = q("SELECT `hidewall`,`nickname` FROM `user` WHERE `user`.`nickname` = '%s' LIMIT 1",
-                               DBA::escape($a->argv[1])
-                       );
-                       if (!$r) {
-                               throw new \Friendica\Network\HTTPException\NotFoundException();
-                       }
-
-                       $hidewall = ($r[0]['hidewall'] && !local_user());
-
-                       $user = $r[0]['nickname'];
-               }
-
-               Logger::log('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $user);
-               header("Content-type: application/atom+xml");
-               echo DFRN::feed('', $user, $last_update, 0, $hidewall);
-               exit();
-       }
-
-       if (($type === 'profile') && (!strlen($sec))) {
-               $sql_extra = '';
-               switch ($direction) {
-                       case -1:
-                               $sql_extra = sprintf(" AND ( `dfrn-id` = '%s' OR `issued-id` = '%s' ) ", DBA::escape($dfrn_id), DBA::escape($dfrn_id));
-                               $my_id = $dfrn_id;
-                               break;
-                       case 0:
-                               $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                               $my_id = '1:' . $dfrn_id;
-                               break;
-                       case 1:
-                               $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                               $my_id = '0:' . $dfrn_id;
-                               break;
-                       default:
-                               DI::baseUrl()->redirect();
-                               break; // NOTREACHED
-               }
-
-               $r = q("SELECT `contact`.*, `user`.`username`, `user`.`nickname`
-                       FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-                       AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
-                       DBA::escape($a->argv[1])
-               );
-
-               if (DBA::isResult($r)) {
-                       $s = DI::httpRequest()->fetch($r[0]['poll'] . '?dfrn_id=' . $my_id . '&type=profile-check');
-
-                       Logger::log("dfrn_poll: old profile returns " . $s, Logger::DATA);
-
-                       if (strlen($s)) {
-                               $xml = XML::parseString($s);
-
-                               if ((int)$xml->status === 1) {
-                                       $_SESSION['authenticated'] = 1;
-                                       $_SESSION['visitor_id'] = $r[0]['id'];
-                                       $_SESSION['visitor_home'] = $r[0]['url'];
-                                       $_SESSION['visitor_handle'] = $r[0]['addr'];
-                                       $_SESSION['visitor_visiting'] = $r[0]['uid'];
-                                       $_SESSION['my_url'] = $r[0]['url'];
-                                       $_SESSION['remote_comment'] = $r[0]['subscribe'];
-
-                                       Session::setVisitorsContacts();
-
-                                       if (!$quiet) {
-                                               info(DI::l10n()->t('%1$s welcomes %2$s', $r[0]['username'], $r[0]['name']));
-                                       }
-
-                                       // Visitors get 1 day session.
-                                       $session_id = session_id();
-                                       $expire = time() + 86400;
-                                       q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s'",
-                                               DBA::escape($expire),
-                                               DBA::escape($session_id)
-                                       );
-                               }
-                       }
-
-                       $profile = (count($r) > 0 && isset($r[0]['nickname']) ? $r[0]['nickname'] : '');
-                       if (!empty($destination_url)) {
-                               System::externalRedirect($destination_url);
-                       } else {
-                               DI::baseUrl()->redirect('profile/' . $profile);
-                       }
-               }
-               DI::baseUrl()->redirect();
-       }
-
-       if ($type === 'profile-check' && $dfrn_version < 2.2) {
-               if ((strlen($challenge)) && (strlen($sec))) {
-                       DBA::delete('profile_check', ["`expire` < ?", time()]);
-                       $r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1",
-                               DBA::escape($sec)
-                       );
-                       if (!DBA::isResult($r)) {
-                               System::xmlExit(3, 'No ticket');
-                               // NOTREACHED
-                       }
-
-                       $orig_id = $r[0]['dfrn_id'];
-                       if (strpos($orig_id, ':')) {
-                               $orig_id = substr($orig_id, 2);
-                       }
-
-                       $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
-                               intval($r[0]['cid'])
-                       );
-                       if (!DBA::isResult($c)) {
-                               System::xmlExit(3, 'No profile');
-                       }
-
-                       $contact = $c[0];
-
-                       $sent_dfrn_id = hex2bin($dfrn_id);
-                       $challenge = hex2bin($challenge);
-
-                       $final_dfrn_id = '';
-
-                       if (($contact['duplex']) && strlen($contact['prvkey'])) {
-                               openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
-                               openssl_private_decrypt($challenge, $decoded_challenge, $contact['prvkey']);
-                       } else {
-                               openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
-                               openssl_public_decrypt($challenge, $decoded_challenge, $contact['pubkey']);
-                       }
-
-                       $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
-
-                       if (strpos($final_dfrn_id, ':') == 1) {
-                               $final_dfrn_id = substr($final_dfrn_id, 2);
-                       }
-
-                       if ($final_dfrn_id != $orig_id) {
-                               Logger::log('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, Logger::DEBUG);
-                               // did not decode properly - cannot trust this site
-                               System::xmlExit(3, 'Bad decryption');
-                       }
-
-                       header("Content-type: text/xml");
-                       echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
-                       exit();
-                       // NOTREACHED
-               } else {
-                       // old protocol
-                       switch ($direction) {
-                               case 1:
-                                       $dfrn_id = '0:' . $dfrn_id;
-                                       break;
-                               case 0:
-                                       $dfrn_id = '1:' . $dfrn_id;
-                                       break;
-                               default:
-                                       break;
-                       }
-
-                       DBA::delete('profile_check', ["`expire` < ?", time()]);
-                       $r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC",
-                               DBA::escape($dfrn_id));
-                       if (DBA::isResult($r)) {
-                               System::xmlExit(1);
-                               return; // NOTREACHED
-                       }
-                       System::xmlExit(0);
-                       return; // NOTREACHED
-               }
-       }
-}
-
-function dfrn_poll_post(App $a)
-{
-       $dfrn_id      =  $_POST['dfrn_id']   ?? '';
-       $challenge    =  $_POST['challenge'] ?? '';
-       $sec          =  $_POST['sec']       ?? '';
-       $ptype        =  $_POST['type']      ?? '';
-       $perm         = ($_POST['perm']      ?? '') ?: 'r';
-       $dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
-
-       if ($ptype === 'profile-check') {
-               if (strlen($challenge) && strlen($sec)) {
-                       Logger::log('dfrn_poll: POST: profile-check');
-
-                       DBA::delete('profile_check', ["`expire` < ?", time()]);
-                       $r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1",
-                               DBA::escape($sec)
-                       );
-                       if (!DBA::isResult($r)) {
-                               System::xmlExit(3, 'No ticket');
-                               // NOTREACHED
-                       }
-
-                       $orig_id = $r[0]['dfrn_id'];
-                       if (strpos($orig_id, ':')) {
-                               $orig_id = substr($orig_id, 2);
-                       }
-
-                       $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
-                               intval($r[0]['cid'])
-                       );
-                       if (!DBA::isResult($c)) {
-                               System::xmlExit(3, 'No profile');
-                       }
-
-                       $contact = $c[0];
-
-                       $sent_dfrn_id = hex2bin($dfrn_id);
-                       $challenge = hex2bin($challenge);
-
-                       $final_dfrn_id = '';
-
-                       if ($contact['duplex'] && strlen($contact['prvkey'])) {
-                               openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
-                               openssl_private_decrypt($challenge, $decoded_challenge, $contact['prvkey']);
-                       } else {
-                               openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
-                               openssl_public_decrypt($challenge, $decoded_challenge, $contact['pubkey']);
-                       }
-
-                       $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
-
-                       if (strpos($final_dfrn_id, ':') == 1) {
-                               $final_dfrn_id = substr($final_dfrn_id, 2);
-                       }
-
-                       if ($final_dfrn_id != $orig_id) {
-                               Logger::log('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, Logger::DEBUG);
-                               // did not decode properly - cannot trust this site
-                               System::xmlExit(3, 'Bad decryption');
-                       }
-
-                       header("Content-type: text/xml");
-                       echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
-                       exit();
-                       // NOTREACHED
-               }
-       }
-
-       $direction = -1;
-       if (strpos($dfrn_id, ':') == 1) {
-               $direction = intval(substr($dfrn_id, 0, 1));
-               $dfrn_id = substr($dfrn_id, 2);
-       }
-
-       $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
-               DBA::escape($dfrn_id),
-               DBA::escape($challenge)
-       );
-
-       if (!DBA::isResult($r)) {
-               exit();
-       }
-
-       $last_update = $r[0]['last_update'];
-
-       DBA::delete('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge]);
-
-       $sql_extra = '';
-       switch ($direction) {
-               case -1:
-                       $sql_extra = sprintf(" AND `issued-id` = '%s' ", DBA::escape($dfrn_id));
-                       break;
-               case 0:
-                       $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                       break;
-               case 1:
-                       $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                       break;
-               default:
-                       DI::baseUrl()->redirect();
-                       break; // NOTREACHED
-       }
-
-       $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1");
-       if (!DBA::isResult($r)) {
-               exit();
-       }
-
-       $contact = $r[0];
-       $contact_id = $r[0]['id'];
-
-       // Update the writable flag if it changed
-       Logger::debug('post request feed', ['post' => $_POST]);
-       if ($dfrn_version >= 2.21) {
-               if ($perm === 'rw') {
-                       $writable = 1;
-               } else {
-                       $writable = 0;
-               }
-
-               if ($writable != $contact['writable']) {
-                       q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d",
-                               intval($writable),
-                               intval($contact_id)
-                       );
-               }
-       }
-
-       header("Content-type: application/atom+xml");
-       $o = DFRN::feed($dfrn_id, $a->argv[1], $last_update, $direction);
-       echo $o;
-       exit();
-}
-
-function dfrn_poll_content(App $a)
-{
-       $dfrn_id         =  $_GET['dfrn_id']         ?? '';
-       $type            = ($_GET['type']            ?? '') ?: 'data';
-       $last_update     =  $_GET['last_update']     ?? '';
-       $destination_url =  $_GET['destination_url'] ?? '';
-       $sec             =  $_GET['sec']             ?? '';
-       $dfrn_version    = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
-       $quiet           = !empty($_GET['quiet']);
-
-       $direction = -1;
-       if (strpos($dfrn_id, ':') == 1) {
-               $direction = intval(substr($dfrn_id, 0, 1));
-               $dfrn_id = substr($dfrn_id, 2);
-       }
-
-       if ($dfrn_id != '') {
-               // initial communication from external contact
-               $hash = Strings::getRandomHex();
-
-               $status = 0;
-
-               DBA::delete('challenge', ["`expire` < ?", time()]);
-
-               if ($type !== 'profile') {
-                       q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` )
-                               VALUES( '%s', '%s', '%s', '%s', '%s' ) ",
-                               DBA::escape($hash),
-                               DBA::escape($dfrn_id),
-                               intval(time() + 60 ),
-                               DBA::escape($type),
-                               DBA::escape($last_update)
-                       );
-               }
-
-               $sql_extra = '';
-               switch ($direction) {
-                       case -1:
-                               if ($type === 'profile') {
-                                       $sql_extra = sprintf(" AND (`dfrn-id` = '%s' OR `issued-id` = '%s') ", DBA::escape($dfrn_id), DBA::escape($dfrn_id));
-                               } else {
-                                       $sql_extra = sprintf(" AND `issued-id` = '%s' ", DBA::escape($dfrn_id));
-                               }
-
-                               $my_id = $dfrn_id;
-                               break;
-                       case 0:
-                               $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                               $my_id = '1:' . $dfrn_id;
-                               break;
-                       case 1:
-                               $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                               $my_id = '0:' . $dfrn_id;
-                               break;
-                       default:
-                               DI::baseUrl()->redirect();
-                               break; // NOTREACHED
-               }
-
-               $nickname = $a->argv[1];
-
-               $r = q("SELECT `contact`.*, `user`.`username`, `user`.`nickname`
-                       FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-                       AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
-                       DBA::escape($nickname)
-               );
-               if (DBA::isResult($r)) {
-                       $challenge = '';
-                       $encrypted_id = '';
-                       $id_str = $my_id . '.' . mt_rand(1000, 9999);
-
-                       if (($r[0]['duplex'] && strlen($r[0]['pubkey'])) || !strlen($r[0]['prvkey'])) {
-                               openssl_public_encrypt($hash, $challenge, $r[0]['pubkey']);
-                               openssl_public_encrypt($id_str, $encrypted_id, $r[0]['pubkey']);
-                       } else {
-                               openssl_private_encrypt($hash, $challenge, $r[0]['prvkey']);
-                               openssl_private_encrypt($id_str, $encrypted_id, $r[0]['prvkey']);
-                       }
-
-                       $challenge = bin2hex($challenge);
-                       $encrypted_id = bin2hex($encrypted_id);
-               } else {
-                       $status = 1;
-                       $challenge = '';
-                       $encrypted_id = '';
-               }
-
-               if (($type === 'profile') && (strlen($sec))) {
-                       // heluecht: I don't know why we don't fail immediately when the user or contact hadn't been found.
-                       // Since it doesn't make sense to continue from this point on, we now fail here. This should be safe.
-                       if (!DBA::isResult($r)) {
-                               throw new \Friendica\Network\HTTPException\NotFoundException();
-                       }
-
-                       // URL reply
-                       if ($dfrn_version < 2.2) {
-                               $s = DI::httpRequest()->fetch($r[0]['poll']
-                                                             . '?dfrn_id=' . $encrypted_id
-                                                             . '&type=profile-check'
-                                                             . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
-                                                             . '&challenge=' . $challenge
-                                                             . '&sec=' . $sec
-                               );
-                       } else {
-                               $s = DI::httpRequest()->post($r[0]['poll'], [
-                                       'dfrn_id'      => $encrypted_id,
-                                       'type'         => 'profile-check',
-                                       'dfrn_version' => DFRN_PROTOCOL_VERSION,
-                                       'challenge'    => $challenge,
-                                       'sec'          => $sec
-                               ])->getBody();
-                       }
-
-                       Logger::log("dfrn_poll: sec profile: " . $s, Logger::DATA);
-
-                       if (strlen($s) && strstr($s, '<?xml')) {
-                               $xml = XML::parseString($s);
-
-                               Logger::debug(' profile: parsed', ['xml' => $xml]);
-
-                               Logger::log('dfrn_poll: secure profile: challenge: ' . $xml->challenge . ' expecting ' . $hash);
-                               Logger::log('dfrn_poll: secure profile: sec: ' . $xml->sec . ' expecting ' . $sec);
-
-                               if (((int) $xml->status == 0) && ($xml->challenge == $hash) && ($xml->sec == $sec)) {
-                                       $_SESSION['authenticated'] = 1;
-                                       $_SESSION['visitor_id'] = $r[0]['id'];
-                                       $_SESSION['visitor_home'] = $r[0]['url'];
-                                       $_SESSION['visitor_handle'] = $r[0]['addr'];
-                                       $_SESSION['visitor_visiting'] = $r[0]['uid'];
-                                       $_SESSION['my_url'] = $r[0]['url'];
-                                       $_SESSION['remote_comment'] = $r[0]['subscribe'];
-
-                                       Session::setVisitorsContacts();
-
-                                       if (!$quiet) {
-                                               info(DI::l10n()->t('%1$s welcomes %2$s', $r[0]['username'], $r[0]['name']));
-                                       }
-
-                                       // Visitors get 1 day session.
-                                       $session_id = session_id();
-                                       $expire = time() + 86400;
-                                       q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s'",
-                                               DBA::escape($expire),
-                                               DBA::escape($session_id)
-                                       );
-                               }
-                       }
-
-                       $profile = ((DBA::isResult($r) && $r[0]['nickname']) ? $r[0]['nickname'] : $nickname);
-
-                       switch ($destination_url) {
-                               case 'profile':
-                                       DI::baseUrl()->redirect('profile/' . $profile . '/profile');
-                                       break;
-                               case 'photos':
-                                       DI::baseUrl()->redirect('photos/' . $profile);
-                                       break;
-                               case 'status':
-                               case '':
-                                       DI::baseUrl()->redirect('profile/' . $profile);
-                                       break;
-                               default:
-                                       $appendix = (strstr($destination_url, '?') ? '&redir=1' : '?redir=1');
-                                       DI::baseUrl()->redirect($destination_url . $appendix);
-                                       break;
-                       }
-                       // NOTREACHED
-               } else {
-                       // XML reply
-                       header("Content-type: text/xml");
-                       echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n"
-                               . '<dfrn_poll>' . "\r\n"
-                               . "\t" . '<status>' . $status . '</status>' . "\r\n"
-                               . "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
-                               . "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n"
-                               . "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
-                               . '</dfrn_poll>' . "\r\n";
-                       exit();
-                       // NOTREACHED
-               }
-       }
+       throw new HTTPException\BadRequestException();
 }
diff --git a/mod/dfrn_request.php b/mod/dfrn_request.php
deleted file mode 100644 (file)
index bdb5a8d..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- *Handles communication associated with the issuance of friend requests.
- *
- * @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
- *    You also find a graphic which describes the confirmation process at
- *    https://github.com/friendica/friendica/blob/stable/spec/dfrn2_contact_request.png
- */
-
-use Friendica\App;
-use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
-use Friendica\Core\Renderer;
-use Friendica\Core\Search;
-use Friendica\Core\Session;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\Group;
-use Friendica\Model\Notification;
-use Friendica\Model\Profile;
-use Friendica\Model\User;
-use Friendica\Module\Security\Login;
-use Friendica\Network\Probe;
-use Friendica\Protocol\Activity;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Network;
-use Friendica\Util\Strings;
-
-function dfrn_request_init(App $a)
-{
-       if ($a->argc > 1) {
-               $which = $a->argv[1];
-               Profile::load($a, $which);
-       }
-
-       return;
-}
-
-/**
- * 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.
- *
- * @param App $a
- * @throws ImagickException
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
-function dfrn_request_post(App $a)
-{
-       if ($a->argc != 2 || empty($a->profile)) {
-               Logger::log('Wrong count of argc or profiles: argc=' . $a->argc . ', profile()=' . count($a->profile ?? []));
-               return;
-       }
-
-       if (!empty($_POST['cancel'])) {
-               DI::baseUrl()->redirect();
-       }
-
-       /*
-        * Scenario 2: We've introduced ourself to another cell, then have been returned to our own cell
-        * to confirm the request, and then we've clicked submit (perhaps after logging in).
-        * That brings us here:
-        */
-       if (!empty($_POST['localconfirm']) && ($_POST['localconfirm'] == 1)) {
-               // Ensure this is a valid request
-               if (local_user() && ($a->user['nickname'] == $a->argv[1]) && !empty($_POST['dfrn_url'])) {
-                       $dfrn_url    = Strings::escapeTags(trim($_POST['dfrn_url']));
-                       $aes_allow   = !empty($_POST['aes_allow']);
-                       $confirm_key = $_POST['confirm_key'] ?? '';
-                       $hidden      = (!empty($_POST['hidden-contact']) ? intval($_POST['hidden-contact']) : 0);
-                       $contact_record = null;
-                       $blocked     = 1;
-                       $pending     = 1;
-
-                       if (!empty($dfrn_url)) {
-                               // Lookup the contact based on their URL (which is the only unique thing we have at the moment)
-                               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND NOT `self` LIMIT 1",
-                                       intval(local_user()),
-                                       DBA::escape(Strings::normaliseLink($dfrn_url))
-                               );
-
-                               if (DBA::isResult($r)) {
-                                       if (strlen($r[0]['dfrn-id'])) {
-                                               // We don't need to be here. It has already happened.
-                                               notice(DI::l10n()->t("This introduction has already been accepted."));
-                                               return;
-                                       } else {
-                                               $contact_record = $r[0];
-                                       }
-                               }
-
-                               if (is_array($contact_record)) {
-                                       $r = q("UPDATE `contact` SET `ret-aes` = %d, hidden = %d WHERE `id` = %d",
-                                               intval($aes_allow),
-                                               intval($hidden),
-                                               intval($contact_record['id'])
-                                       );
-                               } else {
-                                       // Scrape the other site's profile page to pick up the dfrn links, key, fn, and photo
-                                       $parms = Probe::profile($dfrn_url);
-
-                                       if (!count($parms)) {
-                                               notice(DI::l10n()->t('Profile location is not valid or does not contain profile information.'));
-                                               return;
-                                       } else {
-                                               if (empty($parms['fn'])) {
-                                                       notice(DI::l10n()->t('Warning: profile location has no identifiable owner name.'));
-                                               }
-                                               if (empty($parms['photo'])) {
-                                                       notice(DI::l10n()->t('Warning: profile location has no profile photo.'));
-                                               }
-                                               $invalid = Probe::validDfrn($parms);
-                                               if ($invalid) {
-                                                       notice(DI::l10n()->tt("%d required parameter was not found at the given location", "%d required parameters were not found at the given location", $invalid));
-                                                       return;
-                                               }
-                                       }
-
-                                       $dfrn_request = $parms['dfrn-request'];
-
-                                       $photo = $parms["photo"];
-
-                                       // Escape the entire array
-                                       DBA::escapeArray($parms);
-
-                                       // Create a contact record on our site for the other person
-                                       $r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `addr`, `name`, `nick`, `photo`, `site-pubkey`,
-                                               `request`, `confirm`, `notify`, `poll`, `network`, `aes_allow`, `hidden`, `blocked`, `pending`)
-                                               VALUES ( %d, '%s', '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d)",
-                                               intval(local_user()),
-                                               DateTimeFormat::utcNow(),
-                                               DBA::escape($dfrn_url),
-                                               DBA::escape(Strings::normaliseLink($dfrn_url)),
-                                               $parms['addr'],
-                                               $parms['fn'],
-                                               $parms['nick'],
-                                               $parms['photo'],
-                                               $parms['key'],
-                                               $parms['dfrn-request'],
-                                               $parms['dfrn-confirm'],
-                                               $parms['dfrn-notify'],
-                                               $parms['dfrn-poll'],
-                                               DBA::escape(Protocol::DFRN),
-                                               intval($aes_allow),
-                                               intval($hidden),
-                                               intval($blocked),
-                                               intval($pending)
-                                       );
-                               }
-
-                               if ($r) {
-                                       info(DI::l10n()->t("Introduction complete."));
-                               }
-
-                               $r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1",
-                                       intval(local_user()),
-                                       DBA::escape($dfrn_url),
-                                       $parms['key'] ?? '' // Potentially missing
-                               );
-                               if (DBA::isResult($r)) {
-                                       Group::addMember(User::getDefaultGroup(local_user(), $r[0]["network"]), $r[0]['id']);
-
-                                       if (isset($photo)) {
-                                               Contact::updateAvatar($r[0]["id"], $photo, true);
-                                       }
-
-                                       $forward_path = "contact/" . $r[0]['id'];
-                               } else {
-                                       $forward_path = "contact";
-                               }
-
-                               // Allow the blocked remote notification to complete
-                               if (is_array($contact_record)) {
-                                       $dfrn_request = $contact_record['request'];
-                               }
-
-                               if (!empty($dfrn_request) && strlen($confirm_key)) {
-                                       DI::httpRequest()->fetch($dfrn_request . '?confirm_key=' . $confirm_key);
-                               }
-
-                               // (ignore reply, nothing we can do it failed)
-                               DI::baseUrl()->redirect($forward_path);
-                               return; // NOTREACHED
-                       }
-               }
-
-               // invalid/bogus request
-               notice(DI::l10n()->t('Unrecoverable protocol error.'));
-               DI::baseUrl()->redirect();
-               return; // NOTREACHED
-       }
-
-       /*
-        * Otherwise:
-        *
-        * Scenario 1:
-        * 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.
-        *
-        * 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.
-        * 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..
-        *
-        * 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.
-        *
-        */
-       if (empty($a->profile['uid'])) {
-               notice(DI::l10n()->t('Profile unavailable.'));
-               return;
-       }
-
-       $nickname       = $a->profile['nickname'];
-       $uid            = $a->profile['uid'];
-       $maxreq         = intval($a->profile['maxreq']);
-       $contact_record = null;
-       $failed         = false;
-       $parms          = null;
-       $blocked = 1;
-       $pending = 1;
-
-       if (!empty($_POST['dfrn_url'])) {
-               // Block friend request spam
-               if ($maxreq) {
-                       $r = q("SELECT * FROM `intro` WHERE `datetime` > '%s' AND `uid` = %d",
-                               DBA::escape(DateTimeFormat::utc('now - 24 hours')),
-                               intval($uid)
-                       );
-                       if (DBA::isResult($r) && count($r) > $maxreq) {
-                               notice(DI::l10n()->t('%s has received too many connection requests today.', $a->profile['name']));
-                               notice(DI::l10n()->t('Spam protection measures have been invoked.'));
-                               notice(DI::l10n()->t('Friends are advised to please try again in 24 hours.'));
-                               return;
-                       }
-               }
-
-               /* Cleanup old introductions that remain blocked.
-                * Also remove the contact record, but only if there is no existing relationship
-                */
-               $r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
-                       FROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`
-                       WHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0
-                       AND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 30 MINUTE "
-               );
-               if (DBA::isResult($r)) {
-                       foreach ($r as $rr) {
-                               if (!$rr['rel']) {
-                                       DBA::delete('contact', ['id' => $rr['cid'], 'self' => false]);
-                               }
-                               DBA::delete('intro', ['id' => $rr['iid']]);
-                       }
-               }
-
-               $url = trim($_POST['dfrn_url']);
-               if (!strlen($url)) {
-                       notice(DI::l10n()->t("Invalid locator"));
-                       return;
-               }
-
-               $hcard = '';
-
-               // Detect the network
-               $data = Contact::getByURL($url);
-               $network = $data["network"];
-
-               // Canonicalize email-style profile locator
-               $url = Probe::webfingerDfrn($data['url'] ?? $url, $hcard);
-
-               if (substr($url, 0, 5) === 'stat:') {
-                       // 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 != Protocol::DIASPORA) {
-                               $network = Protocol::OSTATUS;
-                       }
-
-                       $url = substr($url, 5);
-               } else {
-                       $network = Protocol::DFRN;
-               }
-
-               Logger::log('dfrn_request: url: ' . $url . ',network=' . $network, Logger::DEBUG);
-
-               if ($network === Protocol::DFRN) {
-                       $ret = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1",
-                               intval($uid),
-                               DBA::escape($url)
-                       );
-
-                       if (DBA::isResult($ret)) {
-                               if (strlen($ret[0]['issued-id'])) {
-                                       notice(DI::l10n()->t('You have already introduced yourself here.'));
-                                       return;
-                               } elseif ($ret[0]['rel'] == Contact::FRIEND) {
-                                       notice(DI::l10n()->t('Apparently you are already friends with %s.', $a->profile['name']));
-                                       return;
-                               } else {
-                                       $contact_record = $ret[0];
-                                       $parms = ['dfrn-request' => $ret[0]['request']];
-                               }
-                       }
-
-                       $issued_id = Strings::getRandomHex();
-
-                       if (is_array($contact_record)) {
-                               // There is a contact record but no issued-id, so this
-                               // is a reciprocal introduction from a known contact
-                               $r = q("UPDATE `contact` SET `issued-id` = '%s' WHERE `id` = %d",
-                                       DBA::escape($issued_id),
-                                       intval($contact_record['id'])
-                               );
-                       } else {
-                               $url = Network::isUrlValid($url);
-                               if (!$url) {
-                                       notice(DI::l10n()->t('Invalid profile URL.'));
-                                       DI::baseUrl()->redirect(DI::args()->getCommand());
-                                       return; // NOTREACHED
-                               }
-
-                               if (!Network::isUrlAllowed($url)) {
-                                       notice(DI::l10n()->t('Disallowed profile URL.'));
-                                       DI::baseUrl()->redirect(DI::args()->getCommand());
-                                       return; // NOTREACHED
-                               }
-
-                               if (Network::isUrlBlocked($url)) {
-                                       notice(DI::l10n()->t('Blocked domain'));
-                                       DI::baseUrl()->redirect(DI::args()->getCommand());
-                                       return; // NOTREACHED
-                               }
-
-                               $parms = Probe::profile(($hcard) ? $hcard : $url);
-
-                               if (!count($parms)) {
-                                       notice(DI::l10n()->t('Profile location is not valid or does not contain profile information.'));
-                                       DI::baseUrl()->redirect(DI::args()->getCommand());
-                               } else {
-                                       if (empty($parms['fn'])) {
-                                               notice(DI::l10n()->t('Warning: profile location has no identifiable owner name.'));
-                                       }
-                                       if (empty($parms['photo'])) {
-                                               notice(DI::l10n()->t('Warning: profile location has no profile photo.'));
-                                       }
-                                       $invalid = Probe::validDfrn($parms);
-                                       if ($invalid) {
-                                               notice(DI::l10n()->tt("%d required parameter was not found at the given location", "%d required parameters were not found at the given location", $invalid));
-
-                                               return;
-                                       }
-                               }
-
-                               $parms['url'] = $url;
-                               $parms['issued-id'] = $issued_id;
-                               $photo = $parms["photo"];
-
-                               DBA::escapeArray($parms);
-                               $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `name`, `nick`, `issued-id`, `photo`, `site-pubkey`,
-                                       `request`, `confirm`, `notify`, `poll`, `network`, `blocked`, `pending` )
-                                       VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
-                                       intval($uid),
-                                       DBA::escape(DateTimeFormat::utcNow()),
-                                       $parms['url'],
-                                       DBA::escape(Strings::normaliseLink($url)),
-                                       $parms['addr'],
-                                       $parms['fn'],
-                                       $parms['nick'],
-                                       $parms['issued-id'],
-                                       $parms['photo'],
-                                       $parms['key'],
-                                       $parms['dfrn-request'],
-                                       $parms['dfrn-confirm'],
-                                       $parms['dfrn-notify'],
-                                       $parms['dfrn-poll'],
-                                       DBA::escape(Protocol::DFRN),
-                                       intval($blocked),
-                                       intval($pending)
-                               );
-
-                               // find the contact record we just created
-                               if ($r) {
-                                       $r = q("SELECT `id` FROM `contact`
-                                               WHERE `uid` = %d AND `url` = '%s' AND `issued-id` = '%s' LIMIT 1",
-                                               intval($uid),
-                                               $parms['url'],
-                                               $parms['issued-id']
-                                       );
-                                       if (DBA::isResult($r)) {
-                                               $contact_record = $r[0];
-                                               Contact::updateAvatar($contact_record["id"], $photo, true);
-                                       }
-                               }
-                       }
-                       if ($r === false) {
-                               notice(DI::l10n()->t('Failed to update contact record.'));
-                               return;
-                       }
-
-                       $hash = Strings::getRandomHex() . (string) time();   // Generate a confirm_key
-
-                       if (is_array($contact_record)) {
-                               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']),
-                                       intval(!empty($_POST['knowyou'])),
-                                       DBA::escape(Strings::escapeTags(trim($_POST['dfrn-request-message'] ?? ''))),
-                                       DBA::escape($hash),
-                                       DBA::escape(DateTimeFormat::utcNow())
-                               );
-                       }
-
-                       // This notice will only be seen by the requestor if the requestor and requestee are on the same server.
-                       if (!$failed) {
-                               info(DI::l10n()->t('Your introduction has been sent.'));
-                       }
-
-                       // "Homecoming" - send the requestor back to their site to record the introduction.
-                       $dfrn_url = bin2hex(DI::baseUrl()->get() . '/profile/' . $nickname);
-                       $aes_allow = ((function_exists('openssl_encrypt')) ? 1 : 0);
-
-                       System::externalRedirect($parms['dfrn-request'] . "?dfrn_url=$dfrn_url"
-                               . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
-                               . '&confirm_key=' . $hash
-                               . (($aes_allow) ? "&aes_allow=1" : "")
-                       );
-                       // NOTREACHED
-                       // END $network === Protocol::DFRN
-               } elseif (($network != Protocol::PHANTOM) && ($url != "")) {
-
-                       /* Substitute our user's feed URL into $url template
-                        * Send the subscriber home to subscribe
-                        */
-                       // Diaspora needs the uri in the format user@domain.tld
-                       // Diaspora will support the remote subscription in a future version
-                       if ($network == Protocol::DIASPORA) {
-                               $uri = urlencode($a->profile['addr']);
-                       } else {
-                               $uri = urlencode($a->profile['url']);
-                       }
-
-                       $url = str_replace('{uri}', $uri, $url);
-                       System::externalRedirect($url);
-                       // NOTREACHED
-                       // END $network != Protocol::PHANTOM
-               } else {
-                       notice(DI::l10n()->t("Remote subscription can't be done for your network. Please subscribe directly on your system."));
-                       return;
-               }
-       } return;
-}
-
-function dfrn_request_content(App $a)
-{
-       if ($a->argc != 2 || empty($a->profile)) {
-               return "";
-       }
-
-       // "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.
-       if (!empty($_GET['dfrn_url'])) {
-               if (!local_user()) {
-                       info(DI::l10n()->t("Please login to confirm introduction."));
-                       /* setup the return URL to come back to this page if they use openid */
-                       return Login::form();
-               }
-
-               // Edge case, but can easily happen in the wild. This person is authenticated,
-               // but not as the person who needs to deal with this request.
-               if ($a->user['nickname'] != $a->argv[1]) {
-                       notice(DI::l10n()->t("Incorrect identity currently logged in. Please login to <strong>this</strong> profile."));
-                       return Login::form();
-               }
-
-               $dfrn_url = Strings::escapeTags(trim(hex2bin($_GET['dfrn_url'])));
-               $aes_allow = !empty($_GET['aes_allow']);
-               $confirm_key = $_GET['confirm_key'] ?? '';
-
-               // Checking fastlane for validity
-               if (!empty($_SESSION['fastlane']) && (Strings::normaliseLink($_SESSION["fastlane"]) == Strings::normaliseLink($dfrn_url))) {
-                       $_POST["dfrn_url"] = $dfrn_url;
-                       $_POST["confirm_key"] = $confirm_key;
-                       $_POST["localconfirm"] = 1;
-                       $_POST["hidden-contact"] = 0;
-                       $_POST["submit"] = DI::l10n()->t('Confirm');
-
-                       dfrn_request_post($a);
-
-                       exit();
-               }
-
-               $tpl = Renderer::getMarkupTemplate("dfrn_req_confirm.tpl");
-               $o = Renderer::replaceMacros($tpl, [
-                       '$dfrn_url' => $dfrn_url,
-                       '$aes_allow' => (($aes_allow) ? '<input type="hidden" name="aes_allow" value="1" />' : "" ),
-                       '$hidethem' => DI::l10n()->t('Hide this contact'),
-                       '$confirm_key' => $confirm_key,
-                       '$welcome' => DI::l10n()->t('Welcome home %s.', $a->user['username']),
-                       '$please' => DI::l10n()->t('Please confirm your introduction/connection request to %s.', $dfrn_url),
-                       '$submit' => DI::l10n()->t('Confirm'),
-                       '$uid' => $_SESSION['uid'],
-                       '$nickname' => $a->user['nickname'],
-                       'dfrn_rawurl' => $_GET['dfrn_url']
-               ]);
-               return $o;
-       } elseif (!empty($_GET['confirm_key'])) {
-               // we are the requestee and it is now safe to send our user their introduction,
-               // 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.
-               $intro = q("SELECT * FROM `intro` WHERE `hash` = '%s' LIMIT 1",
-                       DBA::escape($_GET['confirm_key'])
-               );
-
-               if (DBA::isResult($intro)) {
-                       $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'])
-                       );
-
-                       $auto_confirm = false;
-
-                       if (DBA::isResult($r)) {
-                               if ($r[0]['page-flags'] != User::PAGE_FLAGS_NORMAL && $r[0]['page-flags'] != User::PAGE_FLAGS_PRVGROUP) {
-                                       $auto_confirm = true;
-                               }
-
-                               if (!$auto_confirm) {
-                                       notification([
-                                               'type'  => Notification\Type::INTRO,
-                                               'otype' => Notification\ObjectType::INTRO,
-                                               'verb'  => Activity::REQ_FRIEND,
-                                               'uid'   => $r[0]['uid'],
-                                               'cid'   => $r[0]['id'],
-                                               'link'  => DI::baseUrl() . '/notifications/intros',
-                                       ]);
-                               }
-
-                               if ($auto_confirm) {
-                                       require_once 'mod/dfrn_confirm.php';
-                                       $handsfree = [
-                                               'uid'      => $r[0]['uid'],
-                                               'node'     => $r[0]['nickname'],
-                                               'dfrn_id'  => $r[0]['issued-id'],
-                                               'intro_id' => $intro[0]['id'],
-                                               'duplex'   => (($r[0]['page-flags'] == User::PAGE_FLAGS_FREELOVE) ? 1 : 0),
-                                       ];
-                                       dfrn_confirm_post($a, $handsfree);
-                               }
-                       }
-
-                       if (!$auto_confirm) {
-
-                               // If we are auto_confirming, this record will have already been nuked
-                               // in dfrn_confirm_post()
-
-                               q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s'",
-                                       DBA::escape($_GET['confirm_key'])
-                               );
-                       }
-               }
-
-               exit();
-       } else {
-               // Normal web request. Display our user's introduction form.
-               if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
-                       if (!DI::config()->get('system', 'local_block')) {
-                               notice(DI::l10n()->t('Public access denied.'));
-                               return;
-                       }
-               }
-
-               // Try to auto-fill the profile address
-               // At first look if an address was provided
-               // Otherwise take the local address
-               if (!empty($_GET['addr'])) {
-                       $myaddr = hex2bin($_GET['addr']);
-               } elseif (!empty($_GET['address'])) {
-                       $myaddr = $_GET['address'];
-               } elseif (local_user()) {
-                       if (strlen(DI::baseUrl()->getUrlPath())) {
-                               $myaddr = DI::baseUrl() . '/profile/' . $a->user['nickname'];
-                       } else {
-                               $myaddr = $a->user['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3);
-                       }
-               } else {
-                       // last, try a zrl
-                       $myaddr = Profile::getMyURL();
-               }
-
-               $target_addr = $a->profile['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3);
-
-               /* The auto_request form only has the profile address
-                * because nobody is going to read the comments and
-                * it doesn't matter if they know you or not.
-                */
-               if ($a->profile['page-flags'] == User::PAGE_FLAGS_NORMAL) {
-                       $tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
-               } else {
-                       $tpl = Renderer::getMarkupTemplate('auto_request.tpl');
-               }
-
-               $o = Renderer::replaceMacros($tpl, [
-                       '$header'        => DI::l10n()->t('Friend/Connection Request'),
-                       '$page_desc'     => DI::l10n()->t('Enter your Webfinger address (user@domain.tld) or profile URL here. If this isn\'t supported by your system (for example it doesn\'t work with Diaspora), you have to subscribe to <strong>%s</strong> directly on your system', $target_addr),
-                       '$invite_desc'   => DI::l10n()->t('If you are not yet a member of the free social web, <a href="%s">follow this link to find a public Friendica node and join us today</a>.', Search::getGlobalDirectory() . '/servers'),
-                       '$your_address'  => DI::l10n()->t('Your Webfinger address or profile URL:'),
-                       '$pls_answer'    => DI::l10n()->t('Please answer the following:'),
-                       '$submit'        => DI::l10n()->t('Submit Request'),
-                       '$cancel'        => DI::l10n()->t('Cancel'),
-
-                       '$request'       => 'dfrn_request/' . $a->argv[1],
-                       '$name'          => $a->profile['name'],
-                       '$myaddr'        => $myaddr,
-
-                       '$does_know_you' => ['knowyou', DI::l10n()->t('%s knows you', $a->profile['name'])],
-                       '$addnote_field' => ['dfrn-request-message', DI::l10n()->t('Add a personal note:')],
-               ]);
-               return $o;
-       }
-}
index ed8e3aa5fee881bd470d308be901fa3adb613809..ac74d217bc4d816f09a952d0180d417d93bf7afa 100644 (file)
@@ -118,18 +118,13 @@ function follow_content(App $a)
                $contact['url'] = $contact['addr'];
        }
 
-       if (($protocol === Protocol::DFRN) && !DBA::isResult($contact)) {
-               $request = $contact['request'];
-               $tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
-       } else {
-               if (!empty($_REQUEST['auto'])) {
-                       follow_process($a, $contact['url']);
-               }
-       
-               $request = DI::baseUrl() . '/follow';
-               $tpl = Renderer::getMarkupTemplate('auto_request.tpl');
+       if (!empty($_REQUEST['auto'])) {
+               follow_process($a, $contact['url']);
        }
 
+       $request = DI::baseUrl() . '/follow';
+       $tpl = Renderer::getMarkupTemplate('auto_request.tpl');
+
        $owner = User::getOwnerDataById($uid);
        if (empty($owner)) {
                notice(DI::l10n()->t('Permission denied.'));
@@ -139,9 +134,6 @@ function follow_content(App $a)
 
        $myaddr = $owner['url'];
 
-       // Makes the connection request for friendica contacts easier
-       $_SESSION['fastlane'] = $contact['url'];
-
        $o = Renderer::replaceMacros($tpl, [
                '$header'        => DI::l10n()->t('Connect/Follow'),
                '$pls_answer'    => DI::l10n()->t('Please answer the following:'),
@@ -182,10 +174,6 @@ function follow_process(App $a, string $url)
 {
        $return_path = 'follow?url=' . urlencode($url);
 
-       // Makes the connection request for friendica contacts easier
-       // This is just a precaution if maybe this page is called somewhere directly via POST
-       $_SESSION['fastlane'] = $url;
-
        $result = Contact::createFromProbe($a->user, $url, true);
 
        if ($result['success'] == false) {
index 71db74e9a42eb34bd07c456a2084ce22ed588c8a..2f97911dc3c9662385e5d83d9016897ce17eaab7 100644 (file)
@@ -50,7 +50,7 @@ function redir_init(App $a) {
                throw new \Friendica\Network\HTTPException\BadRequestException(DI::l10n()->t('Bad Request.'));
        }
 
-       $fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
+       $fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name'];
        $contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
        if (!DBA::isResult($contact)) {
                throw new \Friendica\Network\HTTPException\NotFoundException(DI::l10n()->t('Contact not found.'));
@@ -99,33 +99,6 @@ function redir_init(App $a) {
                }
        }
 
-       // Doing remote auth with dfrn.
-       if (local_user() && (!empty($contact['dfrn-id']) || !empty($contact['issued-id'])) && empty($contact['pending'])) {
-               $dfrn_id = $orig_id = (($contact['issued-id']) ? $contact['issued-id'] : $contact['dfrn-id']);
-
-               if ($contact['duplex'] && $contact['issued-id']) {
-                       $orig_id = $contact['issued-id'];
-                       $dfrn_id = '1:' . $orig_id;
-               }
-               if ($contact['duplex'] && $contact['dfrn-id']) {
-                       $orig_id = $contact['dfrn-id'];
-                       $dfrn_id = '0:' . $orig_id;
-               }
-
-               $sec = Strings::getRandomHex();
-
-               $fields = ['uid' => local_user(), 'cid' => $cid, 'dfrn_id' => $dfrn_id,
-                       'sec' => $sec, 'expire' => time() + 45];
-               DBA::insert('profile_check', $fields);
-
-               Logger::log('mod_redir: ' . $contact['name'] . ' ' . $sec, Logger::DEBUG);
-
-               $dest = (!empty($url) ? '&destination_url=' . $url : '');
-
-               System::externalRedirect($contact['poll'] . '?dfrn_id=' . $dfrn_id
-                       . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec . $dest . $quiet);
-       }
-
        if (empty($url)) {
                throw new \Friendica\Network\HTTPException\BadRequestException(DI::l10n()->t('Bad Request.'));
        }
index aca17727b6950627791cd742daad45352f592047..97cb0e1a327ab998d160f8c3f5c60d5c55ffe338 100644 (file)
@@ -84,9 +84,6 @@ function unfollow_content(App $a)
                // NOTREACHED
        }
 
-       // Makes the connection request for friendica contacts easier
-       $_SESSION['fastlane'] = $contact['url'];
-
        if (!empty($_REQUEST['auto'])) {
                unfollow_process($contact['url']);
        }
index 4779487283a169535153c34b9b743615f2f4b298..a6d4061a7c54f3266afdbe89377be56bc27f0688 100644 (file)
@@ -81,7 +81,7 @@ class DBStructure
 
                $old_tables = ['fserver', 'gcign', 'gcontact', 'gcontact-relation', 'gfollower' ,'glink', 'item-delivery-data',
                        'item-activity', 'item-content', 'item_id', 'participation', 'poll', 'poll_result', 'queue', 'retriever_rule',
-                       'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item'];
+                       'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge'];
 
                $tables = DBA::selectToArray(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_NAME'],
                        ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']);
index 0e3de02d67374cbc56ab87fc85bcfd8d09657f99..ab8a7db8c445672c196376739a07f2dba9d91389 100644 (file)
@@ -811,13 +811,11 @@ class Contact
                }
 
                $protocol = $contact['network'];
-               if (($protocol == Protocol::DFRN) && !self::isLegacyDFRNContact($contact)) {
-                       $protocol = Protocol::ACTIVITYPUB;
+               if (($protocol == Protocol::DFRN) && !empty($contact['protocol'])) {
+                       $protocol = $contact['protocol'];
                }
 
-               if (($protocol == Protocol::DFRN) && $dissolve) {
-                       DFRN::deliver($user, $contact, 'placeholder', true);
-               } elseif (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
+               if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
                        // create an unfollow slap
                        $item = [];
                        $item['verb'] = Activity::O_UNFOLLOW;
@@ -2273,18 +2271,6 @@ class Contact
                return $id;
        }
 
-       /**
-        * Detects if a given contact array belongs to a legacy DFRN connection
-        *
-        * @param array $contact
-        * @return boolean
-        */
-       public static function isLegacyDFRNContact($contact)
-       {
-               // Newer Friendica contacts are connected via AP, then these fields aren't set
-               return !empty($contact['dfrn-id']) || !empty($contact['issued-id']);
-       }
-
        /**
         * Detects the communication protocol for a given contact url.
         * This is used to detect Friendica contacts that we can communicate via AP.
@@ -2387,24 +2373,6 @@ class Contact
 
                $protocol = self::getProtocol($ret['url'], $ret['network']);
 
-               if (($protocol === Protocol::DFRN) && !DBA::isResult($contact)) {
-                       if ($interactive) {
-                               if (strlen(DI::baseUrl()->getUrlPath())) {
-                                       $myaddr = bin2hex(DI::baseUrl() . '/profile/' . $user['nickname']);
-                               } else {
-                                       $myaddr = bin2hex($user['nickname'] . '@' . DI::baseUrl()->getHostname());
-                               }
-
-                               DI::baseUrl()->redirect($ret['request'] . "&addr=$myaddr");
-
-                               // NOTREACHED
-                       }
-               } elseif (DI::config()->get('system', 'dfrn_only') && ($ret['network'] != Protocol::DFRN)) {
-                       $result['message'] = DI::l10n()->t('This site is not configured to allow communications with other networks.') . EOL;
-                       $result['message'] .= DI::l10n()->t('No compatible communication protocols or feeds were discovered.') . EOL;
-                       return $result;
-               }
-
                // This extra param just confuses things, remove it
                if ($protocol === Protocol::DIASPORA) {
                        $ret['url'] = str_replace('?absolute=true', '', $ret['url']);
index 742d5230a358b04ba2675d4903738295cd60fa1a..aa2faca503d78c8663d773349467b898f9640e25 100644 (file)
@@ -38,7 +38,7 @@ class Conversation
        const PARCEL_SALMON             = 3;
        const PARCEL_FEED               = 4; // Deprecated
        const PARCEL_SPLIT_CONVERSATION = 6;
-       const PARCEL_LEGACY_DFRN        = 7;
+       const PARCEL_LEGACY_DFRN        = 7; // Deprecated
        const PARCEL_DIASPORA_DFRN      = 8;
        const PARCEL_LOCAL_DFRN         = 9;
        const PARCEL_DIRECT             = 10;
index 5ce9eb86f2f449c91125e3483c0056262b15c1cf..87819593121e009cb8bdc2516084bb07587442f6 100644 (file)
@@ -135,13 +135,7 @@ class Introductions extends BaseNotifications
                                        $friend = ['duplex', DI::l10n()->t('Friend'), '1', $helptext2, true];
                                        $follower = ['duplex', DI::l10n()->t('Subscriber'), '0', $helptext3, false];
 
-                                       $contact = DBA::selectFirst('contact', ['network', 'protocol'], ['id' => $notification->getContactId()]);
-
-                                       if (($contact['network'] != Protocol::DFRN) || ($contact['protocol'] == Protocol::ACTIVITYPUB)) {
-                                               $action = 'follow_confirm';
-                                       } else {
-                                               $action = 'dfrn_confirm';
-                                       }
+                                       $action = 'follow_confirm';
 
                                        $header = $notification->getName();
 
index bb13ce3f2a1b1edb84b1a44ca8dd6b37e6f745e1..2a2d90cda23e04696742b7789494fcddd13f9b37 100644 (file)
@@ -286,7 +286,7 @@ class Introduction implements \JsonSerializable
                $this->knowYou       = $data['knowYou'] ?? false;
                $this->note          = $data['note'] ?? '';
                $this->request       = $data['request'] ?? '';
-               $this->dfrnId        = $data['dfrn_id'] ?? -1;
+               $this->dfrnId        = -1;
                $this->addr          = $data['addr'] ?? '';
                $this->network       = $data['network'] ?? '';
                $this->uid           = $data['uid'] ?? -1;
index faae900b331ec22d6b0f51247ee933f01674ca11..61f5bab62765fd10baef3ca58bbf5b4fa904ae65 100644 (file)
@@ -23,9 +23,7 @@ namespace Friendica\Protocol;
 
 use DOMDocument;
 use DOMXPath;
-use Friendica\App\BaseURL;
 use Friendica\Content\Text\BBCode;
-use Friendica\Core\Hook;
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
 use Friendica\Database\DBA;
@@ -39,13 +37,10 @@ use Friendica\Model\Item;
 use Friendica\Model\ItemURI;
 use Friendica\Model\Mail;
 use Friendica\Model\Notification;
-use Friendica\Model\PermissionSet;
 use Friendica\Model\Post;
-use Friendica\Model\Post\Category;
 use Friendica\Model\Profile;
 use Friendica\Model\Tag;
 use Friendica\Model\User;
-use Friendica\Model\Verb;
 use Friendica\Network\Probe;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
@@ -145,172 +140,6 @@ class DFRN
                return trim($doc->saveXML());
        }
 
-       /**
-        * Generate an atom feed for the given user
-        *
-        * This function is called when another server is pulling data from the user feed.
-        *
-        * @param string  $dfrn_id     DFRN ID from the requesting party
-        * @param string  $owner_nick  Owner nick name
-        * @param string  $last_update Date of the last update
-        * @param int     $direction   Can be -1, 0 or 1.
-        * @param boolean $onlyheader  Output only the header without content? (Default is "no")
-        *
-        * @return string DFRN feed entries
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function feed($dfrn_id, $owner_nick, $last_update, $direction = 0, $onlyheader = false)
-       {
-               $a = DI::app();
-
-               $sitefeed    = ((strlen($owner_nick)) ? false : true); // not yet implemented, need to rewrite huge chunks of following logic
-               $public_feed = (($dfrn_id) ? false : true);
-               $starred     = false;   // not yet implemented, possible security issues
-               $converse    = false;
-
-               if ($public_feed && $a->argc > 2) {
-                       for ($x = 2; $x < $a->argc; $x++) {
-                               if ($a->argv[$x] == 'converse') {
-                                       $converse = true;
-                               }
-                               if ($a->argv[$x] == 'starred') {
-                                       $starred = true;
-                               }
-                               if ($a->argv[$x] == 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1])) {
-                                       $category = $a->argv[$x+1];
-                               }
-                       }
-               }
-
-               // default permissions - anonymous user
-
-               $sql_extra = sprintf(" AND `private` != %s ", Item::PRIVATE);
-
-               $owner = DBA::selectFirst('owner-view', [], ['nickname' => $owner_nick]);
-               if (!DBA::isResult($owner)) {
-                       Logger::log(sprintf('No contact found for nickname=%d', $owner_nick), Logger::WARNING);
-                       exit();
-               }
-
-               $owner_id = $owner['uid'];
-
-               if (!$public_feed) {
-                       switch ($direction) {
-                               case (-1):
-                                       $sql_extra = sprintf(" AND `issued-id` = '%s' ", DBA::escape($dfrn_id));
-                                       break;
-                               case 0:
-                                       $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                                       break;
-                               case 1:
-                                       $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
-                                       break;
-                               default:
-                                       return false;
-                                       break; // NOTREACHED
-                       }
-
-                       $contact = DBA::selectFirst('contact', [], ["NOT `blocked` AND `contact`.`uid` = ?" . $sql_extra, $owner_id]);
-                       if (!DBA::isResult($contact)) {
-                               Logger::notice('No contact found', ['uid' => $owner_id]);
-                               exit();
-                       }
-
-                       $set = PermissionSet::get($owner_id, $contact['id']);
-
-                       if (!empty($set)) {
-                               $sql_extra = " AND `psid` IN (" . implode(',', $set) .")";
-                       } else {
-                               $sql_extra = sprintf(" AND `private` != %s", Item::PRIVATE);
-                       }
-               }
-
-               if (!strlen($last_update)) {
-                       $last_update = 'now -30 days';
-               }
-
-               if (isset($category)) {
-                       $sql_extra .= sprintf(" AND `uri-id` IN (SELECT `uri-id` FROM `category-view` WHERE `name` = '%s' AND `type` = %d AND `uid` = %d)",
-                               DBA::escape(Strings::protectSprintf($category)), intval(Category::CATEGORY), intval($owner_id));
-               }
-
-               if ($public_feed && ! $converse) {
-                       $sql_extra .= " AND `self` ";
-               }
-
-               $check_date = DateTimeFormat::utc($last_update);
-
-               $condition = ["`uid` = ? AND `wall` AND `changed` > ? AND `vid` != ? AND `visible`" . $sql_extra,
-                       $owner_id, $check_date, Verb::getID(Activity::ANNOUNCE)];
-
-               $params = ['sort' => ['parent' => $public_feed, 'received']];
-               $items = Post::selectToArray(Item::DELIVER_FIELDLIST, $condition, $params, ['limit' => 300]);
-
-               /*
-                * Will check further below if this actually returned results.
-                * We will provide an empty feed if that is the case.
-                */
-
-               $doc = new DOMDocument('1.0', 'utf-8');
-               $doc->formatOutput = true;
-
-               $alternatelink = $owner['url'];
-
-               if (isset($category)) {
-                       $alternatelink .= "/category/".$category;
-               }
-
-               if ($public_feed) {
-                       $author = "dfrn:owner";
-               } else {
-                       $author = "author";
-               }
-
-               $root = self::addHeader($doc, $owner, $author, $alternatelink, true);
-
-               /// @TODO This hook can't work anymore
-               //      \Friendica\Core\Hook::callAll('atom_feed', $atom);
-
-               if (!DBA::isResult($items) || $onlyheader) {
-                       $atom = trim($doc->saveXML());
-
-                       Hook::callAll('atom_feed_end', $atom);
-
-                       return $atom;
-               }
-
-               foreach ($items as $item) {
-                       // prevent private email from leaking.
-                       if ($item['network'] == Protocol::MAIL) {
-                               continue;
-                       }
-
-                       // public feeds get html, our own nodes use bbcode
-
-                       if ($public_feed) {
-                               $type = 'html';
-                               // catch any email that's in a public conversation and make sure it doesn't leak
-                               if ($item['private'] == Item::PRIVATE) {
-                                       continue;
-                               }
-                       } else {
-                               $type = 'text';
-                       }
-
-                       $entry = self::entry($doc, $type, $item, $owner, true);
-                       if (isset($entry)) {
-                               $root->appendChild($entry);
-                       }
-               }
-
-               $atom = trim($doc->saveXML());
-
-               Hook::callAll('atom_feed_end', $atom);
-
-               return $atom;
-       }
-
        /**
         * Generate an atom entry for a given uri id and user
         *
@@ -1089,268 +918,6 @@ class DFRN
                return $entry;
        }
 
-       /**
-        * encrypts data via AES
-        *
-        * @param string $data The data that is to be encrypted
-        * @param string $key  The AES key
-        *
-        * @return string encrypted data
-        */
-       private static function aesEncrypt($data, $key)
-       {
-               return openssl_encrypt($data, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
-       }
-
-       /**
-        * decrypts data via AES
-        *
-        * @param string $encrypted The encrypted data
-        * @param string $key       The AES key
-        *
-        * @return string decrypted data
-        */
-       public static function aesDecrypt($encrypted, $key)
-       {
-               return openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
-       }
-
-       /**
-        * Delivers the atom content to the contacts
-        *
-        * @param array  $owner    Owner record
-        * @param array  $contact  Contact record of the receiver
-        * @param string $atom     Content that will be transmitted
-        * @param bool   $dissolve (to be documented)
-        *
-        * @return int Deliver status. Negative values mean an error.
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        * @todo  Add array type-hint for $owner, $contact
-        */
-       public static function deliver($owner, $contact, $atom, $dissolve = false)
-       {
-               $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
-
-               if ($contact['duplex'] && $contact['dfrn-id']) {
-                       $idtosend = '0:' . $orig_id;
-               }
-               if ($contact['duplex'] && $contact['issued-id']) {
-                       $idtosend = '1:' . $orig_id;
-               }
-
-               $rino = DI::config()->get('system', 'rino_encrypt');
-               $rino = intval($rino);
-
-               Logger::log("Local rino version: ". $rino, Logger::DEBUG);
-
-               $ssl_val = intval(DI::config()->get('system', 'ssl_policy'));
-
-               switch ($ssl_val) {
-                       case BaseURL::SSL_POLICY_FULL:
-                               $ssl_policy = 'full';
-                               break;
-                       case BaseURL::SSL_POLICY_SELFSIGN:
-                               $ssl_policy = 'self';
-                               break;
-                       case BaseURL::SSL_POLICY_NONE:
-                       default:
-                               $ssl_policy = 'none';
-                               break;
-               }
-
-               $url = $contact['notify'] . '&dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . (($rino) ? '&rino='.$rino : '');
-
-               Logger::log('dfrn_deliver: ' . $url);
-
-               $curlResult = DI::httpRequest()->get($url);
-
-               if ($curlResult->isTimeout()) {
-                       return -2; // timed out
-               }
-
-               $xml = $curlResult->getBody();
-
-               $curl_stat = $curlResult->getReturnCode();
-               if (empty($curl_stat)) {
-                       return -3; // timed out
-               }
-
-               Logger::log('dfrn_deliver: ' . $xml, Logger::DATA);
-
-               if (empty($xml)) {
-                       return 3;
-               }
-
-               if (strpos($xml, '<?xml') === false) {
-                       Logger::log('dfrn_deliver: no valid XML returned');
-                       Logger::log('dfrn_deliver: returned XML: ' . $xml, Logger::DATA);
-                       return 3;
-               }
-
-               $res = XML::parseString($xml);
-
-               if (!is_object($res) || (intval($res->status) != 0) || !strlen($res->challenge) || !strlen($res->dfrn_id)) {
-                       if (empty($res->status)) {
-                               $status = 3;
-                       } else {
-                               $status = $res->status;
-                       }
-
-                       return $status;
-               }
-
-               $postvars     = [];
-               $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
-               $challenge    = hex2bin((string) $res->challenge);
-               $perm         = (($res->perm) ? $res->perm : null);
-               $dfrn_version = floatval($res->dfrn_version ?: 2.0);
-               $rino_remote_version = intval($res->rino);
-               $page         = (($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY) ? 1 : 0);
-
-               Logger::log("Remote rino version: ".$rino_remote_version." for ".$contact["url"], Logger::DEBUG);
-
-               if ($owner['page-flags'] == User::PAGE_FLAGS_PRVGROUP) {
-                       $page = 2;
-               }
-
-               $final_dfrn_id = '';
-
-               if ($perm) {
-                       if ((($perm == 'rw') && !intval($contact['writable']))
-                               || (($perm == 'r') && intval($contact['writable']))
-                       ) {
-                               DBA::update('contact', ['writable' => ($perm == 'rw')], ['id' => $contact['id']]);
-
-                               $contact['writable'] = (string) 1 - intval($contact['writable']);
-                       }
-               }
-
-               if (($contact['duplex'] && strlen($contact['pubkey']))
-                       || ($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY && strlen($contact['pubkey']))
-                       || ($contact['rel'] == Contact::SHARING && strlen($contact['pubkey']))
-               ) {
-                       openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
-                       openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']);
-               } else {
-                       openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
-                       openssl_private_decrypt($challenge, $postvars['challenge'], $contact['prvkey']);
-               }
-
-               $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
-
-               if (strpos($final_dfrn_id, ':') == 1) {
-                       $final_dfrn_id = substr($final_dfrn_id, 2);
-               }
-
-               if ($final_dfrn_id != $orig_id) {
-                       Logger::log('dfrn_deliver: wrong dfrn_id.');
-                       // did not decode properly - cannot trust this site
-                       return 3;
-               }
-
-               $postvars['dfrn_id']      = $idtosend;
-               $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
-               if ($dissolve) {
-                       $postvars['dissolve'] = '1';
-               }
-
-               if ((($contact['rel']) && ($contact['rel'] != Contact::SHARING) && (! $contact['blocked'])) || ($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY)) {
-                       $postvars['data'] = $atom;
-                       $postvars['perm'] = 'rw';
-               } else {
-                       $postvars['data'] = str_replace('<dfrn:comment-allow>1', '<dfrn:comment-allow>0', $atom);
-                       $postvars['perm'] = 'r';
-               }
-
-               $postvars['ssl_policy'] = $ssl_policy;
-
-               if ($page) {
-                       $postvars['page'] = $page;
-               }
-
-
-               if ($rino > 0 && $rino_remote_version > 0 && (! $dissolve)) {
-                       Logger::log('rino version: '. $rino_remote_version);
-
-                       switch ($rino_remote_version) {
-                               case 1:
-                                       $key = random_bytes(16);
-                                       $data = self::aesEncrypt($postvars['data'], $key);
-                                       break;
-
-                               default:
-                                       Logger::log("rino: invalid requested version '$rino_remote_version'");
-                                       return -8;
-                       }
-
-                       $postvars['rino'] = $rino_remote_version;
-                       $postvars['data'] = bin2hex($data);
-
-                       if ($dfrn_version >= 2.1) {
-                               if (($contact['duplex'] && strlen($contact['pubkey']))
-                                       || ($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY && strlen($contact['pubkey']))
-                                       || ($contact['rel'] == Contact::SHARING && strlen($contact['pubkey']))
-                               ) {
-                                       openssl_public_encrypt($key, $postvars['key'], $contact['pubkey']);
-                               } else {
-                                       openssl_private_encrypt($key, $postvars['key'], $contact['prvkey']);
-                               }
-                       } else {
-                               if (($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY)) {
-                                       openssl_private_encrypt($key, $postvars['key'], $contact['prvkey']);
-                               } else {
-                                       openssl_public_encrypt($key, $postvars['key'], $contact['pubkey']);
-                               }
-                       }
-
-                       Logger::log('md5 rawkey ' . md5($postvars['key']));
-
-                       $postvars['key'] = bin2hex($postvars['key']);
-               }
-
-
-               Logger::debug('dfrn_deliver', ['post' => $postvars]);
-
-               $postResult = DI::httpRequest()->post($contact['notify'], $postvars);
-
-               $xml = $postResult->getBody();
-
-               Logger::log('dfrn_deliver: ' . "RECEIVED: " . $xml, Logger::DATA);
-
-               $curl_stat = $postResult->getReturnCode();
-               if (empty($curl_stat) || empty($xml)) {
-                       return -9; // timed out
-               }
-
-               if (($curl_stat == 503) && stristr($postResult->getHeader(), 'retry-after')) {
-                       return -10;
-               }
-
-               if (strpos($xml, '<?xml') === false) {
-                       Logger::log('dfrn_deliver: phase 2: no valid XML returned');
-                       Logger::log('dfrn_deliver: phase 2: returned XML: ' . $xml, Logger::DATA);
-                       return 3;
-               }
-
-               $res = XML::parseString($xml);
-
-               if (!isset($res->status)) {
-                       return -11;
-               }
-
-               // Possibly old servers had returned an empty value when everything was okay
-               if (empty($res->status)) {
-                       $res->status = 200;
-               }
-
-               if (!empty($res->message)) {
-                       Logger::log('Delivery returned status '.$res->status.' - '.$res->message, Logger::DEBUG);
-               }
-
-               return intval($res->status);
-       }
-
        /**
         * Transmits atom content to the contacts via the Diaspora transport layer
         *
@@ -2618,12 +2185,8 @@ class DFRN
 
                Logger::log("Import DFRN message for user " . $importer["importer_uid"] . " from contact " . $importer["id"], Logger::DEBUG);
 
-               if (!empty($importer['gsid'])) {
-                       if ($protocol == Conversation::PARCEL_DIASPORA_DFRN) {
-                               GServer::setProtocol($importer['gsid'], Post\DeliveryData::DFRN);
-                       } elseif ($protocol == Conversation::PARCEL_LEGACY_DFRN) {
-                               GServer::setProtocol($importer['gsid'], Post\DeliveryData::LEGACY_DFRN);
-                       }
+               if (!empty($importer['gsid']) && ($protocol == Conversation::PARCEL_DIASPORA_DFRN)) {
+                       GServer::setProtocol($importer['gsid'], Post\DeliveryData::DFRN);
                }
 
                // is it a public forum? Private forums aren't exposed with this method
index dad2ff7b3d0cf75819e777a53a6b58aaf5da781a..e42b5a10195f4c5035ffedbdc949873f38f0d857 100644 (file)
@@ -340,17 +340,9 @@ class Delivery
                                self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
                                return;
                        }
-               } elseif ($cmd != self::RELOCATION) {
+               } else {
                        // DFRN payload over Diaspora transport layer
                        $deliver_status = DFRN::transmit($owner, $contact, $atom);
-                       if (($deliver_status < 200) && (empty($server_protocol) || ($server_protocol == Model\Post\DeliveryData::LEGACY_DFRN))) {
-                               // Legacy DFRN
-                               $deliver_status = DFRN::deliver($owner, $contact, $atom);
-                               $protocol = Model\Post\DeliveryData::LEGACY_DFRN;
-                       }
-               } else {
-                       $deliver_status = DFRN::deliver($owner, $contact, $atom);
-                       $protocol = Model\Post\DeliveryData::LEGACY_DFRN;
                }
 
                Logger::info('DFRN Delivery', ['cmd' => $cmd, 'url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id'], 'return' => $deliver_status]);
index f98898660783306447e87511e831b9fdcf5c2fbe..c24d991b567266c234a860c2bad3389a3d4938e0 100644 (file)
@@ -42,7 +42,6 @@ class OptimizeTables
 
                DBA::e("OPTIMIZE TABLE `auth_codes`");
                DBA::e("OPTIMIZE TABLE `cache`");
-               DBA::e("OPTIMIZE TABLE `challenge`");
                DBA::e("OPTIMIZE TABLE `locks`");
                DBA::e("OPTIMIZE TABLE `oembed`");
                DBA::e("OPTIMIZE TABLE `parsed_url`");
index 19688e698cac1ecf34b758b85fc66d241eb33d7b..8af6c16eb1b1ef96491c118b2d83342529dcb86e 100644 (file)
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1429);
+       define('DB_UPDATE_VERSION', 1430);
 }
 
 return [
@@ -175,7 +175,7 @@ return [
                        "self" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "1 if the contact is the user him/her self"],
                        "remote_self" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
                        "rel" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "The kind of the relation between the user and the contact"],
-                       "duplex" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
+                       "duplex" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Deprecated"],
                        "network" => ["type" => "char(4)", "not null" => "1", "default" => "", "comment" => "Network of the contact"],
                        "protocol" => ["type" => "char(4)", "not null" => "1", "default" => "", "comment" => "Protocol of the contact"],
                        "name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Name that this contact is known by"],
@@ -191,9 +191,9 @@ return [
                        "thumb" => ["type" => "varchar(255)", "default" => "", "comment" => "Link to the profile photo (thumb size)"],
                        "micro" => ["type" => "varchar(255)", "default" => "", "comment" => "Link to the profile photo (micro size)"],
                        "header" => ["type" => "varchar(255)", "comment" => "Header picture"],
-                       "site-pubkey" => ["type" => "text", "comment" => ""],
-                       "issued-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "dfrn-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
+                       "site-pubkey" => ["type" => "text", "comment" => "Deprecated"],
+                       "issued-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Deprecated"],
+                       "dfrn-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Deprecated"],
                        "url" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "nurl" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the contact url"],
@@ -208,8 +208,8 @@ return [
                        "confirm" => ["type" => "varchar(255)", "comment" => ""],
                        "subscribe" => ["type" => "varchar(255)", "comment" => ""],
                        "poco" => ["type" => "varchar(255)", "comment" => ""],
-                       "aes_allow" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
-                       "ret-aes" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
+                       "aes_allow" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Deprecated"],
+                       "ret-aes" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Deprecated"],
                        "usehub" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
                        "subhub" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
                        "hub-verify" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
@@ -265,8 +265,6 @@ return [
                        "nurl_uid" => ["nurl(128)", "uid"],
                        "nick_uid" => ["nick(128)", "uid"],
                        "attag_uid" => ["attag(96)", "uid"],
-                       "dfrn-id" => ["dfrn-id(64)"],
-                       "issued-id" => ["issued-id(64)"],
                        "network_uid_lastupdate" => ["network", "uid", "last-update"],
                        "uid_network_self_lastupdate" => ["uid", "network", "self", "last-update"],
                        "uid_lastitem" => ["uid", "last-item"],
@@ -524,21 +522,6 @@ return [
                        "k_expires" => ["k", "expires"],
                ]
        ],
-       "challenge" => [
-               "comment" => "",
-               "fields" => [
-                       "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
-                       "challenge" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "dfrn-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "expire" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "comment" => ""],
-                       "type" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "last_update" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-               ],
-               "indexes" => [
-                       "PRIMARY" => ["id"],
-                       "expire" => ["expire"],
-               ]
-       ],
        "config" => [
                "comment" => "main configuration storage",
                "fields" => [
index bb2cd0f17a98509ac83de0862647b63d4d2d2b4c..b2b9875c193b5649e9164c8180fe73bbec6d8e7d 100644 (file)
                        "uri-date" => ["contact", "uri-date"],
                        "avatar-date" => ["contact", "avatar-date"],
                        "thumb" => ["contact", "thumb"],
-                       "dfrn-id" => ["contact", "dfrn-id"],
                        "author-id" => ["post-user", "author-id"],
                        "author-link" => ["author", "url"],
                        "author-addr" => ["author", "addr"],
                        "uri-date" => ["contact", "uri-date"],
                        "avatar-date" => ["contact", "avatar-date"],
                        "thumb" => ["contact", "thumb"],
-                       "dfrn-id" => ["contact", "dfrn-id"],
                        "author-id" => ["post-thread-user", "author-id"],
                        "author-link" => ["author", "url"],
                        "author-addr" => ["author", "addr"],
                        "uri-date" => ["author", "uri-date"],
                        "avatar-date" => ["author", "avatar-date"],
                        "thumb" => ["author", "thumb"],
-                       "dfrn-id" => ["author", "dfrn-id"],
                        "author-id" => ["post", "author-id"],
                        "author-link" => ["author", "url"],
                        "author-addr" => ["author", "addr"],
                        "uri-date" => ["author", "uri-date"],
                        "avatar-date" => ["author", "avatar-date"],
                        "thumb" => ["author", "thumb"],
-                       "dfrn-id" => ["author", "dfrn-id"],
                        "author-id" => ["post-thread", "author-id"],
                        "author-link" => ["author", "url"],
                        "author-addr" => ["author", "addr"],
                        "self" => ["contact", "self"],
                        "remote_self" => ["contact", "remote_self"],
                        "rel" => ["contact", "rel"],
-                       "duplex" => ["contact", "duplex"],
                        "network" => ["contact", "network"],
                        "protocol" => ["contact", "protocol"],
                        "name" => ["contact", "name"],
                        "thumb" => ["contact", "thumb"],
                        "micro" => ["contact", "micro"],
                        "header" => ["contact", "header"],
-                       "site-pubkey" => ["contact", "site-pubkey"],
-                       "issued-id" => ["contact", "issued-id"],
-                       "dfrn-id" => ["contact", "dfrn-id"],
                        "url" => ["contact", "url"],
                        "nurl" => ["contact", "nurl"],
                        "uri-id" => ["contact", "uri-id"],
                        "poll" => ["contact", "poll"],
                        "confirm" => ["contact", "confirm"],
                        "poco" => ["contact", "poco"],
-                       "aes_allow" => ["contact", "aes_allow"],
-                       "ret-aes" => ["contact", "ret-aes"],
                        "usehub" => ["contact", "usehub"],
                        "subhub" => ["contact", "subhub"],
                        "hub-verify" => ["contact", "hub-verify"],
                        "subhub" => ["ucontact", "subhub"],
                        "hub-verify" => ["ucontact", "hub-verify"],
                        "reason" => ["ucontact", "reason"],
-                       "dfrn-duplex" => ["ucontact", "duplex"],
-                       "dfrn-ret-aes" => ["ucontact", "ret-aes"],
-                       "dfrn-site-pubkey" => ["ucontact", "site-pubkey"],
-                       "dfrn-issued-id" => ["ucontact", "issued-id"],
-                       "dfrn-id" => ["ucontact", "dfrn-id"],
-                       "dfrn-aes_allow" => ["ucontact", "aes_allow"],
                        "dfrn-request" => ["contact", "request"],
                        "dfrn-notify" => ["contact", "notify"],
                        "dfrn-poll" => ["contact", "poll"],
index d4a43080eb5c63e62daf50bbcc1596e1d21000c3..127423df4caf21fc909d668a8666d38af42ed90d 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: 2021.09-dev\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-07-14 02:55+0000\n"
+"POT-Creation-Date: 2021-07-15 08:57+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -54,7 +54,7 @@ msgstr ""
 msgid "%1$s poked %2$s"
 msgstr ""
 
-#: include/conversation.php:138 src/Model/Item.php:2647
+#: include/conversation.php:138 src/Model/Item.php:2606
 msgid "event"
 msgstr ""
 
@@ -62,7 +62,7 @@ msgstr ""
 msgid "status"
 msgstr ""
 
-#: include/conversation.php:146 mod/tagger.php:90 src/Model/Item.php:2649
+#: include/conversation.php:146 mod/tagger.php:90 src/Model/Item.php:2608
 msgid "photo"
 msgstr ""
 
@@ -184,32 +184,32 @@ msgstr ""
 msgid "Follow Thread"
 msgstr ""
 
-#: include/conversation.php:852 src/Model/Contact.php:1045
+#: include/conversation.php:852 src/Model/Contact.php:1043
 msgid "View Status"
 msgstr ""
 
 #: include/conversation.php:853 include/conversation.php:875
-#: src/Model/Contact.php:971 src/Model/Contact.php:1037
-#: src/Model/Contact.php:1046 src/Module/Directory.php:166
+#: src/Model/Contact.php:969 src/Model/Contact.php:1035
+#: src/Model/Contact.php:1044 src/Module/Directory.php:166
 #: src/Module/Settings/Profile/Index.php:224
 msgid "View Profile"
 msgstr ""
 
-#: include/conversation.php:854 src/Model/Contact.php:1047
+#: include/conversation.php:854 src/Model/Contact.php:1045
 msgid "View Photos"
 msgstr ""
 
-#: include/conversation.php:855 src/Model/Contact.php:1038
-#: src/Model/Contact.php:1048
+#: include/conversation.php:855 src/Model/Contact.php:1036
+#: src/Model/Contact.php:1046
 msgid "Network Posts"
 msgstr ""
 
-#: include/conversation.php:856 src/Model/Contact.php:1039
-#: src/Model/Contact.php:1049
+#: include/conversation.php:856 src/Model/Contact.php:1037
+#: src/Model/Contact.php:1047
 msgid "View Contact"
 msgstr ""
 
-#: include/conversation.php:857 src/Model/Contact.php:1051
+#: include/conversation.php:857 src/Model/Contact.php:1049
 msgid "Send PM"
 msgstr ""
 
@@ -223,7 +223,7 @@ msgstr ""
 #: include/conversation.php:859 src/Module/Contact.php:634
 #: src/Module/Contact.php:892 src/Module/Contact.php:1181
 #: src/Module/Notifications/Introductions.php:113
-#: src/Module/Notifications/Introductions.php:191
+#: src/Module/Notifications/Introductions.php:185
 #: src/Module/Notifications/Notification.php:59
 msgid "Ignore"
 msgstr ""
@@ -232,12 +232,12 @@ msgstr ""
 msgid "Languages"
 msgstr ""
 
-#: include/conversation.php:867 src/Model/Contact.php:1052
+#: include/conversation.php:867 src/Model/Contact.php:1050
 msgid "Poke"
 msgstr ""
 
-#: include/conversation.php:872 mod/follow.php:146 src/Content/Widget.php:76
-#: src/Model/Contact.php:1040 src/Model/Contact.php:1053
+#: include/conversation.php:872 mod/follow.php:138 src/Content/Widget.php:76
+#: src/Model/Contact.php:1038 src/Model/Contact.php:1051
 #: view/theme/vier/theme.php:172
 msgid "Connect/Follow"
 msgstr ""
@@ -476,11 +476,10 @@ msgstr ""
 msgid "Preview"
 msgstr ""
 
-#: include/conversation.php:1145 mod/dfrn_request.php:642 mod/editpost.php:128
-#: mod/fbrowser.php:105 mod/fbrowser.php:134 mod/follow.php:152
-#: mod/photos.php:1036 mod/photos.php:1142 mod/tagrm.php:37 mod/tagrm.php:129
-#: mod/unfollow.php:100 src/Module/Contact.php:467
-#: src/Module/RemoteFollow.php:110
+#: include/conversation.php:1145 mod/editpost.php:128 mod/fbrowser.php:105
+#: mod/fbrowser.php:134 mod/follow.php:144 mod/photos.php:1036
+#: mod/photos.php:1142 mod/tagrm.php:37 mod/tagrm.php:129 mod/unfollow.php:97
+#: src/Module/Contact.php:467 src/Module/RemoteFollow.php:110
 msgid "Cancel"
 msgstr ""
 
@@ -823,17 +822,17 @@ msgstr ""
 msgid "Please visit %s to approve or reject the request."
 msgstr ""
 
-#: mod/api.php:52 mod/api.php:57 mod/dfrn_confirm.php:78 mod/editpost.php:37
-#: mod/events.php:231 mod/follow.php:55 mod/follow.php:135 mod/item.php:185
-#: mod/item.php:190 mod/item.php:917 mod/message.php:69 mod/message.php:112
-#: mod/notes.php:44 mod/ostatus_subscribe.php:32 mod/photos.php:175
-#: mod/photos.php:921 mod/repair_ostatus.php:31 mod/settings.php:47
-#: mod/settings.php:65 mod/settings.php:474 mod/suggest.php:34
-#: mod/uimport.php:32 mod/unfollow.php:35 mod/unfollow.php:50
-#: mod/unfollow.php:82 mod/wall_attach.php:78 mod/wall_attach.php:81
-#: mod/wall_upload.php:99 mod/wall_upload.php:102 mod/wallmessage.php:35
-#: mod/wallmessage.php:59 mod/wallmessage.php:96 mod/wallmessage.php:120
-#: src/Module/Attach.php:56 src/Module/BaseApi.php:81 src/Module/BaseApi.php:92
+#: mod/api.php:52 mod/api.php:57 mod/editpost.php:37 mod/events.php:231
+#: mod/follow.php:55 mod/follow.php:130 mod/item.php:185 mod/item.php:190
+#: mod/item.php:917 mod/message.php:69 mod/message.php:112 mod/notes.php:44
+#: mod/ostatus_subscribe.php:32 mod/photos.php:175 mod/photos.php:921
+#: mod/repair_ostatus.php:31 mod/settings.php:47 mod/settings.php:65
+#: mod/settings.php:474 mod/suggest.php:34 mod/uimport.php:32
+#: mod/unfollow.php:35 mod/unfollow.php:50 mod/unfollow.php:82
+#: mod/wall_attach.php:78 mod/wall_attach.php:81 mod/wall_upload.php:99
+#: mod/wall_upload.php:102 mod/wallmessage.php:35 mod/wallmessage.php:59
+#: mod/wallmessage.php:96 mod/wallmessage.php:120 src/Module/Attach.php:56
+#: src/Module/BaseApi.php:81 src/Module/BaseApi.php:92
 #: src/Module/BaseApi.php:103 src/Module/BaseApi.php:114
 #: src/Module/BaseNotifications.php:88 src/Module/Contact.php:385
 #: src/Module/Contact/Advanced.php:43 src/Module/Delegation.php:118
@@ -886,7 +885,7 @@ msgid "No"
 msgstr ""
 
 #: mod/cal.php:46 mod/cal.php:50 mod/follow.php:38 mod/redir.php:34
-#: mod/redir.php:203 src/Module/Conversation/Community.php:194
+#: mod/redir.php:176 src/Module/Conversation/Community.php:194
 #: src/Module/Debug/ItemBody.php:38 src/Module/Diaspora/Receive.php:51
 #: src/Module/Item/Follow.php:42 src/Module/Item/Ignore.php:41
 #: src/Module/Item/Pin.php:42 src/Module/Item/Pin.php:57
@@ -968,253 +967,13 @@ msgstr ""
 msgid "calendar"
 msgstr ""
 
-#: mod/dfrn_confirm.php:84 src/Module/Profile/Profile.php:82
-msgid "Profile not found."
-msgstr ""
-
-#: mod/dfrn_confirm.php:139 mod/redir.php:56 mod/redir.php:157
-#: src/Module/Contact/Advanced.php:53 src/Module/Contact/Advanced.php:104
-#: src/Module/Contact/Contacts.php:36 src/Module/FriendSuggest.php:54
-#: src/Module/FriendSuggest.php:93 src/Module/Group.php:105
-msgid "Contact not found."
-msgstr ""
-
-#: mod/dfrn_confirm.php:140
-msgid ""
-"This may occasionally happen if contact was requested by both persons and it "
-"has already been approved."
-msgstr ""
-
-#: mod/dfrn_confirm.php:241
-msgid "Response from remote site was not understood."
-msgstr ""
-
-#: mod/dfrn_confirm.php:248 mod/dfrn_confirm.php:254
-msgid "Unexpected response from remote site: "
-msgstr ""
-
-#: mod/dfrn_confirm.php:263
-msgid "Confirmation completed successfully."
-msgstr ""
-
-#: mod/dfrn_confirm.php:275
-msgid "Temporary failure. Please wait and try again."
-msgstr ""
-
-#: mod/dfrn_confirm.php:278
-msgid "Introduction failed or was revoked."
-msgstr ""
-
-#: mod/dfrn_confirm.php:283
-msgid "Remote site reported: "
-msgstr ""
-
-#: mod/dfrn_confirm.php:388
-#, php-format
-msgid "No user record found for '%s' "
-msgstr ""
-
-#: mod/dfrn_confirm.php:398
-msgid "Our site encryption key is apparently messed up."
-msgstr ""
-
-#: mod/dfrn_confirm.php:409
-msgid "Empty site URL was provided or URL could not be decrypted by us."
-msgstr ""
-
-#: mod/dfrn_confirm.php:425
-msgid "Contact record was not found for you on our site."
-msgstr ""
-
-#: mod/dfrn_confirm.php:439
-#, php-format
-msgid "Site public key not available in contact record for URL %s."
-msgstr ""
-
-#: mod/dfrn_confirm.php:455
-msgid ""
-"The ID provided by your system is a duplicate on our system. It should work "
-"if you try again."
-msgstr ""
-
-#: mod/dfrn_confirm.php:466
-msgid "Unable to set your contact credentials on our system."
-msgstr ""
-
-#: mod/dfrn_confirm.php:522
-msgid "Unable to update your contact profile details on our system"
-msgstr ""
-
-#: mod/dfrn_poll.php:136 mod/dfrn_poll.php:509
-#, php-format
-msgid "%1$s welcomes %2$s"
-msgstr ""
-
-#: mod/dfrn_request.php:113
-msgid "This introduction has already been accepted."
-msgstr ""
-
-#: mod/dfrn_request.php:131 mod/dfrn_request.php:369
-msgid "Profile location is not valid or does not contain profile information."
-msgstr ""
-
-#: mod/dfrn_request.php:135 mod/dfrn_request.php:373
-msgid "Warning: profile location has no identifiable owner name."
-msgstr ""
-
-#: mod/dfrn_request.php:138 mod/dfrn_request.php:376
-msgid "Warning: profile location has no profile photo."
-msgstr ""
-
-#: mod/dfrn_request.php:142 mod/dfrn_request.php:380
-#, php-format
-msgid "%d required parameter was not found at the given location"
-msgid_plural "%d required parameters were not found at the given location"
-msgstr[0] ""
-msgstr[1] ""
-
-#: mod/dfrn_request.php:180
-msgid "Introduction complete."
-msgstr ""
-
-#: mod/dfrn_request.php:216
-msgid "Unrecoverable protocol error."
-msgstr ""
-
-#: mod/dfrn_request.php:243 src/Module/RemoteFollow.php:54
-msgid "Profile unavailable."
-msgstr ""
-
-#: mod/dfrn_request.php:264
-#, php-format
-msgid "%s has received too many connection requests today."
-msgstr ""
-
-#: mod/dfrn_request.php:265
-msgid "Spam protection measures have been invoked."
-msgstr ""
-
-#: mod/dfrn_request.php:266
-msgid "Friends are advised to please try again in 24 hours."
-msgstr ""
-
-#: mod/dfrn_request.php:290 src/Module/RemoteFollow.php:60
-msgid "Invalid locator"
-msgstr ""
-
-#: mod/dfrn_request.php:326
-msgid "You have already introduced yourself here."
-msgstr ""
-
-#: mod/dfrn_request.php:329
-#, php-format
-msgid "Apparently you are already friends with %s."
-msgstr ""
-
-#: mod/dfrn_request.php:349
-msgid "Invalid profile URL."
-msgstr ""
-
-#: mod/dfrn_request.php:355 src/Model/Contact.php:2341
-msgid "Disallowed profile URL."
-msgstr ""
-
-#: mod/dfrn_request.php:361 src/Model/Contact.php:2346
-#: src/Module/Friendica.php:80
-msgid "Blocked domain"
-msgstr ""
-
-#: mod/dfrn_request.php:428 src/Module/Contact.php:157
-msgid "Failed to update contact record."
-msgstr ""
-
-#: mod/dfrn_request.php:448
-msgid "Your introduction has been sent."
-msgstr ""
-
-#: mod/dfrn_request.php:480 src/Module/RemoteFollow.php:72
-msgid ""
-"Remote subscription can't be done for your network. Please subscribe "
-"directly on your system."
-msgstr ""
-
-#: mod/dfrn_request.php:496
-msgid "Please login to confirm introduction."
-msgstr ""
-
-#: mod/dfrn_request.php:504
-msgid ""
-"Incorrect identity currently logged in. Please login to <strong>this</"
-"strong> profile."
-msgstr ""
-
-#: mod/dfrn_request.php:518 mod/dfrn_request.php:533
-msgid "Confirm"
-msgstr ""
-
-#: mod/dfrn_request.php:529
-msgid "Hide this contact"
-msgstr ""
-
-#: mod/dfrn_request.php:531
-#, php-format
-msgid "Welcome home %s."
-msgstr ""
-
-#: mod/dfrn_request.php:532
-#, php-format
-msgid "Please confirm your introduction/connection request to %s."
-msgstr ""
-
-#: mod/dfrn_request.php:600 mod/display.php:179 mod/photos.php:835
-#: mod/videos.php:128 src/Module/Conversation/Community.php:188
-#: src/Module/Debug/Probe.php:39 src/Module/Debug/WebFinger.php:38
-#: src/Module/Directory.php:49 src/Module/Search/Index.php:50
-#: src/Module/Search/Index.php:55
+#: mod/display.php:179 mod/photos.php:835 mod/videos.php:128
+#: src/Module/Conversation/Community.php:188 src/Module/Debug/Probe.php:39
+#: src/Module/Debug/WebFinger.php:38 src/Module/Directory.php:49
+#: src/Module/Search/Index.php:50 src/Module/Search/Index.php:55
 msgid "Public access denied."
 msgstr ""
 
-#: mod/dfrn_request.php:636 src/Module/RemoteFollow.php:104
-msgid "Friend/Connection Request"
-msgstr ""
-
-#: mod/dfrn_request.php:637
-#, php-format
-msgid ""
-"Enter your Webfinger address (user@domain.tld) or profile URL here. If this "
-"isn't supported by your system (for example it doesn't work with Diaspora), "
-"you have to subscribe to <strong>%s</strong> directly on your system"
-msgstr ""
-
-#: mod/dfrn_request.php:638 src/Module/RemoteFollow.php:106
-#, php-format
-msgid ""
-"If you are not yet a member of the free social web, <a href=\"%s\">follow "
-"this link to find a public Friendica node and join us today</a>."
-msgstr ""
-
-#: mod/dfrn_request.php:639 src/Module/RemoteFollow.php:107
-msgid "Your Webfinger address or profile URL:"
-msgstr ""
-
-#: mod/dfrn_request.php:640 mod/follow.php:147 src/Module/RemoteFollow.php:108
-msgid "Please answer the following:"
-msgstr ""
-
-#: mod/dfrn_request.php:641 mod/follow.php:74 mod/unfollow.php:99
-#: src/Module/RemoteFollow.php:109
-msgid "Submit Request"
-msgstr ""
-
-#: mod/dfrn_request.php:648 mod/follow.php:161
-#, php-format
-msgid "%s knows you"
-msgstr ""
-
-#: mod/dfrn_request.php:649 mod/follow.php:162
-msgid "Add a personal note:"
-msgstr ""
-
 #: mod/display.php:235 mod/display.php:320
 msgid "The requested item doesn't exist or has been deleted."
 msgstr ""
@@ -1331,7 +1090,7 @@ msgstr ""
 #: mod/events.php:563 src/Model/Event.php:86 src/Model/Event.php:113
 #: src/Model/Event.php:475 src/Model/Event.php:962 src/Model/Profile.php:420
 #: src/Module/Contact.php:654 src/Module/Directory.php:156
-#: src/Module/Notifications/Introductions.php:172
+#: src/Module/Notifications/Introductions.php:166
 #: src/Module/Profile/Profile.php:190
 msgid "Location:"
 msgstr ""
@@ -1389,6 +1148,10 @@ msgstr ""
 msgid "Files"
 msgstr ""
 
+#: mod/follow.php:74 mod/unfollow.php:96 src/Module/RemoteFollow.php:109
+msgid "Submit Request"
+msgstr ""
+
 #: mod/follow.php:84
 msgid "You already added this contact."
 msgstr ""
@@ -1405,29 +1168,42 @@ msgstr ""
 msgid "OStatus support is disabled. Contact can't be added."
 msgstr ""
 
-#: mod/follow.php:148 mod/unfollow.php:97
+#: mod/follow.php:139 src/Module/RemoteFollow.php:108
+msgid "Please answer the following:"
+msgstr ""
+
+#: mod/follow.php:140 mod/unfollow.php:94
 msgid "Your Identity Address:"
 msgstr ""
 
-#: mod/follow.php:149 mod/unfollow.php:103
+#: mod/follow.php:141 mod/unfollow.php:100
 #: src/Module/Admin/Blocklist/Contact.php:100 src/Module/Contact.php:650
 #: src/Module/Notifications/Introductions.php:108
-#: src/Module/Notifications/Introductions.php:183
+#: src/Module/Notifications/Introductions.php:177
 msgid "Profile URL"
 msgstr ""
 
-#: mod/follow.php:150 src/Module/Contact.php:660
-#: src/Module/Notifications/Introductions.php:176
+#: mod/follow.php:142 src/Module/Contact.php:660
+#: src/Module/Notifications/Introductions.php:170
 #: src/Module/Profile/Profile.php:203
 msgid "Tags:"
 msgstr ""
 
-#: mod/follow.php:171 mod/unfollow.php:113 src/Module/BaseProfile.php:63
+#: mod/follow.php:153
+#, php-format
+msgid "%s knows you"
+msgstr ""
+
+#: mod/follow.php:154
+msgid "Add a personal note:"
+msgstr ""
+
+#: mod/follow.php:163 mod/unfollow.php:110 src/Module/BaseProfile.php:63
 #: src/Module/Contact.php:939
 msgid "Status Messages and Posts"
 msgstr ""
 
-#: mod/follow.php:203
+#: mod/follow.php:191
 msgid "The contact could not be added."
 msgstr ""
 
@@ -1628,7 +1404,7 @@ msgid "Message collection failure."
 msgstr ""
 
 #: mod/message.php:121 src/Module/Notifications/Introductions.php:114
-#: src/Module/Notifications/Introductions.php:155
+#: src/Module/Notifications/Introductions.php:149
 #: src/Module/Notifications/Notification.php:56
 msgid "Discard"
 msgstr ""
@@ -2033,10 +1809,17 @@ msgstr ""
 msgid "{0} and %d others requested registration"
 msgstr ""
 
-#: mod/redir.php:50 mod/redir.php:130
+#: mod/redir.php:50 mod/redir.php:103
 msgid "Bad Request."
 msgstr ""
 
+#: mod/redir.php:56 mod/redir.php:130 src/Module/Contact/Advanced.php:53
+#: src/Module/Contact/Advanced.php:104 src/Module/Contact/Contacts.php:36
+#: src/Module/FriendSuggest.php:54 src/Module/FriendSuggest.php:93
+#: src/Module/Group.php:105
+msgid "Contact not found."
+msgstr ""
+
 #: mod/removeme.php:63
 msgid "User deleted their account"
 msgstr ""
@@ -2912,15 +2695,15 @@ msgid ""
 "select \"Export account\""
 msgstr ""
 
-#: mod/unfollow.php:65 mod/unfollow.php:133
+#: mod/unfollow.php:65 mod/unfollow.php:130
 msgid "You aren't following this contact."
 msgstr ""
 
-#: mod/unfollow.php:71 mod/unfollow.php:139
+#: mod/unfollow.php:71 mod/unfollow.php:136
 msgid "Unfollowing is currently not supported by your network."
 msgstr ""
 
-#: mod/unfollow.php:95
+#: mod/unfollow.php:92
 msgid "Disconnect/Unfollow"
 msgstr ""
 
@@ -3652,8 +3435,8 @@ msgid ""
 "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
 msgstr ""
 
-#: src/Content/Text/BBCode.php:1108 src/Model/Item.php:3175
-#: src/Model/Item.php:3181 src/Model/Item.php:3182
+#: src/Content/Text/BBCode.php:1108 src/Model/Item.php:3134
+#: src/Model/Item.php:3140 src/Model/Item.php:3141
 msgid "Link to source"
 msgstr ""
 
@@ -3808,7 +3591,7 @@ msgstr ""
 msgid "Organisations"
 msgstr ""
 
-#: src/Content/Widget.php:532 src/Model/Contact.php:1469
+#: src/Content/Widget.php:532 src/Model/Contact.php:1467
 msgid "News"
 msgstr ""
 
@@ -4629,82 +4412,85 @@ msgstr ""
 msgid "Legacy module file not found: %s"
 msgstr ""
 
-#: src/Model/Contact.php:1041 src/Model/Contact.php:1054
+#: src/Model/Contact.php:1039 src/Model/Contact.php:1052
 msgid "UnFollow"
 msgstr ""
 
-#: src/Model/Contact.php:1050
+#: src/Model/Contact.php:1048
 msgid "Drop Contact"
 msgstr ""
 
-#: src/Model/Contact.php:1060 src/Module/Admin/Users/Pending.php:107
+#: src/Model/Contact.php:1058 src/Module/Admin/Users/Pending.php:107
 #: src/Module/Notifications/Introductions.php:111
-#: src/Module/Notifications/Introductions.php:189
+#: src/Module/Notifications/Introductions.php:183
 msgid "Approve"
 msgstr ""
 
-#: src/Model/Contact.php:1465
+#: src/Model/Contact.php:1463
 msgid "Organisation"
 msgstr ""
 
-#: src/Model/Contact.php:1473
+#: src/Model/Contact.php:1471
 msgid "Forum"
 msgstr ""
 
-#: src/Model/Contact.php:2351
+#: src/Model/Contact.php:2327
+msgid "Disallowed profile URL."
+msgstr ""
+
+#: src/Model/Contact.php:2332 src/Module/Friendica.php:80
+msgid "Blocked domain"
+msgstr ""
+
+#: src/Model/Contact.php:2337
 msgid "Connect URL missing."
 msgstr ""
 
-#: src/Model/Contact.php:2360
+#: src/Model/Contact.php:2346
 msgid ""
 "The contact could not be added. Please check the relevant network "
 "credentials in your Settings -> Social Networks page."
 msgstr ""
 
-#: src/Model/Contact.php:2403
-msgid ""
-"This site is not configured to allow communications with other networks."
+#: src/Model/Contact.php:2383
+msgid "The profile address specified does not provide adequate information."
 msgstr ""
 
-#: src/Model/Contact.php:2404 src/Model/Contact.php:2417
+#: src/Model/Contact.php:2385
 msgid "No compatible communication protocols or feeds were discovered."
 msgstr ""
 
-#: src/Model/Contact.php:2415
-msgid "The profile address specified does not provide adequate information."
-msgstr ""
-
-#: src/Model/Contact.php:2420
+#: src/Model/Contact.php:2388
 msgid "An author or name was not found."
 msgstr ""
 
-#: src/Model/Contact.php:2423
+#: src/Model/Contact.php:2391
 msgid "No browser URL could be matched to this address."
 msgstr ""
 
-#: src/Model/Contact.php:2426
+#: src/Model/Contact.php:2394
 msgid ""
 "Unable to match @-style Identity Address with a known protocol or email "
 "contact."
 msgstr ""
 
-#: src/Model/Contact.php:2427
+#: src/Model/Contact.php:2395
 msgid "Use mailto: in front of address to force email check."
 msgstr ""
 
-#: src/Model/Contact.php:2433
+#: src/Model/Contact.php:2401
 msgid ""
 "The profile address specified belongs to a network which has been disabled "
 "on this site."
 msgstr ""
 
-#: src/Model/Contact.php:2438
+#: src/Model/Contact.php:2406
 msgid ""
 "Limited profile. This person will be unable to receive direct/personal "
 "notifications from you."
 msgstr ""
 
-#: src/Model/Contact.php:2497
+#: src/Model/Contact.php:2465
 msgid "Unable to retrieve contact information."
 msgstr ""
 
@@ -4821,33 +4607,33 @@ msgstr ""
 msgid "Edit groups"
 msgstr ""
 
-#: src/Model/Item.php:1701
+#: src/Model/Item.php:1660
 #, php-format
 msgid "Detected languages in this post:\\n%s"
 msgstr ""
 
-#: src/Model/Item.php:2651
+#: src/Model/Item.php:2610
 msgid "activity"
 msgstr ""
 
-#: src/Model/Item.php:2653
+#: src/Model/Item.php:2612
 msgid "comment"
 msgstr ""
 
-#: src/Model/Item.php:2656
+#: src/Model/Item.php:2615
 msgid "post"
 msgstr ""
 
-#: src/Model/Item.php:2770
+#: src/Model/Item.php:2729
 #, php-format
 msgid "Content warning: %s"
 msgstr ""
 
-#: src/Model/Item.php:3140
+#: src/Model/Item.php:3099
 msgid "bytes"
 msgstr ""
 
-#: src/Model/Item.php:3169 src/Model/Item.php:3170
+#: src/Model/Item.php:3128 src/Model/Item.php:3129
 msgid "View on separate page"
 msgstr ""
 
@@ -4870,7 +4656,7 @@ msgid "Homepage:"
 msgstr ""
 
 #: src/Model/Profile.php:424 src/Module/Contact.php:658
-#: src/Module/Notifications/Introductions.php:174
+#: src/Module/Notifications/Introductions.php:168
 msgid "About:"
 msgstr ""
 
@@ -4888,7 +4674,7 @@ msgid "Atom feed"
 msgstr ""
 
 #: src/Model/Profile.php:516 src/Module/Contact.php:338
-#: src/Module/Notifications/Introductions.php:186
+#: src/Module/Notifications/Introductions.php:180
 msgid "Network:"
 msgstr ""
 
@@ -7393,6 +7179,10 @@ msgstr[1] ""
 msgid "Could not access contact record."
 msgstr ""
 
+#: src/Module/Contact.php:157
+msgid "Failed to update contact record."
+msgstr ""
+
 #: src/Module/Contact.php:417
 msgid "You can't block yourself"
 msgstr ""
@@ -7592,7 +7382,7 @@ msgstr ""
 msgid "Awaiting connection acknowledge"
 msgstr ""
 
-#: src/Module/Contact.php:642 src/Module/Notifications/Introductions.php:177
+#: src/Module/Contact.php:642 src/Module/Notifications/Introductions.php:171
 msgid "Hide this contact from others"
 msgstr ""
 
@@ -8781,7 +8571,7 @@ msgid "Hide Ignored Requests"
 msgstr ""
 
 #: src/Module/Notifications/Introductions.php:94
-#: src/Module/Notifications/Introductions.php:163
+#: src/Module/Notifications/Introductions.php:157
 msgid "Notification type:"
 msgstr ""
 
@@ -8819,11 +8609,11 @@ msgstr ""
 msgid "Subscriber"
 msgstr ""
 
-#: src/Module/Notifications/Introductions.php:201
+#: src/Module/Notifications/Introductions.php:195
 msgid "No introductions."
 msgstr ""
 
-#: src/Module/Notifications/Introductions.php:202
+#: src/Module/Notifications/Introductions.php:196
 #: src/Module/Notifications/Notifications.php:133
 #, php-format
 msgid "No more %s notifications."
@@ -8907,6 +8697,10 @@ msgstr ""
 msgid "No contacts."
 msgstr ""
 
+#: src/Module/Profile/Profile.php:82
+msgid "Profile not found."
+msgstr ""
+
 #: src/Module/Profile/Profile.php:135
 #, php-format
 msgid ""
@@ -9108,10 +8902,28 @@ msgstr ""
 msgid "Your registration is pending approval by the site owner."
 msgstr ""
 
+#: src/Module/RemoteFollow.php:54
+msgid "Profile unavailable."
+msgstr ""
+
+#: src/Module/RemoteFollow.php:60
+msgid "Invalid locator"
+msgstr ""
+
 #: src/Module/RemoteFollow.php:67
 msgid "The provided profile link doesn't seem to be valid"
 msgstr ""
 
+#: src/Module/RemoteFollow.php:72
+msgid ""
+"Remote subscription can't be done for your network. Please subscribe "
+"directly on your system."
+msgstr ""
+
+#: src/Module/RemoteFollow.php:104
+msgid "Friend/Connection Request"
+msgstr ""
+
 #: src/Module/RemoteFollow.php:105
 #, php-format
 msgid ""
@@ -9120,6 +8932,17 @@ msgid ""
 "or <strong>%s</strong> directly on your system."
 msgstr ""
 
+#: src/Module/RemoteFollow.php:106
+#, php-format
+msgid ""
+"If you are not yet a member of the free social web, <a href=\"%s\">follow "
+"this link to find a public Friendica node and join us today</a>."
+msgstr ""
+
+#: src/Module/RemoteFollow.php:107
+msgid "Your Webfinger address or profile URL:"
+msgstr ""
+
 #: src/Module/Search/Index.php:54
 msgid "Only logged in users are permitted to perform a search."
 msgstr ""
@@ -10465,7 +10288,7 @@ msgstr ""
 msgid "Show fewer"
 msgstr ""
 
-#: src/Protocol/Diaspora.php:3435
+#: src/Protocol/Diaspora.php:3434
 msgid "Attachments:"
 msgstr ""
 
@@ -10673,7 +10496,7 @@ msgstr ""
 msgid "%1$d %2$s ago"
 msgstr ""
 
-#: src/Worker/Delivery.php:529
+#: src/Worker/Delivery.php:521
 msgid "(no subject)"
 msgstr ""
 
diff --git a/view/templates/dfrn_req_confirm.tpl b/view/templates/dfrn_req_confirm.tpl
deleted file mode 100644 (file)
index 2e586ec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-<p id="dfrn-request-homecoming">
-{{$welcome}}
-<br />
-{{$please}}
-
-</p>
-<form id="dfrn-request-homecoming-form" action="dfrn_request/{{$nickname}}" method="post"> 
-<input type="hidden" name="dfrn_url" value="{{$dfrn_url}}" />
-<input type="hidden" name="confirm_key" value="{{$confirm_key}}" />
-<input type="hidden" name="localconfirm" value="1" />
-{{$aes_allow nofilter}}
-
-<label id="dfrn-request-homecoming-hide-label" for="dfrn-request-homecoming-hide">{{$hidethem}}</label>
-<input type="checkbox" name="hidden-contact" value="1" />
-
-
-<div id="dfrn-request-homecoming-submit-wrapper">
-<input id="dfrn-request-homecoming-submit" type="submit" name="submit" value="{{$submit}}" />
-</div>
-</form>
\ No newline at end of file
diff --git a/view/templates/dfrn_request.tpl b/view/templates/dfrn_request.tpl
deleted file mode 100644 (file)
index f1ef7c4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<h1>{{$header}}</h1>
-
-{{if !$myaddr}}
-<p id="dfrn-request-intro">
-       {{$page_desc nofilter}}
-</p>
-<p>
-       {{$invite_desc nofilter}}
-</p>
-{{/if}}
-
-<form action="{{$request}}" method="post">
-       <div id="dfrn-request-url-wrapper">
-               <label id="dfrn-url-label" for="dfrn-url">{{$your_address}}</label>
-{{if $myaddr}}
-               {{$myaddr}}
-               <input type="hidden" name="dfrn_url" id="dfrn-url" value="{{$myaddr}}">
-{{else}}
-               <input type="text" name="dfrn_url" id="dfrn-url" size="32" value="{{$myaddr}}">
-{{/if}}
-               <div id="dfrn-request-url-end"></div>
-       </div>
-
-       <p id="dfrn-request-options">
-               {{$pls_answer}}
-       </p>
-
-       <div id="dfrn-request-info-wrapper">
-               {{include file="field_checkbox.tpl" field=$does_know_you}}
-
-               {{include file="field_textarea.tpl" field=$addnote_field}}
-       </div>
-
-       <div id="dfrn-request-submit-wrapper">
-               <input type="submit" name="submit" id="dfrn-request-submit-button" value="{{$submit}}">
-               <input type="submit" name="cancel" id="dfrn-request-cancel-button" value="{{$cancel}}">
-       </div>
-</form>
diff --git a/view/theme/frio/templates/dfrn_request.tpl b/view/theme/frio/templates/dfrn_request.tpl
deleted file mode 100644 (file)
index 65f84fd..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<div class="generic-page-wrapper">
-       <h1>{{$header}}</h1>
-
-{{if !$myaddr}}
-       <p id="dfrn-request-intro">
-               {{$page_desc nofilter}}
-       </p>
-       <p>
-               {{$invite_desc nofilter}}
-       </p>
-{{/if}}
-
-       <form action="{{$request}}" method="post">
-               <div id="dfrn-request-url-wrapper">
-                       <label id="dfrn-url-label" for="dfrn-url">{{$your_address}}</label>
-{{if $myaddr}}
-                       {{$myaddr}}
-                       <input type="hidden" name="dfrn_url" id="dfrn-url" value="{{$myaddr}}">
-{{else}}
-                       <input type="text" name="dfrn_url" id="dfrn-url" size="32" value="{{$myaddr}}">
-{{/if}}
-                       <div id="dfrn-request-url-end"></div>
-               </div>
-
-               <p id="dfrn-request-options">
-                       {{$pls_answer}}
-               </p>
-
-               <div id="dfrn-request-info-wrapper">
-                       {{include file="field_checkbox.tpl" field=$does_know_you}}
-
-                       {{include file="field_textarea.tpl" field=$addnote_field}}
-               </div>
-
-               <div id="dfrn-request-submit-wrapper">
-                       <input class="btn btn-primary" type="submit" name="submit" id="dfrn-request-submit-button" value="{{$submit}}">
-                       <input class="btn btn-default" type="submit" name="cancel" id="dfrn-request-cancel-button" value="{{$cancel}}">
-               </div>
-       </form>
-</div>