mirror of
https://github.com/friendica/friendica
synced 2025-04-22 03:50:11 +00:00
Merge branch 'master' 2019.12 into develop
This commit is contained in:
commit
00756737b5
66 changed files with 70843 additions and 67948 deletions
|
@ -2,11 +2,13 @@
|
|||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
|
||||
use Friendica\Api\Mastodon\Account;
|
||||
use Friendica\Api\Mastodon;
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\APContact;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Introduction;
|
||||
use Friendica\Module\Base\Api;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
||||
|
@ -19,7 +21,40 @@ class FollowRequests extends Api
|
|||
{
|
||||
parent::init($parameters);
|
||||
|
||||
self::login();
|
||||
if (!self::login()) {
|
||||
throw new HTTPException\UnauthorizedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static function post(array $parameters = [])
|
||||
{
|
||||
parent::post($parameters);
|
||||
|
||||
/** @var Introduction $Intro */
|
||||
$Intro = self::getClass(Introduction::class);
|
||||
$Intro->fetch(['id' => $parameters['id'], 'uid' => self::$current_user_id]);
|
||||
|
||||
$contactId = $Intro->{'contact-id'};
|
||||
|
||||
$relationship = new Mastodon\Relationship();
|
||||
$relationship->id = $contactId;
|
||||
|
||||
switch ($parameters['action']) {
|
||||
case 'authorize':
|
||||
$Intro->confirm();
|
||||
$relationship = Mastodon\Relationship::createFromContact(Contact::getById($contactId));
|
||||
break;
|
||||
case 'ignore':
|
||||
$Intro->ignore();
|
||||
break;
|
||||
case 'reject':
|
||||
$Intro->discard();
|
||||
break;
|
||||
default:
|
||||
throw new HTTPException\BadRequestException('Unexpected action parameter, expecting "authorize", "ignore" or "reject"');
|
||||
}
|
||||
|
||||
System::jsonExit($relationship);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,26 +69,32 @@ class FollowRequests extends Api
|
|||
$limit = intval($_GET['limit'] ?? 40);
|
||||
|
||||
if (isset($since_id) && isset($max_id)) {
|
||||
$condition = ['`uid` = ? AND NOT `self` AND `pending` AND `id` > ? AND `id` < ?', self::$current_user_id, $since_id, $max_id];
|
||||
$condition = ['`uid` = ? AND NOT `ignore` AND `id` > ? AND `id` < ?', self::$current_user_id, $since_id, $max_id];
|
||||
} elseif (isset($since_id)) {
|
||||
$condition = ['`uid` = ? AND NOT `self` AND `pending` AND `id` > ?', self::$current_user_id, $since_id];
|
||||
$condition = ['`uid` = ? AND NOT `ignore` AND `id` > ?', self::$current_user_id, $since_id];
|
||||
} elseif (isset($max_id)) {
|
||||
$condition = ['`uid` = ? AND NOT `self` AND `pending` AND `id` < ?', self::$current_user_id, $max_id];
|
||||
$condition = ['`uid` = ? AND NOT `ignore` AND `id` < ?', self::$current_user_id, $max_id];
|
||||
} else {
|
||||
$condition = ['`uid` = ? AND NOT `self` AND `pending`', self::$current_user_id];
|
||||
$condition = ['`uid` = ? AND NOT `ignore`', self::$current_user_id];
|
||||
}
|
||||
|
||||
$count = DBA::count('contact', $condition);
|
||||
$count = DBA::count('intro', $condition);
|
||||
|
||||
$contacts = Contact::selectToArray(
|
||||
$intros = DBA::selectToArray(
|
||||
'intro',
|
||||
[],
|
||||
$condition,
|
||||
['order' => ['id' => 'DESC'], 'limit' => $limit]
|
||||
);
|
||||
|
||||
$return = [];
|
||||
foreach ($contacts as $contact) {
|
||||
$account = Account::createFromContact($contact);
|
||||
foreach ($intros as $intro) {
|
||||
$contact = Contact::getById($intro['contact-id']);
|
||||
$apcontact = APContact::getByURL($contact['url'], false);
|
||||
$account = Mastodon\Account::createFromContact($contact, $apcontact);
|
||||
|
||||
// Not ideal, the same "account" can have multiple ids depending on the context
|
||||
$account->id = $intro['id'];
|
||||
|
||||
$return[] = $account;
|
||||
}
|
||||
|
@ -68,9 +109,9 @@ class FollowRequests extends Api
|
|||
|
||||
$links = [];
|
||||
if ($count > $limit) {
|
||||
$links[] = '<' . $BaseURL->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['max_id' => $contacts[count($contacts) - 1]['id']]) . '>; rel="next"';
|
||||
$links[] = '<' . $BaseURL->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['max_id' => $intros[count($intros) - 1]['id']]) . '>; rel="next"';
|
||||
}
|
||||
$links[] = '<' . $BaseURL->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['since_id' => $contacts[0]['id']]) . '>; rel="prev"';
|
||||
$links[] = '<' . $BaseURL->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['since_id' => $intros[0]['id']]) . '>; rel="prev"';
|
||||
|
||||
header('Link: ' . implode(', ', $links));
|
||||
|
||||
|
|
22
src/Module/Api/Mastodon/Instance.php
Normal file
22
src/Module/Api/Mastodon/Instance.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
|
||||
use Friendica\Api\Mastodon\Instance as InstanceEntity;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Module\Base\Api;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/api/rest/instances/
|
||||
*/
|
||||
class Instance extends Api
|
||||
{
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
System::jsonExit(InstanceEntity::get(self::getApp()));
|
||||
}
|
||||
}
|
36
src/Module/Api/Mastodon/Instance/Peers.php
Normal file
36
src/Module/Api/Mastodon/Instance/Peers.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Instance;
|
||||
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Module\Base\Api;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Util\Network;
|
||||
|
||||
/**
|
||||
* Undocumented API endpoint that is implemented by both Mastodon and Pleroma
|
||||
*/
|
||||
class Peers extends Api
|
||||
{
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function rawContent(array $parameters = [])
|
||||
{
|
||||
$return = [];
|
||||
|
||||
// We only select for Friendica and ActivityPub servers, since it is expected to only deliver AP compatible systems here.
|
||||
$instances = DBA::select('gserver', ['url'], ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]);
|
||||
while ($instance = DBA::fetch($instances)) {
|
||||
$urldata = parse_url($instance['url']);
|
||||
unset($urldata['scheme']);
|
||||
$return[] = ltrim(Network::unparseURL($urldata), '/');
|
||||
}
|
||||
DBA::close($instances);
|
||||
|
||||
System::jsonExit($return);
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ class Api extends BaseModule
|
|||
*
|
||||
* @brief Login API user
|
||||
*
|
||||
* @return bool Was a user authenticated?
|
||||
* @throws HTTPException\ForbiddenException
|
||||
* @throws HTTPException\UnauthorizedException
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
|
@ -69,6 +70,8 @@ class Api extends BaseModule
|
|||
api_login(self::getApp());
|
||||
|
||||
self::$current_user_id = api_user();
|
||||
|
||||
return (bool)self::$current_user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -646,21 +646,25 @@ class Contact extends BaseModule
|
|||
return $arr['output'];
|
||||
}
|
||||
|
||||
$select_uid = local_user();
|
||||
|
||||
// @TODO: Replace with parameter from router
|
||||
$type = $a->argv[1] ?? '';
|
||||
|
||||
switch ($type) {
|
||||
case 'blocked':
|
||||
$sql_extra = " AND `blocked`";
|
||||
$sql_extra = sprintf(" AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = %d and `user-contact`.`blocked`)", intval(local_user()));
|
||||
$select_uid = 0;
|
||||
break;
|
||||
case 'hidden':
|
||||
$sql_extra = " AND `hidden` AND NOT `blocked`";
|
||||
$sql_extra = " AND `hidden` AND NOT `blocked` AND NOT `pending`";
|
||||
break;
|
||||
case 'ignored':
|
||||
$sql_extra = " AND `readonly` AND NOT `blocked`";
|
||||
$sql_extra = sprintf(" AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = %d and `user-contact`.`ignored`)", intval(local_user()));
|
||||
$select_uid = 0;
|
||||
break;
|
||||
case 'archived':
|
||||
$sql_extra = " AND `archive` AND NOT `blocked`";
|
||||
$sql_extra = " AND `archive` AND NOT `blocked` AND NOT `pending`";
|
||||
break;
|
||||
case 'pending':
|
||||
$sql_extra = sprintf(" AND `pending` AND NOT `archive` AND ((`rel` = %d)
|
||||
|
@ -762,21 +766,21 @@ class Contact extends BaseModule
|
|||
|
||||
$sql_extra2 = ((($sort_type > 0) && ($sort_type <= Model\Contact::FRIEND)) ? sprintf(" AND `rel` = %d ", intval($sort_type)) : '');
|
||||
|
||||
$sql_extra3 = Widget::unavailableNetworks();
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `contact`
|
||||
WHERE `uid` = %d AND `self` = 0 $sql_extra $sql_extra2 ",
|
||||
intval($_SESSION['uid'])
|
||||
WHERE `uid` = %d AND `self` = 0 $sql_extra $sql_extra2 $sql_extra3",
|
||||
intval($select_uid)
|
||||
);
|
||||
if (DBA::isResult($r)) {
|
||||
$total = $r[0]['total'];
|
||||
}
|
||||
$pager = new Pager($a->query_string);
|
||||
|
||||
$sql_extra3 = Widget::unavailableNetworks();
|
||||
|
||||
$contacts = [];
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ",
|
||||
intval($_SESSION['uid']),
|
||||
intval($select_uid),
|
||||
$pager->getStart(),
|
||||
$pager->getItemsPerPage()
|
||||
);
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
<?php
|
||||
namespace Friendica\Module;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Protocol\ActivityPub;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Model\Introduction;
|
||||
|
||||
/**
|
||||
* Process follow request confirmations
|
||||
|
@ -30,67 +22,15 @@ class FollowConfirm extends BaseModule
|
|||
|
||||
$intro_id = intval($_POST['intro_id'] ?? 0);
|
||||
$duplex = intval($_POST['duplex'] ?? 0);
|
||||
$cid = intval($_POST['contact_id'] ?? 0);
|
||||
$hidden = intval($_POST['hidden'] ?? 0);
|
||||
|
||||
if (empty($cid)) {
|
||||
notice(L10n::t('No given contact.') . EOL);
|
||||
return;
|
||||
}
|
||||
/** @var Introduction $Intro */
|
||||
$Intro = self::getClass(Introduction::class);
|
||||
$Intro->fetch(['id' => $intro_id, 'uid' => local_user()]);
|
||||
|
||||
Logger::info('Confirming follower', ['cid' => $cid]);
|
||||
$cid = $Intro->{'contact-id'};
|
||||
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $cid, 'uid' => $uid]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
Logger::warning('Contact not found in DB.', ['cid' => $cid]);
|
||||
notice(L10n::t('Contact not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$relation = $contact['rel'];
|
||||
$new_relation = $contact['rel'];
|
||||
$writable = $contact['writable'];
|
||||
|
||||
if (!empty($contact['protocol'])) {
|
||||
$protocol = $contact['protocol'];
|
||||
} else {
|
||||
$protocol = $contact['network'];
|
||||
}
|
||||
|
||||
if ($protocol == Protocol::ACTIVITYPUB) {
|
||||
ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $uid);
|
||||
}
|
||||
|
||||
if (in_array($protocol, [Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
|
||||
if ($duplex) {
|
||||
$new_relation = Contact::FRIEND;
|
||||
} else {
|
||||
$new_relation = Contact::FOLLOWER;
|
||||
}
|
||||
|
||||
if ($new_relation != Contact::FOLLOWER) {
|
||||
$writable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$fields = ['name-date' => DateTimeFormat::utcNow(),
|
||||
'uri-date' => DateTimeFormat::utcNow(),
|
||||
'blocked' => false, 'pending' => false, 'protocol' => $protocol,
|
||||
'writable' => $writable, 'hidden' => $hidden, 'rel' => $new_relation];
|
||||
DBA::update('contact', $fields, ['id' => $cid]);
|
||||
|
||||
if ($new_relation == Contact::FRIEND) {
|
||||
if ($protocol == Protocol::DIASPORA) {
|
||||
$user = User::getById($uid);
|
||||
$contact = Contact::getById($cid);
|
||||
$ret = Diaspora::sendShare($user, $contact);
|
||||
Logger::info('share returns', ['return' => $ret]);
|
||||
} elseif ($protocol == Protocol::ACTIVITYPUB) {
|
||||
ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $uid);
|
||||
}
|
||||
}
|
||||
|
||||
DBA::delete('intro', ['id' => $intro_id]);
|
||||
$Intro->confirm($duplex, $hidden);
|
||||
|
||||
$a->internalRedirect('contact/' . intval($cid));
|
||||
}
|
||||
|
|
|
@ -85,15 +85,20 @@ class Compose extends BaseModule
|
|||
$type = 'post';
|
||||
$doesFederate = true;
|
||||
|
||||
if ($_REQUEST['contact_allow']
|
||||
. $_REQUEST['group_allow']
|
||||
. $_REQUEST['contact_deny']
|
||||
. $_REQUEST['group_deny'])
|
||||
$contact_allow = $_REQUEST['contact_allow'] ?? '';
|
||||
$group_allow = $_REQUEST['group_allow'] ?? '';
|
||||
$contact_deny = $_REQUEST['contact_deny'] ?? '';
|
||||
$group_deny = $_REQUEST['group_deny'] ?? '';
|
||||
|
||||
if ($contact_allow
|
||||
. $group_allow
|
||||
. $contact_deny
|
||||
. $group_deny)
|
||||
{
|
||||
$contact_allow_list = $_REQUEST['contact_allow'] ? explode(',', $_REQUEST['contact_allow']) : [];
|
||||
$group_allow_list = $_REQUEST['group_allow'] ? explode(',', $_REQUEST['group_allow']) : [];
|
||||
$contact_deny_list = $_REQUEST['contact_deny'] ? explode(',', $_REQUEST['contact_deny']) : [];
|
||||
$group_deny_list = $_REQUEST['group_deny'] ? explode(',', $_REQUEST['group_deny']) : [];
|
||||
$contact_allow_list = $contact_allow ? explode(',', $contact_allow) : [];
|
||||
$group_allow_list = $group_allow ? explode(',', $group_allow) : [];
|
||||
$contact_deny_list = $contact_deny ? explode(',', $contact_deny) : [];
|
||||
$group_deny_list = $group_deny ? explode(',', $group_deny) : [];
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -126,7 +126,7 @@ class NodeInfo extends BaseModule
|
|||
$nodeinfo = [
|
||||
'version' => '1.0',
|
||||
'software' => [
|
||||
'name' => 'friendica',
|
||||
'name' => 'Friendica',
|
||||
'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION,
|
||||
],
|
||||
'protocols' => [
|
||||
|
@ -191,7 +191,7 @@ class NodeInfo extends BaseModule
|
|||
$nodeinfo = [
|
||||
'version' => '2.0',
|
||||
'software' => [
|
||||
'name' => 'friendica',
|
||||
'name' => 'Friendica',
|
||||
'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION,
|
||||
],
|
||||
'protocols' => ['dfrn', 'activitypub'],
|
||||
|
|
|
@ -67,7 +67,7 @@ class Verify extends BaseModule
|
|||
'$errors_label' => L10n::tt('Error', 'Errors', count(self::$errors)),
|
||||
'$errors' => self::$errors,
|
||||
'$recovery_message' => L10n::t('Don’t have your phone? <a href="%s">Enter a two-factor recovery code</a>', '2fa/recovery'),
|
||||
'$verify_code' => ['verify_code', L10n::t('Please enter a code from your authentication app'), '', '', 'required', 'autofocus placeholder="000000"', 'number'],
|
||||
'$verify_code' => ['verify_code', L10n::t('Please enter a code from your authentication app'), '', '', 'required', 'autofocus placeholder="000000"', 'tel'],
|
||||
'$verify_label' => L10n::t('Verify code and complete login'),
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue