3 * @copyright Copyright (C) 2010-2021, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Model\Contact;
24 use Friendica\Contact\Introduction\Entity;
25 use Friendica\Core\Protocol;
27 use Friendica\Network\HTTPException;
28 use Friendica\Model\Contact;
29 use Friendica\Model\User;
30 use Friendica\Protocol\ActivityPub;
31 use Friendica\Protocol\Diaspora;
32 use Friendica\Util\DateTimeFormat;
37 * Confirms a follow request and sends a notice to the remote contact.
39 * @param Entity\Introduction $introduction
41 * @throws HTTPException\InternalServerErrorException
42 * @throws HTTPException\NotFoundException
43 * @throws \ImagickException
45 public static function confirm(Entity\Introduction $introduction): void
47 DI::logger()->info('Confirming follower', ['cid' => $introduction->cid]);
49 $contact = Contact::selectFirst([], ['id' => $introduction->cid, 'uid' => $introduction->uid]);
52 throw new HTTPException\NotFoundException('Contact record not found.');
55 $newRelation = $contact['rel'];
56 $writable = $contact['writable'];
58 if (!empty($contact['protocol'])) {
59 $protocol = $contact['protocol'];
61 $protocol = $contact['network'];
64 if ($protocol == Protocol::ACTIVITYPUB) {
65 ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $contact['uid']);
68 if (in_array($protocol, [Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
69 if ($introduction->duplex) {
70 $newRelation = Contact::FRIEND;
72 $newRelation = Contact::FOLLOWER;
75 if ($newRelation != Contact::FOLLOWER) {
81 'name-date' => DateTimeFormat::utcNow(),
82 'uri-date' => DateTimeFormat::utcNow(),
85 'protocol' => $protocol,
86 'writable' => $writable,
87 'hidden' => $hidden ?? $contact['hidden'],
88 'rel' => $newRelation,
90 Contact::update($fields, ['id' => $contact['id']]);
92 array_merge($contact, $fields);
94 if ($newRelation == Contact::FRIEND) {
95 if ($protocol == Protocol::DIASPORA) {
96 $ret = Diaspora::sendShare(User::getById($contact['uid']), $contact);
97 DI::logger()->info('share returns', ['return' => $ret]);
98 } elseif ($protocol == Protocol::ACTIVITYPUB) {
99 ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $contact['uid']);
105 * Discards the introduction and sends a rejection message to AP contacts.
107 * @param Entity\Introduction $introduction
109 * @throws HTTPException\InternalServerErrorException
110 * @throws \ImagickException
112 public static function discard(Entity\Introduction $introduction): void
114 $contact = Contact::selectFirst([], ['id' => $introduction->cid, 'uid' => $introduction->uid]);
115 if (!empty($contact)) {
116 if (!empty($contact['protocol'])) {
117 $protocol = $contact['protocol'];
119 $protocol = $contact['network'];
122 if ($protocol == Protocol::ACTIVITYPUB) {
123 ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $contact['uid']);