use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1310);
+ define('DB_UPDATE_VERSION', 1311);
}
return [
"alias" => ["type" => "varchar(255)", "comment" => ""],
"pubkey" => ["type" => "text", "comment" => ""],
"baseurl" => ["type" => "varchar(255)", "comment" => "baseurl of the ap contact"],
+ "generator" => ["type" => "varchar(255)", "comment" => "Name of the contact's system"],
"updated" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""]
],
"indexes" => [
"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" => ""],
- "network" => ["type" => "char(4)", "not null" => "1", "default" => "", "comment" => "Network protocol of the contact"],
+ "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"],
"nick" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Nick- and user name of the contact"],
"location" => ["type" => "varchar(255)", "default" => "", "comment" => ""],
-- ------------------------------------------
-- Friendica 2019.06-dev (Dalmatian Bellflower)
--- DB_UPDATE_VERSION 1310
+-- DB_UPDATE_VERSION 1311
-- ------------------------------------------
`alias` varchar(255) COMMENT '',
`pubkey` text COMMENT '',
`baseurl` varchar(255) COMMENT 'baseurl of the ap contact',
+ `generator` varchar(255) COMMENT 'Name of the contact\'s system',
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
PRIMARY KEY(`url`),
INDEX `addr` (`addr`(32)),
`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 '',
- `network` char(4) NOT NULL DEFAULT '' COMMENT 'Network protocol of the contact',
+ `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',
`nick` varchar(255) NOT NULL DEFAULT '' COMMENT 'Nick- and user name of the contact',
`location` varchar(255) DEFAULT '' COMMENT '',
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Database\DBA;
-use Friendica\Model\APContact;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\User;
$dfrn_confirm = $contact['confirm'];
$aes_allow = $contact['aes_allow'];
- $network = ((strlen($contact['issued-id'])) ? Protocol::DFRN : Protocol::OSTATUS);
-
- if ($contact['network']) {
- $network = $contact['network'];
- }
-
// an empty DFRN-ID tells us that it had been a request via AP from a Friendica contact
- if (($network === Protocol::DFRN) && empty($dfrn_id) && !empty($contact['hub-verify'])) {
- $apcontact = APContact::getByURL($contact['url']);
- if (!empty($apcontact)) {
- $network = Protocol::ACTIVITYPUB;
- }
+ if (!empty($contact['protocol'])) {
+ $protocol = $contact['protocol'];
+ } elseif (($contact['network'] === Protocol::DFRN) && empty($dfrn_id)) {
+ $protocol = Contact::getProtocol($contact['url'], $contact['network']);
+ } else {
+ $protocol = $contact['network'];
}
- if ($network === Protocol::DFRN) {
+ if ($protocol === Protocol::DFRN) {
/*
* 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.
$public_key = $res['pubkey'];
// Save the private key. Send them the public key.
- q("UPDATE `contact` SET `prvkey` = '%s' WHERE `id` = %d AND `uid` = %d",
- DBA::escape($private_key),
- intval($contact_id),
- intval($uid)
- );
+ $fields = ['prvkey' => $private_key, 'protocol' => Protocol::DFRN];
+ DBA::update('contact', $fields, ['id' => $contact_id]);
$params = [];
if ($status != 0) {
return;
}
+ } else {
+ DBA::update('contact', ['protocol' => $protocol], ['id' => $contact_id]);
}
/*
Logger::log('dfrn_confirm: confirm - imported photos');
- if ($network === Protocol::DFRN) {
+ if ($protocol === Protocol::DFRN) {
$new_relation = Contact::FOLLOWER;
if (($relation == Contact::SHARING) || ($duplex)) {
intval($contact_id)
);
} else {
- if ($network == Protocol::ACTIVITYPUB) {
+ if ($protocol == Protocol::ACTIVITYPUB) {
ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $uid);
// Setting "pending" to true on a bidirectional contact request could create a problem when it isn't accepted on the other side
// Then we have got a situation where - although one direction is accepted - the contact still appears as pending.
$pending = false;
}
- // $network !== Protocol::DFRN
- $network = defaults($contact, 'network', Protocol::OSTATUS);
-
- $arr = Probe::uri($contact['url'], $network);
+ $arr = Probe::uri($contact['url'], $protocol);
$notify = defaults($contact, 'notify' , $arr['notify']);
$poll = defaults($contact, 'poll' , $arr['poll']);
$new_relation = $contact['rel'];
$writable = $contact['writable'];
- if (in_array($network, [Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
+ if (in_array($protocol, [Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
if ($duplex) {
$new_relation = Contact::FRIEND;
} else {
$fields = ['name-date' => DateTimeFormat::utcNow(),
'uri-date' => DateTimeFormat::utcNow(), 'addr' => $addr,
'notify' => $notify, 'poll' => $poll, 'blocked' => false,
- 'pending' => $pending, 'network' => $network,
+ 'pending' => $pending, 'protocol' => $protocol,
'writable' => $writable, 'hidden' => $hidden, 'rel' => $new_relation];
DBA::update('contact', $fields, ['id' => $contact_id]);
}
// reload contact info
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id]);
- if ((isset($new_relation) && $new_relation == Contact::FRIEND)) {
+ if (isset($new_relation) && ($new_relation == Contact::FRIEND)) {
if (DBA::isResult($contact) && ($contact['network'] === Protocol::DIASPORA)) {
$ret = Diaspora::sendShare($user, $contact);
Logger::log('share returns: ' . $ret);
Group::addMember(User::getDefaultGroup($uid, $contact["network"]), $contact['id']);
- if ($network == Protocol::ACTIVITYPUB && $duplex) {
+ if (($protocol == Protocol::ACTIVITYPUB) && $duplex) {
ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $uid);
}
+++ /dev/null
-<?php
-
-use Friendica\App;
-use Friendica\Core\Logger;
-use Friendica\Model\FileTag;
-use Friendica\Util\XML;
-
-function filerm_content(App $a)
-{
- if (! local_user())
- {
- exit();
- }
-
- $term = XML::unescape(trim(defaults($_GET, 'term', '')));
- $cat = XML::unescape(trim(defaults($_GET, 'cat', '')));
-
- $category = (($cat) ? true : false);
-
- if ($category)
- {
- $term = $cat;
- }
-
- $item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
-
- Logger::log('filerm: tag ' . $term . ' item ' . $item_id . ' category ' . ($category ? 'true' : 'false'));
-
- if ($item_id && strlen($term)) {
- if (FileTag::unsaveFile(local_user(), $item_id, $term, $category)) {
- info('Item removed');
- }
- }
- else {
- info('Item was not deleted');
- }
-
- $a->internalRedirect('/network?f=&file=' . rawurlencode($term));
- exit();
-}
$ret = Probe::uri($url);
- if (($ret['network'] == Protocol::DIASPORA) && !Config::get('system', 'diaspora_enabled')) {
+ $protocol = Contact::getProtocol($ret['url'], $ret['network']);
+
+ if (($protocol == Protocol::DIASPORA) && !Config::get('system', 'diaspora_enabled')) {
notice(L10n::t("Diaspora support isn't enabled. Contact can't be added."));
$submit = '';
//$a->internalRedirect($_SESSION['return_path']);
// NOTREACHED
}
- if (($ret['network'] == Protocol::OSTATUS) && Config::get('system', 'ostatus_disabled')) {
+ if (($protocol == Protocol::OSTATUS) && Config::get('system', 'ostatus_disabled')) {
notice(L10n::t("OStatus support is disabled. Contact can't be added."));
$submit = '';
//$a->internalRedirect($_SESSION['return_path']);
// NOTREACHED
}
- if ($ret['network'] == Protocol::PHANTOM) {
+ if ($protocol == Protocol::PHANTOM) {
notice(L10n::t("The network type couldn't be detected. Contact can't be added."));
$submit = '';
//$a->internalRedirect($_SESSION['return_path']);
// NOTREACHED
}
- if ($ret['network'] == Protocol::MAIL) {
+ if ($protocol == Protocol::MAIL) {
$ret['url'] = $ret['addr'];
}
- if (($ret['network'] === Protocol::DFRN) && !DBA::isResult($r)) {
+ if (($protocol === Protocol::DFRN) && !DBA::isResult($r)) {
$request = $ret['request'];
$tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
} else {
$gcontact_id = $r[0]['id'];
}
- if ($ret['network'] === Protocol::DIASPORA) {
+ if ($protocol === Protocol::DIASPORA) {
$r[0]['location'] = '';
$r[0]['about'] = '';
}
+++ /dev/null
-<?php
-/**
- * @file mod/friendica.php
- */
-
-use Friendica\App;
-use Friendica\Core\Addon;
-use Friendica\Core\Config;
-use Friendica\Core\Hook;
-use Friendica\Core\L10n;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Module\Register;
-
-function friendica_init(App $a)
-{
- if (!empty($a->argv[1]) && ($a->argv[1] == "json")) {
- $register_policies = [
- Register::CLOSED => 'REGISTER_CLOSED',
- Register::APPROVE => 'REGISTER_APPROVE',
- Register::OPEN => 'REGISTER_OPEN'
- ];
-
- $register_policy_int = intval(Config::get('config', 'register_policy'));
- if ($register_policy_int !== Register::CLOSED && Config::get('config', 'invitation_only')) {
- $register_policy = 'REGISTER_INVITATION';
- } else {
- $register_policy = $register_policies[$register_policy_int];
- }
-
- $condition = [];
- $admin = false;
- if (!empty(Config::get('config', 'admin_nickname'))) {
- $condition['nickname'] = Config::get('config', 'admin_nickname');
- }
- if (!empty(Config::get('config', 'admin_email'))) {
- $adminlist = explode(",", str_replace(" ", "", Config::get('config', 'admin_email')));
- $condition['email'] = $adminlist[0];
- $administrator = DBA::selectFirst('user', ['username', 'nickname'], $condition);
- if (DBA::isResult($administrator)) {
- $admin = [
- 'name' => $administrator['username'],
- 'profile'=> System::baseUrl() . '/profile/' . $administrator['nickname'],
- ];
- }
- }
-
- $visible_addons = Addon::getVisibleList();
-
- Config::load('feature_lock');
- $locked_features = [];
- $featureLock = Config::get('config', 'feature_lock');
- if (isset($featureLock)) {
- foreach ($featureLock as $k => $v) {
- if ($k === 'config_loaded') {
- continue;
- }
-
- $locked_features[$k] = intval($v);
- }
- }
-
- $data = [
- 'version' => FRIENDICA_VERSION,
- 'url' => System::baseUrl(),
- 'addons' => $visible_addons,
- 'locked_features' => $locked_features,
- 'explicit_content' => (int)Config::get('system', 'explicit_content', false),
- 'language' => Config::get('system','language'),
- 'register_policy' => $register_policy,
- 'admin' => $admin,
- 'site_name' => Config::get('config', 'sitename'),
- 'platform' => FRIENDICA_PLATFORM,
- 'info' => Config::get('config', 'info'),
- 'no_scrape_url' => System::baseUrl().'/noscrape'
- ];
-
- header('Content-type: application/json; charset=utf-8');
- echo json_encode($data);
- exit();
- }
-}
-
-function friendica_content(App $a)
-{
- $o = '<h1>Friendica</h1>' . PHP_EOL;
- $o .= '<p>';
- $o .= L10n::t('This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.',
- '<strong>' . FRIENDICA_VERSION . '</strong>', System::baseUrl(), '<strong>' . DB_UPDATE_VERSION . '</strong>',
- '<strong>' . Config::get("system", "post_update_version") . '</strong>');
- $o .= '</p>' . PHP_EOL;
-
- $o .= '<p>';
- $o .= L10n::t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.') . PHP_EOL;
- $o .= '</p>' . PHP_EOL;
-
- $o .= '<p>';
- $o .= L10n::t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">'.L10n::t('the bugtracker at github').'</a>';
- $o .= '</p>' . PHP_EOL;
- $o .= '<p>';
- $o .= L10n::t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca');
- $o .= '</p>' . PHP_EOL;
-
- $visible_addons = Addon::getVisibleList();
- if (count($visible_addons)) {
- $o .= '<p>' . L10n::t('Installed addons/apps:') . '</p>' . PHP_EOL;
- $sorted = $visible_addons;
- $s = '';
- sort($sorted);
- foreach ($sorted as $p) {
- if (strlen($p)) {
- if (strlen($s)) {
- $s .= ', ';
- }
- $s .= $p;
- }
- }
- $o .= '<div style="margin-left: 25px; margin-right: 25px; margin-bottom: 25px;">' . $s . '</div>' . PHP_EOL;
- } else {
- $o .= '<p>' . L10n::t('No installed addons/apps') . '</p>' . PHP_EOL;
- }
-
- if (Config::get('system', 'tosdisplay'))
- {
- $o .= '<p>'.L10n::t('Read about the <a href="%1$s/tos">Terms of Service</a> of this node.', System::baseurl()).'</p>';
- }
-
- $blocklist = Config::get('system', 'blocklist', []);
- if (!empty($blocklist)) {
- $o .= '<div id="about_blocklist"><p>' . L10n::t('On this server the following remote servers are blocked.') . '</p>' . PHP_EOL;
- $o .= '<table class="table"><thead><tr><th>' . L10n::t('Blocked domain') . '</th><th>' . L10n::t('Reason for the block') . '</th></thead><tbody>' . PHP_EOL;
- foreach ($blocklist as $b) {
- $o .= '<tr><td>' . $b['domain'] .'</td><td>' . $b['reason'] . '</td></tr>' . PHP_EOL;
- }
- $o .= '</tbody></table></div>' . PHP_EOL;
- }
-
- Hook::callAll('about_hook', $o);
-
- return $o;
-}
+++ /dev/null
-<?php
-/**
- * @file mod/maintenance.php
- */
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Core\L10n;
-use Friendica\Core\Renderer;
-use Friendica\Util\Strings;
-
-function maintenance_content(App $a)
-{
- $reason = Config::get('system', 'maintenance_reason');
-
- if (substr(Strings::normaliseLink($reason), 0, 7) == 'http://') {
- header("HTTP/1.1 307 Temporary Redirect");
- header("Location:".$reason);
- return;
- }
-
- header('HTTP/1.1 503 Service Temporarily Unavailable');
- header('Status: 503 Service Temporarily Unavailable');
- header('Retry-After: 600');
-
- return Renderer::replaceMacros(Renderer::getMarkupTemplate('maintenance.tpl'), [
- '$sysdown' => L10n::t('System down for maintenance'),
- '$reason' => $reason
- ]);
-}
+++ /dev/null
-<?php
-
-use Friendica\App;
-use Friendica\Database\DBA;
-
-function modexp_init(App $a) {
-
- if($a->argc != 2)
- exit();
-
- $nick = $a->argv[1];
- $r = q("SELECT `spubkey` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
- DBA::escape($nick)
- );
-
- if (! DBA::isResult($r)) {
- exit();
- }
-
- $lines = explode("\n",$r[0]['spubkey']);
- unset($lines[0]);
- unset($lines[count($lines)]);
- $x = base64_decode(implode('',$lines));
-
- $r = ASN_BASE::parseASNString($x);
-
- $m = $r[0]->asnData[1]->asnData[0]->asnData[0]->asnData;
- $e = $r[0]->asnData[1]->asnData[0]->asnData[1]->asnData;
-
- header("Content-type: application/magic-public-key");
- echo 'RSA' . '.' . $m . '.' . $e;
-
- exit();
-
-}
-
+++ /dev/null
-<?php
-
-use Friendica\App;
-use Friendica\Core\Theme;
-
-function pretheme_init(App $a) {
-
- if ($_REQUEST['theme']) {
- $theme = $_REQUEST['theme'];
- $info = Theme::getInfo($theme);
- if ($info) {
- // unfortunately there will be no translation for this string
- $desc = $info['description'];
- $version = $info['version'];
- $credits = $info['credits'];
- } else {
- $desc = '';
- $version = '';
- $credits = '';
- }
- echo json_encode(['img' => Theme::getScreenshot($theme), 'desc' => $desc, 'version' => $version, 'credits' => $credits]);
- }
-
- exit();
-}
+++ /dev/null
-<?php
-
-/**
- * @file mod/robots_text.php
- * @brief Module which returns the default robots.txt
- * @version 0.1.2
- */
-
-use Friendica\App;
-
-/**
- * @brief Return default robots.txt when init
- * @param App $a
- * @return void
- */
-function robots_txt_init(App $a)
-{
- $allDisalloweds = [
- '/settings/',
- '/admin/',
- '/message/',
- ];
-
- header('Content-Type: text/plain');
- echo 'User-agent: *' . PHP_EOL;
- foreach ($allDisalloweds as $disallowed) {
- echo 'Disallow: ' . $disallowed . PHP_EOL;
- }
- exit();
-}
+++ /dev/null
-<?php
-/**
- * @file mod/viewsrc.php
- */
-use Friendica\App;
-use Friendica\Core\L10n;
-use Friendica\Database\DBA;
-use Friendica\Model\Item;
-
-function viewsrc_content(App $a)
-{
- if (!local_user()) {
- notice(L10n::t('Access denied.') . EOL);
- return;
- }
-
- $o = '';
- $item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
-
- if (!$item_id) {
- throw new \Friendica\Network\HTTPException\NotFoundException(L10n::t('Item not found.'));
- }
-
- $item = Item::selectFirst(['body'], ['uid' => local_user(), 'id' => $item_id]);
-
- if (DBA::isResult($item)) {
- if ($a->isAjax()) {
- echo str_replace("\n", '<br />', $item['body']);
- exit();
- } else {
- $o .= str_replace("\n", '<br />', $item['body']);
- }
- }
- return $o;
-}
header('Refresh: 120; url=' . $this->getBaseURL() . "/" . $this->query_string);
Module\Special\HTTPException::rawContent(
- new HTTPException\ServiceUnavaiableException('The node is currently overloaded. Please try again later.')
+ new HTTPException\ServiceUnavailableException('The node is currently overloaded. Please try again later.')
);
}
// in install mode, any url loads install module
// but we need "view" module for stylesheet
- if ($this->getMode()->isInstall() && $this->module != 'view') {
- $this->module = 'install';
- } elseif (!$this->getMode()->has(App\Mode::MAINTENANCEDISABLED) && $this->module != 'view') {
- $this->module = 'maintenance';
+ if ($this->getMode()->isInstall() && $this->module !== 'install') {
+ $this->internalRedirect('install');
+ } elseif (!$this->getMode()->has(App\Mode::MAINTENANCEDISABLED) && $this->module !== 'maintenance') {
+ $this->internalRedirect('maintenance');
} else {
$this->checkURL();
Core\Update::check($this->getBasePath(), false, $this->getMode());
$this->routeCollector->addRoute(['GET'], '/apps', Module\Apps::class);
$this->routeCollector->addRoute(['GET'], '/attach/{item:\d+}', Module\Attach::class);
$this->routeCollector->addRoute(['GET'], '/babel', Module\Babel::class);
- $this->routeCollector->addRoute(['GET'], '/bookmarklet', Module\BookMarklet::class);
+ $this->routeCollector->addRoute(['GET'], '/bookmarklet', Module\Bookmarklet::class);
$this->routeCollector->addGroup('/contact', function (RouteCollector $collector) {
$collector->addRoute(['GET'], '[/]', Module\Contact::class);
$collector->addRoute(['GET'], '/{id:\d+}[/posts|conversations]', Module\Contact::class);
});
$this->routeCollector->addRoute(['GET'], '/credits', Module\Credits::class);
+ $this->routeCollector->addRoute(['GET'], '/directory', Module\Directory::class);
$this->routeCollector->addGroup('/feed', function (RouteCollector $collector) {
$collector->addRoute(['GET'], '/{nickname}', Module\Feed::class);
$collector->addRoute(['GET'], '/{nickname}/posts', Module\Feed::class);
$collector->addRoute(['GET'], '/{nickname}/replies', Module\Feed::class);
$collector->addRoute(['GET'], '/{nickname}/activity', Module\Feed::class);
});
- $this->routeCollector->addRoute(['GET'], '/directory', Module\Directory::class);
$this->routeCollector->addRoute(['GET'], '/feedtest', Module\Feedtest::class);
$this->routeCollector->addGroup('/fetch', function (RouteCollector $collector) {
$collector->addRoute(['GET'], '/{guid}/post', Module\Diaspora\Fetch::class);
$collector->addRoute(['GET'], '/{guid}/status_message', Module\Diaspora\Fetch::class);
$collector->addRoute(['GET'], '/{guid}/reshare', Module\Diaspora\Fetch::class);
});
- $this->routeCollector->addRoute(['GET'], '/filer[/{id:\d+}]', Module\Filer::class);
+ $this->routeCollector->addRoute(['GET'], '/filer[/{id:\d+}]', Module\Filer\SaveTag::class);
+ $this->routeCollector->addRoute(['GET'], '/filerm/{id:\d+}', Module\Filer\RemoveTag::class);
$this->routeCollector->addRoute(['GET'], '/followers/{owner}', Module\Followers::class);
$this->routeCollector->addRoute(['GET'], '/following/{owner}', Module\Following::class);
+ $this->routeCollector->addRoute(['GET'], '/friendica[/json]', Module\Friendica::class);
$this->routeCollector->addGroup('/group', function (RouteCollector $collector) {
$collector->addRoute(['GET', 'POST'], '[/]', Module\Group::class);
$collector->addRoute(['GET', 'POST'], '/{group:\d+}', Module\Group::class);
$this->routeCollector->addRoute(['GET', 'POST'], '/login', Module\Login::class);
$this->routeCollector->addRoute(['GET', 'POST'], '/logout', Module\Logout::class);
$this->routeCollector->addRoute(['GET'], '/magic', Module\Magic::class);
+ $this->routeCollector->addRoute(['GET'], '/maintenance', Module\Maintenance::class);
$this->routeCollector->addRoute(['GET'], '/manifest', Module\Manifest::class);
+ $this->routeCollector->addRoute(['GET'], '/modexp/{nick}', Module\PublicRSAKey::class);
$this->routeCollector->addRoute(['GET'], '/nodeinfo/1.0', Module\NodeInfo::class);
$this->routeCollector->addRoute(['GET'], '/nogroup', Module\Group::class);
$this->routeCollector->addRoute(['GET'], '/objects/{guid}', Module\Objects::class);
$collector->addRoute(['GET'], '/{type}/{name}', Module\Photo::class);
$collector->addRoute(['GET'], '/{type}/{customize}/{name}', Module\Photo::class);
});
+ $this->routeCollector->addRoute(['GET'], '/pretheme', Module\ThemeDetails::class);
$this->routeCollector->addGroup('/profile', function (RouteCollector $collector) {
$collector->addRoute(['GET'], '/{nickname}', Module\Profile::class);
$collector->addRoute(['GET'], '/{profile:\d+}/view', Module\Profile::class);
$collector->addRoute(['GET'], '/{sub1}/{sub2}/{url}' , Module\Proxy::class);
});
$this->routeCollector->addRoute(['GET', 'POST'], '/register', Module\Register::class);
+ $this->routeCollector->addRoute(['GET'], '/robots.txt', Module\RobotsTxt::class);
$this->routeCollector->addRoute(['GET'], '/rsd.xml', Module\ReallySimpleDiscovery::class);
$this->routeCollector->addRoute(['GET'], '/smilies[/json]', Module\Smilies::class);
$this->routeCollector->addRoute(['GET'], '/statistics.json', Module\Statistics::class);
$this->routeCollector->addRoute(['GET'], '/tos', Module\Tos::class);
+ $this->routeCollector->addRoute(['GET'], '/viewsrc/{item:\d+}', Module\ItemBody::class);
$this->routeCollector->addRoute(['GET'], '/webfinger', Module\WebFinger::class);
$this->routeCollector->addRoute(['GET'], '/xrd', Module\Xrd::class);
}
case 301:
header('HTTP/1.1 301 Moved Permanently');
break;
+ case 307:
+ header('HTTP/1.1 307 Temporary Redirect');
+ break;
}
header("Location: $url");
'uid' => $admin['uid'],
'type' => SYSTEM_EMAIL,
'to_email' => $admin['email'],
+ 'subject' => l10n::t('[Friendica Notify] Database update'),
'preamble' => $preamble,
'body' => $preamble,
'language' => $lang]
$apcontact['manually-approve'] = (int)JsonLD::fetchElement($compacted, 'as:manuallyApprovesFollowers');
+ if (!empty($compacted['as:generator'])) {
+ $apcontact['baseurl'] = JsonLD::fetchElement($compacted['as:generator'], 'as:url', '@id');
+ $apcontact['generator'] = JsonLD::fetchElement($compacted['as:generator'], 'as:name', '@value');
+ }
+
// To-Do
// Unhandled
- // @context, tag, attachment, image, nomadicLocations, signature, following, followers, featured, movedTo, liked
+ // tag, attachment, image, nomadicLocations, signature, featured, movedTo, liked
// Unhandled from Misskey
// sharedInbox, isCat
$apcontact['baseurl'] = Network::unparseURL($parts);
} else {
$apcontact['addr'] = null;
+ }
+
+ if (empty($apcontact['baseurl'])) {
$apcontact['baseurl'] = null;
}
if (empty($contact['network'])) {
return;
}
- if (($contact['network'] == Protocol::DFRN) && $dissolve) {
+
+ $protocol = $contact['network'];
+ if (($protocol == Protocol::DFRN) && !self::isLegacyDFRNContact($contact)) {
+ $protocol = Protocol::ACTIVITYPUB;
+ }
+
+ if (($protocol == Protocol::DFRN) && $dissolve) {
DFRN::deliver($user, $contact, 'placeholder', true);
- } elseif (in_array($contact['network'], [Protocol::OSTATUS, Protocol::DFRN])) {
+ } elseif (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
// create an unfollow slap
$item = [];
$item['verb'] = NAMESPACE_OSTATUS . "/unfollow";
if (!empty($contact['notify'])) {
Salmon::slapper($user, $contact['notify'], $slap);
}
- } elseif ($contact['network'] == Protocol::DIASPORA) {
+ } elseif ($protocol == Protocol::DIASPORA) {
Diaspora::sendUnshare($user, $contact);
- } elseif ($contact['network'] == Protocol::ACTIVITYPUB) {
+ } elseif ($protocol == Protocol::ACTIVITYPUB) {
ActivityPub\Transmitter::sendContactUndo($contact['url'], $contact['id'], $user['uid']);
if ($dissolve) {
// The link could be provided as http although we stored it as https
$ssl_url = str_replace('http://', 'https://', $url);
- $fields = ['url', 'addr', 'alias', 'notify', 'poll', 'name', 'nick',
+ $fields = ['id', 'uid', 'url', 'addr', 'alias', 'notify', 'poll', 'name', 'nick',
'photo', 'keywords', 'location', 'about', 'network',
'priority', 'batch', 'request', 'confirm', 'poco'];
return true;
}
+ /**
+ * 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.
+ *
+ * @param string $url contact url
+ * @param string $network Network of that contact
+ * @return string with protocol
+ */
+ public static function getProtocol($url, $network)
+ {
+ if ($network != Protocol::DFRN) {
+ return $network;
+ }
+
+ $apcontact = APContact::getByURL($url);
+ if (!empty($apcontact) && !empty($apcontact['generator'])) {
+ return Protocol::ACTIVITYPUB;
+ } else {
+ return $network;
+ }
+ }
+
/**
* Takes a $uid and a url/handle and adds a new contact
* Currently if the contact is DFRN, interactive needs to be true, to redirect to the
$contact = DBA::selectFirst('contact', ['id', 'rel'], $condition);
}
- if (($ret['network'] === Protocol::DFRN) && !DBA::isResult($contact)) {
+ $protocol = self::getProtocol($url, $ret['network']);
+
+ if (($protocol === Protocol::DFRN) && !DBA::isResult($contact)) {
if ($interactive) {
if (strlen($a->getURLPath())) {
$myaddr = bin2hex(System::baseUrl() . '/profile/' . $a->user['nickname']);
}
// This extra param just confuses things, remove it
- if ($ret['network'] === Protocol::DIASPORA) {
+ if ($protocol === Protocol::DIASPORA) {
$ret['url'] = str_replace('?absolute=true', '', $ret['url']);
}
return $result;
}
- if ($ret['network'] === Protocol::OSTATUS && Config::get('system', 'ostatus_disabled')) {
+ if ($protocol === Protocol::OSTATUS && Config::get('system', 'ostatus_disabled')) {
$result['message'] .= L10n::t('The profile address specified belongs to a network which has been disabled on this site.') . EOL;
$ret['notify'] = '';
}
$result['message'] .= L10n::t('Limited profile. This person will be unable to receive direct/personal notifications from you.') . EOL;
}
- $writeable = ((($ret['network'] === Protocol::OSTATUS) && ($ret['notify'])) ? 1 : 0);
+ $writeable = ((($protocol === Protocol::OSTATUS) && ($ret['notify'])) ? 1 : 0);
- $subhub = (($ret['network'] === Protocol::OSTATUS) ? true : false);
+ $subhub = (($protocol === Protocol::OSTATUS) ? true : false);
- $hidden = (($ret['network'] === Protocol::MAIL) ? 1 : 0);
+ $hidden = (($protocol === Protocol::MAIL) ? 1 : 0);
- $pending = in_array($ret['network'], [Protocol::ACTIVITYPUB]);
+ $pending = in_array($protocol, [Protocol::ACTIVITYPUB]);
- if (in_array($ret['network'], [Protocol::MAIL, Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
+ if (in_array($protocol, [Protocol::MAIL, Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
$writeable = 1;
}
$fields = ['rel' => $new_relation, 'subhub' => $subhub, 'readonly' => false];
DBA::update('contact', $fields, ['id' => $contact['id']]);
} else {
- $new_relation = (in_array($ret['network'], [Protocol::MAIL]) ? self::FRIEND : self::SHARING);
+ $new_relation = (in_array($protocol, [Protocol::MAIL]) ? self::FRIEND : self::SHARING);
// create contact record
DBA::insert('contact', [
'name' => $ret['name'],
'nick' => $ret['nick'],
'network' => $ret['network'],
+ 'protocol' => $protocol,
'pubkey' => $ret['pubkey'],
'rel' => $new_relation,
'priority'=> $ret['priority'],
$owner = User::getOwnerDataById($uid);
if (DBA::isResult($owner)) {
- if (in_array($contact['network'], [Protocol::OSTATUS, Protocol::DFRN])) {
+ if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
// create a follow slap
$item = [];
$item['verb'] = ACTIVITY_FOLLOW;
if (!empty($contact['notify'])) {
Salmon::slapper($owner, $contact['notify'], $slap);
}
- } elseif ($contact['network'] == Protocol::DIASPORA) {
+ } elseif ($protocol == Protocol::DIASPORA) {
$ret = Diaspora::sendShare($a->user, $contact);
Logger::log('share returns: ' . $ret);
- } elseif ($contact['network'] == Protocol::ACTIVITYPUB) {
+ } elseif ($protocol == Protocol::ACTIVITYPUB) {
$activity_id = ActivityPub\Transmitter::activityIDFromContact($contact_id);
if (empty($activity_id)) {
// This really should never happen
return $contact;
}
- public static function addRelationship($importer, $contact, $datarray, $item = '', $sharing = false) {
+ public static function addRelationship($importer, $contact, $datarray, $item = '', $sharing = false, $note = '') {
// Should always be set
if (empty($datarray['author-id'])) {
return;
$network = $pub_contact['network'];
if (is_array($contact)) {
+ // Make sure that the existing contact isn't archived
+ self::unmarkForArchival($contact);
+
+ $protocol = self::getProtocol($url, $contact['network']);
+
if (($contact['rel'] == self::SHARING)
|| ($sharing && $contact['rel'] == self::FOLLOWER)) {
- DBA::update('contact', ['rel' => self::FRIEND, 'writable' => true],
+ DBA::update('contact', ['rel' => self::FRIEND, 'writable' => true, 'pending' => false],
['id' => $contact['id'], 'uid' => $importer['uid']]);
}
- if ($contact['network'] == Protocol::ACTIVITYPUB) {
+ if ($protocol == Protocol::ACTIVITYPUB) {
ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $importer['uid']);
}
// send email notification to owner?
} else {
+ $protocol = self::getProtocol($url, $network);
+
if (DBA::exists('contact', ['nurl' => Strings::normaliseLink($url), 'uid' => $importer['uid'], 'pending' => true])) {
Logger::log('ignoring duplicated connection request from pending contact ' . $url);
return;
if (is_array($contact_record)) {
DBA::insert('intro', ['uid' => $importer['uid'], 'contact-id' => $contact_record['id'],
- 'blocked' => false, 'knowyou' => false,
+ 'blocked' => false, 'knowyou' => false, 'note' => $note,
'hash' => $hash, 'datetime' => DateTimeFormat::utcNow()]);
}
DBA::update('contact', ['pending' => false], $condition);
$contact = DBA::selectFirst('contact', ['url', 'network', 'hub-verify'], ['id' => $contact_record['id']]);
+ $protocol = self::getProtocol($contact['url'], $contact['network']);
- if ($contact['network'] == Protocol::ACTIVITYPUB) {
+ if ($protocol == Protocol::ACTIVITYPUB) {
ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $importer['uid']);
}
}
*/
public static function magicLinkByContact($contact, $url = '')
{
+ if (empty($contact['id']) || empty($contact['uid'])) {
+ return $url ?: $contact['url'];
+ }
+
if ((!local_user() && !remote_user()) || ($contact['network'] != Protocol::DFRN)) {
return $url ?: $contact['url']; // Equivalent to ($url != '') ? $url : $contact['url'];
}
// Field list that is used to deliver items via the protocols
const DELIVER_FIELDLIST = ['uid', 'id', 'parent', 'uri', 'thr-parent', 'parent-uri', 'guid',
- 'created', 'edited', 'verb', 'object-type', 'object', 'target',
+ 'parent-guid', 'created', 'edited', 'verb', 'object-type', 'object', 'target',
'private', 'title', 'body', 'location', 'coord', 'app',
'attach', 'tag', 'deleted', 'extid', 'post-type',
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
*/
public static function searchProfiles($start = 0, $count = 100, $search = null)
{
- if ($search) {
- $search = DBA::escape($search);
-
- $sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR
- (`user`.`nickname` LIKE '%$search%') OR
- (`profile`.`pdesc` LIKE '%$search%') OR
- (`profile`.`locality` LIKE '%$search%') OR
- (`profile`.`region` LIKE '%$search%') OR
- (`profile`.`country-name` LIKE '%$search%') OR
- (`profile`.`gender` LIKE '%$search%') OR
- (`profile`.`marital` LIKE '%$search%') OR
- (`profile`.`sexual` LIKE '%$search%') OR
- (`profile`.`about` LIKE '%$search%') OR
- (`profile`.`romance` LIKE '%$search%') OR
- (`profile`.`work` LIKE '%$search%') OR
- (`profile`.`education` LIKE '%$search%') OR
- (`profile`.`pub_keywords` LIKE '%$search%') OR
- (`profile`.`prv_keywords` LIKE '%$search%'))";
- } else {
- $sql_extra = '';
- }
-
$publish = (Config::get('system', 'publish_all') ? '' : " AND `publish` = 1 ");
-
$total = 0;
- $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total`
+
+ if (!empty($search)) {
+ $searchTerm = '%' . $search . '%';
+ $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total`
FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
- WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` $sql_extra");
+ WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
+ AND ((`profile`.`name` LIKE ?) OR
+ (`user`.`nickname` LIKE ?) OR
+ (`profile`.`pdesc` LIKE ?) OR
+ (`profile`.`locality` LIKE ?) OR
+ (`profile`.`region` LIKE ?) OR
+ (`profile`.`country-name` LIKE ?) OR
+ (`profile`.`gender` LIKE ?) OR
+ (`profile`.`marital` LIKE ?) OR
+ (`profile`.`sexual` LIKE ?) OR
+ (`profile`.`about` LIKE ?) OR
+ (`profile`.`romance` LIKE ?) OR
+ (`profile`.`work` LIKE ?) OR
+ (`profile`.`education` LIKE ?) OR
+ (`profile`.`pub_keywords` LIKE ?) OR
+ (`profile`.`prv_keywords` LIKE ?))",
+ $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm,
+ $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm);
+ } else {
+ $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total`
+ FROM `profile`
+ LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
+ WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`");
+ }
+
if (DBA::isResult($cnt)) {
$total = $cnt['total'];
}
$order = " ORDER BY `name` ASC ";
- $limit = $start . ',' . $count;
+ $profiles = [];
+
+ // If nothing found, don't try to select details
+ if ($total > 0) {
+ if (!empty($search)) {
+ $searchTerm = '%' . $search . '%';
- $profiles = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
+ $profiles = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
`contact`.`addr`, `contact`.`url` AS `profile_url`
FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
- $sql_extra $order LIMIT $limit"
- );
+ AND ((`profile`.`name` LIKE ?) OR
+ (`user`.`nickname` LIKE ?) OR
+ (`profile`.`pdesc` LIKE ?) OR
+ (`profile`.`locality` LIKE ?) OR
+ (`profile`.`region` LIKE ?) OR
+ (`profile`.`country-name` LIKE ?) OR
+ (`profile`.`gender` LIKE ?) OR
+ (`profile`.`marital` LIKE ?) OR
+ (`profile`.`sexual` LIKE ?) OR
+ (`profile`.`about` LIKE ?) OR
+ (`profile`.`romance` LIKE ?) OR
+ (`profile`.`work` LIKE ?) OR
+ (`profile`.`education` LIKE ?) OR
+ (`profile`.`pub_keywords` LIKE ?) OR
+ (`profile`.`prv_keywords` LIKE ?))
+ $order LIMIT ?,?",
+ $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm,
+ $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm, $searchTerm,
+ $start, $count
+ );
+ } else {
+ $profiles = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
+ `contact`.`addr`, `contact`.`url` AS `profile_url`
+ FROM `profile`
+ LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
+ LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
+ WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
+ $order LIMIT ?,?",
+ $start, $count
+ );
+ }
+ }
- if (DBA::isResult($profiles)) {
+ if (DBA::isResult($profiles) && $total > 0) {
return [
'total' => $total,
'entries' => DBA::toArray($profiles),
];
+
} else {
return [
'total' => $total,
}
}
+ /**
+ * Get a user based on its email
+ *
+ * @param string $email
+ * @param array $fields
+ *
+ * @return array|boolean User record if it exists, false otherwise
+ *
+ * @throws Exception
+ */
+ public static function getByEmail($email, array $fields = [])
+ {
+ return DBA::selectFirst('user', $fields, ['email' => $email]);
+ }
+
/**
* @brief Get owner data by user id
*
+++ /dev/null
-<?php
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Core\ACL;
-use Friendica\Core\L10n;
-use Friendica\Network\HTTPException;
-use Friendica\Util\Strings;
-
-/**
- * Creates a bookmarklet
- * Shows either a editor browser or adds the given bookmarklet to the current user
- */
-class BookMarklet extends BaseModule
-{
- public static function content()
- {
- $_GET['mode'] = 'minimal';
-
- $app = self::getApp();
- $config = $app->getConfig();
-
- if (!local_user()) {
- $output = '<h2>' . L10n::t('Login') . '</h2>';
- $output .= Login::form($app->query_string, intval($config->get('config', 'register_policy')) === Register::CLOSED ? false : true);
- return $output;
- }
-
- $referer = Strings::normaliseLink(defaults($_SERVER, 'HTTP_REFERER', ''));
- $page = Strings::normaliseLink($app->getBaseURL() . "/bookmarklet");
-
- if (!strstr($referer, $page)) {
- if (empty($_REQUEST["url"])) {
- throw new HTTPException\BadRequestException(L10n::t('This page is missing a url parameter.'));
- }
-
- $content = add_page_info($_REQUEST["url"]);
-
- $x = [
- 'is_owner' => true,
- 'allow_location' => $app->user['allow_location'],
- 'default_location' => $app->user['default-location'],
- 'nickname' => $app->user['nickname'],
- 'lockstate' => ((is_array($app->user) && ((strlen($app->user['allow_cid'])) || (strlen($a->user['allow_gid'])) || (strlen($app->user['deny_cid'])) || (strlen($app->user['deny_gid'])))) ? 'lock' : 'unlock'),
- 'default_perms' => ACL::getDefaultUserPermissions($app->user),
- 'acl' => ACL::getFullSelectorHTML($app->user, true),
- 'bang' => '',
- 'visitor' => 'block',
- 'profile_uid' => local_user(),
- 'title' => trim(defaults($_REQUEST, 'title', ''), '*'),
- 'content' => $content
- ];
- $output = status_editor($app, $x, 0, false);
- $output .= "<script>window.resizeTo(800,550);</script>";
- } else {
- $output = '<h2>' . L10n::t('The post was created') . '</h2>';
- $output .= "<script>window.close()</script>";
- }
-
- return $output;
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\ACL;
+use Friendica\Core\L10n;
+use Friendica\Network\HTTPException;
+use Friendica\Util\Strings;
+
+/**
+ * Creates a bookmarklet
+ * Shows either a editor browser or adds the given bookmarklet to the current user
+ */
+class Bookmarklet extends BaseModule
+{
+ public static function content()
+ {
+ $_GET['mode'] = 'minimal';
+
+ $app = self::getApp();
+ $config = $app->getConfig();
+
+ if (!local_user()) {
+ $output = '<h2>' . L10n::t('Login') . '</h2>';
+ $output .= Login::form($app->query_string, intval($config->get('config', 'register_policy')) === Register::CLOSED ? false : true);
+ return $output;
+ }
+
+ $referer = Strings::normaliseLink(defaults($_SERVER, 'HTTP_REFERER', ''));
+ $page = Strings::normaliseLink($app->getBaseURL() . "/bookmarklet");
+
+ if (!strstr($referer, $page)) {
+ if (empty($_REQUEST["url"])) {
+ throw new HTTPException\BadRequestException(L10n::t('This page is missing a url parameter.'));
+ }
+
+ $content = add_page_info($_REQUEST["url"]);
+
+ $x = [
+ 'is_owner' => true,
+ 'allow_location' => $app->user['allow_location'],
+ 'default_location' => $app->user['default-location'],
+ 'nickname' => $app->user['nickname'],
+ 'lockstate' => ((is_array($app->user) && ((strlen($app->user['allow_cid'])) || (strlen($a->user['allow_gid'])) || (strlen($app->user['deny_cid'])) || (strlen($app->user['deny_gid'])))) ? 'lock' : 'unlock'),
+ 'default_perms' => ACL::getDefaultUserPermissions($app->user),
+ 'acl' => ACL::getFullSelectorHTML($app->user, true),
+ 'bang' => '',
+ 'visitor' => 'block',
+ 'profile_uid' => local_user(),
+ 'title' => trim(defaults($_REQUEST, 'title', ''), '*'),
+ 'content' => $content
+ ];
+ $output = status_editor($app, $x, 0, false);
+ $output .= "<script>window.resizeTo(800,550);</script>";
+ } else {
+ $output = '<h2>' . L10n::t('The post was created') . '</h2>';
+ $output .= "<script>window.close()</script>";
+ }
+
+ return $output;
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Core\L10n;
-use Friendica\Core\PConfig;
-use Friendica\Core\Renderer;
-use Friendica\Model;
-use Friendica\Util\XML;
-
-/**
- * Shows a dialog for adding tags to a file
- */
-class Filer extends BaseModule
-{
- public static function init()
- {
- if (!local_user()) {
- info(L10n::t('You must be logged in to use this module'));
- self::getApp()->internalRedirect();
- }
- }
-
- public static function rawContent()
- {
- $a = self::getApp();
- $logger = $a->getLogger();
-
- $term = XML::unescape(trim(defaults($_GET, 'term', '')));
- // @TODO: Replace with parameter from router
- $item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
-
- $logger->info('filer', ['tag' => $term, 'item' => $item_id]);
-
- if ($item_id && strlen($term)) {
- // file item
- Model\FileTag::saveFile(local_user(), $item_id, $term);
- info(L10n::t('Filetag %s saved to item', $term));
- }
-
- // return filer dialog
- $filetags = PConfig::get(local_user(), 'system', 'filetags');
- $filetags = Model\FileTag::fileToList($filetags, 'file');
- $filetags = explode(",", $filetags);
-
- $tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
- echo Renderer::replaceMacros($tpl, [
- '$field' => ['term', L10n::t("Save to Folder:"), '', '', $filetags, L10n::t('- select -')],
- '$submit' => L10n::t('Save'),
- ]);
-
- exit;
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Module\Filer;
+
+use Friendica\BaseModule;
+use Friendica\Model\FileTag;
+use Friendica\Network\HTTPException;
+use Friendica\Util\XML;
+
+/**
+ * Remove a tag from a file
+ */
+class RemoveTag extends BaseModule
+{
+ public static function content()
+ {
+ if (!local_user()) {
+ throw new HTTPException\ForbiddenException();
+ }
+
+ $app = self::getApp();
+ $logger = $app->getLogger();
+
+ $item_id = (($app->argc > 1) ? intval($app->argv[1]) : 0);
+
+ $term = XML::unescape(trim(defaults($_GET, 'term', '')));
+ $cat = XML::unescape(trim(defaults($_GET, 'cat', '')));
+
+ $category = (($cat) ? true : false);
+
+ if ($category) {
+ $term = $cat;
+ }
+
+ $logger->info('Filer - Remove Tag', [
+ 'term' => $term,
+ 'item' => $item_id,
+ 'category' => ($category ? 'true' : 'false')
+ ]);
+
+ if ($item_id && strlen($term)) {
+ if (FileTag::unsaveFile(local_user(), $item_id, $term, $category)) {
+ info('Item removed');
+ }
+ } else {
+ info('Item was not deleted');
+ }
+
+ $app->internalRedirect('/network?f=&file=' . rawurlencode($term));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module\Filer;
+
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Core\PConfig;
+use Friendica\Core\Renderer;
+use Friendica\Model;
+use Friendica\Util\XML;
+
+/**
+ * Shows a dialog for adding tags to a file
+ */
+class SaveTag extends BaseModule
+{
+ public static function init()
+ {
+ if (!local_user()) {
+ info(L10n::t('You must be logged in to use this module'));
+ self::getApp()->internalRedirect();
+ }
+ }
+
+ public static function rawContent()
+ {
+ $a = self::getApp();
+ $logger = $a->getLogger();
+
+ $term = XML::unescape(trim(defaults($_GET, 'term', '')));
+ // @TODO: Replace with parameter from router
+ $item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
+
+ $logger->info('filer', ['tag' => $term, 'item' => $item_id]);
+
+ if ($item_id && strlen($term)) {
+ // file item
+ Model\FileTag::saveFile(local_user(), $item_id, $term);
+ info(L10n::t('Filetag %s saved to item', $term));
+ }
+
+ // return filer dialog
+ $filetags = PConfig::get(local_user(), 'system', 'filetags');
+ $filetags = Model\FileTag::fileToList($filetags, 'file');
+ $filetags = explode(",", $filetags);
+
+ $tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
+ echo Renderer::replaceMacros($tpl, [
+ '$field' => ['term', L10n::t("Save to Folder:"), '', '', $filetags, L10n::t('- select -')],
+ '$submit' => L10n::t('Save'),
+ ]);
+
+ exit;
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\Addon;
+use Friendica\Core\Hook;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Model\User;
+
+/**
+ * Prints information about the current node
+ * Either in human readable form or in JSON
+ */
+class Friendica extends BaseModule
+{
+ public static function content()
+ {
+ $app = self::getApp();
+ $config = $app->getConfig();
+
+ $visibleAddonList = Addon::getVisibleList();
+ if (!empty($visibleAddonList)) {
+
+ $sorted = $visibleAddonList;
+ sort($sorted);
+
+ $sortedAddonList = '';
+
+ foreach ($sorted as $addon) {
+ if (strlen($addon)) {
+ if (strlen($sortedAddonList)) {
+ $sortedAddonList .= ', ';
+ }
+ $sortedAddonList .= $addon;
+ }
+ }
+ $addon = [
+ 'title' => L10n::t('Installed addons/apps:'),
+ 'list' => $sortedAddonList,
+ ];
+ } else {
+ $addon = [
+ 'title' => L10n::t('No installed addons/apps'),
+ ];
+ }
+
+ $tos = ($config->get('system', 'tosdisplay')) ?
+ L10n::t('Read about the <a href="%1$s/tos">Terms of Service</a> of this node.', $app->getBaseURL()) :
+ '';
+
+ $blockList = $config->get('system', 'blocklist');
+
+ if (!empty($blockList)) {
+ $blocked = [
+ 'title' => L10n::t('On this server the following remote servers are blocked.'),
+ 'header' => [
+ L10n::t('Blocked domain'),
+ L10n::t('Reason for the block'),
+ ],
+ 'list' => $blockList,
+ ];
+ } else {
+ $blocked = null;
+ }
+
+ $hooked = '';
+
+ Hook::callAll('about_hook', $hooked);
+
+ $tpl = Renderer::getMarkupTemplate('friendica.tpl');
+
+ return Renderer::replaceMacros($tpl, [
+ 'about' => L10n::t('This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.',
+ '<strong>' . FRIENDICA_VERSION . '</strong>',
+ $app->getBaseURL(),
+ '<strong>' . DB_UPDATE_VERSION . '</strong>',
+ '<strong>' . $config->get('system', 'post_update_version') . '</strong>'),
+ 'friendica' => L10n::t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'),
+ 'bugs' => L10n::t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . L10n::t('the bugtracker at github') . '</a>',
+ 'info' => L10n::t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),
+
+ 'visible_addons' => $addon,
+ 'tos' => $tos,
+ 'block_list' => $blocked,
+ 'hooked' => $hooked,
+ ]);
+ }
+
+ public static function rawContent()
+ {
+ $app = self::getApp();
+
+ // @TODO: Replace with parameter from router
+ if ($app->argc <= 1 || ($app->argv[1] !== 'json')) {
+ return;
+ }
+
+ $config = $app->getConfig();
+
+ $register_policies = [
+ Register::CLOSED => 'REGISTER_CLOSED',
+ Register::APPROVE => 'REGISTER_APPROVE',
+ Register::OPEN => 'REGISTER_OPEN'
+ ];
+
+ $register_policy_int = intval($config->get('config', 'register_policy'));
+ if ($register_policy_int !== Register::CLOSED && $config->get('config', 'invitation_only')) {
+ $register_policy = 'REGISTER_INVITATION';
+ } else {
+ $register_policy = $register_policies[$register_policy_int];
+ }
+
+ $condition = [];
+ $admin = false;
+ if (!empty($config->get('config', 'admin_nickname'))) {
+ $condition['nickname'] = $config->get('config', 'admin_nickname');
+ }
+ if (!empty($config->get('config', 'admin_email'))) {
+ $adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email')));
+ $condition['email'] = $adminList[0];
+ $administrator = User::getByEmail($adminList[0], ['username', 'nickname']);
+ if (!empty($administrator)) {
+ $admin = [
+ 'name' => $administrator['username'],
+ 'profile' => $app->getBaseURL() . '/profile/' . $administrator['nickname'],
+ ];
+ }
+ }
+
+ $visible_addons = Addon::getVisibleList();
+
+ $config->load('feature_lock');
+ $locked_features = [];
+ $featureLocks = $config->get('config', 'feature_lock');
+ if (isset($featureLocks)) {
+ foreach ($featureLocks as $feature => $lock) {
+ if ($feature === 'config_loaded') {
+ continue;
+ }
+
+ $locked_features[$feature] = intval($lock);
+ }
+ }
+
+ $data = [
+ 'version' => FRIENDICA_VERSION,
+ 'url' => $app->getBaseURL(),
+ 'addons' => $visible_addons,
+ 'locked_features' => $locked_features,
+ 'explicit_content' => intval($config->get('system', 'explicit_content', 0)),
+ 'language' => $config->get('system', 'language'),
+ 'register_policy' => $register_policy,
+ 'admin' => $admin,
+ 'site_name' => $config->get('config', 'sitename'),
+ 'platform' => FRIENDICA_PLATFORM,
+ 'info' => $config->get('config', 'info'),
+ 'no_scrape_url' => $app->getBaseURL() . '/noscrape',
+ ];
+
+ header('Content-type: application/json; charset=utf-8');
+ echo json_encode($data);
+ exit();
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Model\Item;
+use Friendica\Network\HTTPException;
+
+/**
+ * Print the body of an Item
+ */
+class ItemBody extends BaseModule
+{
+ public static function content()
+ {
+ if (!local_user()) {
+ throw new HTTPException\UnauthorizedException(L10n::t('Access denied.'));
+ }
+
+ $app = self::getApp();
+
+ // @TODO: Replace with parameter from router
+ $itemId = (($app->argc > 1) ? intval($app->argv[1]) : 0);
+
+ if (!$itemId) {
+ throw new HTTPException\NotFoundException(L10n::t('Item not found.'));
+ }
+
+ $item = Item::selectFirst(['body'], ['uid' => local_user(), 'id' => $itemId]);
+
+ if (!empty($item)) {
+ if ($app->isAjax()) {
+ echo str_replace("\n", '<br />', $item['body']);
+ exit();
+ } else {
+ return str_replace("\n", '<br />', $item['body']);
+ }
+ } else {
+ throw new HTTPException\NotFoundException(L10n::t('Item not found.'));
+ }
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Core\System;
+use Friendica\Network\HTTPException;
+use Friendica\Util\Strings;
+
+/**
+ * Shows the maintenance reason
+ * or redirects to the alternate location
+ */
+class Maintenance extends BaseModule
+{
+ public static function content()
+ {
+ $config = self::getApp()->getConfig();
+
+ $reason = $config->get('system', 'maintenance_reason');
+
+ if ((substr(Strings::normaliseLink($reason), 0, 7) === 'http://') ||
+ (substr(Strings::normaliseLink($reason), 0, 8) === 'https://')) {
+ System::externalRedirect($reason, 307);
+ }
+
+ $exception = new HTTPException\ServiceUnavailableException($reason);
+ $exception->httpdesc = L10n::t('System down for maintenance');
+ throw $exception;
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use ASN_BASE;
+use Friendica\BaseModule;
+use Friendica\Model\User;
+use Friendica\Network\HTTPException\BadRequestException;
+
+/**
+ * prints the public RSA key of a user
+ */
+class PublicRSAKey extends BaseModule
+{
+ public static function rawContent()
+ {
+ $app = self::getApp();
+
+ // @TODO: Replace with parameter from router
+ if ($app->argc !== 2) {
+ throw new BadRequestException();
+ }
+
+ // @TODO: Replace with parameter from router
+ $nick = $app->argv[1];
+
+ $user = User::getByNickname($nick, ['spubkey']);
+ if (empty($user) || empty($user['spubkey'])) {
+ throw new BadRequestException();
+ }
+
+ $lines = explode("\n", $user['spubkey']);
+ unset($lines[0]);
+ unset($lines[count($lines)]);
+
+ $asnString = base64_decode(implode('', $lines));
+ $asnBase = ASN_BASE::parseASNString($asnString);
+
+ $m = $asnBase[0]->asnData[1]->asnData[0]->asnData[0]->asnData;
+ $e = $asnBase[0]->asnData[1]->asnData[0]->asnData[1]->asnData;
+
+ header('Content-type: application/magic-public-key');
+ echo 'RSA' . '.' . $m . '.' . $e;
+
+ exit();
+ }
+}
namespace Friendica\Module;
use Friendica\BaseModule;
-use Friendica\Core\Renderer;
+use Friendica\Util\XML;
/**
* Prints the rsd.xml
{
public static function rawContent()
{
- header ('Content-Type: text/xml');
- $tpl = Renderer::getMarkupTemplate('rsd.tpl');
- echo Renderer::replaceMacros($tpl);
+ header('Content-Type: text/xml');
+
+ $app = self::getApp();
+ $xml = null;
+ echo XML::fromArray([
+ 'rsd' => [
+ '@attributes' => [
+ 'version' => '1.0',
+ 'xmlns' => 'http://archipelago.phrasewise.com/rsd',
+ ],
+ 'service' => [
+ 'engineName' => 'Friendica',
+ 'engineLink' => 'http://friendica.com',
+ 'apis' => [
+ 'api' => [
+ '@attributes' => [
+ 'name' => 'Twitter',
+ 'preferred' => 'true',
+ 'apiLink' => $app->getBaseURL(),
+ 'blogID' => '',
+ ],
+ 'settings' => [
+ 'docs' => [
+ 'http://status.net/wiki/TwitterCompatibleAPI',
+ ],
+ 'setting' => [
+ '@attributes' => [
+ 'name' => 'OAuth',
+ ],
+ 'false',
+ ],
+ ],
+ ]
+ ],
+ ],
+ ],
+ ], $xml);
exit();
}
}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+
+/**
+ * Return the default robots.txt
+ */
+class RobotsTxt extends BaseModule
+{
+ public static function rawContent()
+ {
+ $allDisalloweds = [
+ '/settings/',
+ '/admin/',
+ '/message/',
+ ];
+
+ header('Content-Type: text/plain');
+ echo 'User-agent: *' . PHP_EOL;
+ foreach ($allDisalloweds as $disallowed) {
+ echo 'Disallow: ' . $disallowed . PHP_EOL;
+ }
+ exit();
+ }
+}
$message = defaults($explanation, $e->getCode(), '');
}
- return ['$title' => $title, '$description' => $message];
+ return ['$title' => $title, '$message' => $message, '$back' => L10n::t('Go back')];
}
/**
* Displays a bare message page with no theming at all.
*
* @param \Friendica\Network\HTTPException $e
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws \Exception
*/
public static function rawContent(\Friendica\Network\HTTPException $e)
{
*
* @param \Friendica\Network\HTTPException $e
* @return string
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws \Exception
*/
public static function content(\Friendica\Network\HTTPException $e)
{
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\Theme;
+
+/**
+ * Prints theme specific details as a JSON string
+ */
+class ThemeDetails extends BaseModule
+{
+ public static function rawContent()
+ {
+ if (!empty($_REQUEST['theme'])) {
+ $theme = $_REQUEST['theme'];
+ $info = Theme::getInfo($theme);
+
+ // Unfortunately there will be no translation for this string
+ $description = defaults($info, 'description', '');
+ $version = defaults($info, 'version' , '');
+ $credits = defaults($info, 'credits' , '');
+
+ echo json_encode([
+ 'img' => Theme::getScreenshot($theme),
+ 'desc' => $description,
+ 'version' => $version,
+ 'credits' => $credits,
+ ]);
+ }
+ exit();
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Network\HTTPException;
-
-use Friendica\Network\HTTPException;
-
-class ServiceUnavaiableException extends HTTPException
-{
- protected $code = 503;
-}
--- /dev/null
+<?php
+
+namespace Friendica\Network\HTTPException;
+
+use Friendica\Network\HTTPException;
+
+class ServiceUnavailableException extends HTTPException
+{
+ protected $code = 503;
+}
$cid = Contact::getIdForURL($activity['actor'], $uid);
if (!empty($cid)) {
self::switchContact($cid);
- DBA::update('contact', ['hub-verify' => $activity['id']], ['id' => $cid]);
+ DBA::update('contact', ['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]);
$contact = DBA::selectFirst('contact', [], ['id' => $cid, 'network' => Protocol::NATIVE_SUPPORT]);
} else {
$contact = false;
$item = ['author-id' => Contact::getIdForURL($activity['actor']),
'author-link' => $activity['actor']];
+ $note = Strings::escapeTags(trim(defaults($activity, 'content', '')));
+
// Ensure that the contact has got the right network type
self::switchContact($item['author-id']);
- Contact::addRelationship($owner, $contact, $item);
+ Contact::addRelationship($owner, $contact, $item, '', false, $note);
$cid = Contact::getIdForURL($activity['actor'], $uid);
if (empty($cid)) {
return;
}
if (empty($contact)) {
- DBA::update('contact', ['hub-verify' => $activity['id']], ['id' => $cid]);
+ DBA::update('contact', ['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]);
}
Logger::log('Follow user ' . $uid . ' from contact ' . $cid . ' with id ' . $activity['id']);
self::switchContact($cid);
- if (DBA::exists('contact', ['id' => $cid, 'rel' => Contact::SHARING, 'pending' => true])) {
+ if (DBA::exists('contact', ['id' => $cid, 'rel' => Contact::SHARING])) {
Contact::remove($cid);
Logger::log('Rejected contact request from contact ' . $cid . ' for user ' . $uid . ' - contact had been removed.', Logger::DEBUG);
} else {
private static function switchContact($cid)
{
$contact = DBA::selectFirst('contact', ['network'], ['id' => $cid, 'network' => Protocol::NATIVE_SUPPORT]);
- if (!DBA::isResult($contact) || ($contact['network'] == Protocol::ACTIVITYPUB)) {
+ if (!DBA::isResult($contact) || in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN])) {
return;
}
return;
}
+ if (($contact['network'] == Protocol::DFRN) && !Contact::isLegacyDFRNContact($contact)) {
+ $protocol = Protocol::ACTIVITYPUB;
+ } else {
+ $protocol = $contact['network'];
+ }
+
$importer_uid = $contact['uid'];
// Possibly switch the remote contact to AP
- if ($contact['network'] === Protocol::OSTATUS) {
+ if ($protocol === Protocol::OSTATUS) {
ActivityPub\Receiver::switchContact($contact['id'], $importer_uid, $contact['url']);
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id]);
}
+ $updated = DateTimeFormat::utcNow();
+
// These three networks can be able to speak AP, so we are trying to fetch AP profile data here
- if (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN])) {
+ if (in_array($protocol, [Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN])) {
$apcontact = APContact::getByURL($contact['url'], true);
- $updated = DateTimeFormat::utcNow();
- if (($contact['network'] === Protocol::ACTIVITYPUB) && empty($apcontact)) {
+ if (($protocol === Protocol::ACTIVITYPUB) && empty($apcontact)) {
self::updateContact($contact, ['last-update' => $updated, 'failure_update' => $updated]);
Contact::markForArchival($contact);
Logger::log('Contact archived');
}
// Diaspora users, archived users and followers are only checked if they still exist.
- if (($contact['network'] != Protocol::ACTIVITYPUB) && ($contact['archive'] || ($contact["network"] == Protocol::DIASPORA) || ($contact["rel"] == Contact::FOLLOWER))) {
+ if (($protocol != Protocol::ACTIVITYPUB) && ($contact['archive'] || ($contact["network"] == Protocol::DIASPORA) || ($contact["rel"] == Contact::FOLLOWER))) {
$last_updated = PortableContact::lastUpdated($contact["url"], true);
- $updated = DateTimeFormat::utcNow();
if ($last_updated) {
Logger::log('Contact '.$contact['id'].' had last update on '.$last_updated, Logger::DEBUG);
}
// Update the contact entry
- if (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN])) {
- $updated = DateTimeFormat::utcNow();
+ if (in_array($protocol, [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN])) {
// Currently we can't check every AP implementation, so we don't do it at all
- if (($contact['network'] != Protocol::ACTIVITYPUB) && !PortableContact::reachable($contact['url'])) {
+ if (($protocol != Protocol::ACTIVITYPUB) && !PortableContact::reachable($contact['url'])) {
Logger::log("Skipping probably dead contact ".$contact['url']);
// set the last-update so we don't keep polling
Logger::log("Don't poll follower");
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
return;
}
// Don't poll if polling is deactivated (But we poll feeds and mails anyway)
- if (!in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) && Config::get('system', 'disable_polling')) {
+ if (!in_array($protocol, [Protocol::FEED, Protocol::MAIL]) && Config::get('system', 'disable_polling')) {
Logger::log('Polling is disabled');
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
return;
}
// We don't poll AP contacts by now
- if ($contact['network'] === Protocol::ACTIVITYPUB) {
+ if ($protocol === Protocol::ACTIVITYPUB) {
Logger::log("Don't poll AP contact");
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
return;
}
Logger::log('Ignore public contacts');
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
return;
}
Logger::log('No self contact for user '.$importer_uid);
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
return;
}
: DateTimeFormat::utc($contact['last-update'], DateTimeFormat::ATOM)
);
- Logger::log("poll: ({$contact['network']}-{$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
+ Logger::log("poll: ({$protocol}-{$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
- if ($contact['network'] === Protocol::DFRN) {
+ if ($protocol === Protocol::DFRN) {
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
if (intval($contact['duplex']) && $contact['dfrn-id']) {
$idtosend = '0:' . $orig_id;
if (!$curlResult->isSuccess() && ($curlResult->getErrorNumber() == CURLE_OPERATION_TIMEDOUT)) {
// set the last-update so we don't keep polling
- self::updateContact($contact, ['last-update' => DateTimeFormat::utcNow()]);
+ self::updateContact($contact, ['last-update' => $updated]);
Contact::markForArchival($contact);
Logger::log('Contact archived');
return;
Logger::log("$url appears to be dead - marking for death ");
// set the last-update so we don't keep polling
- $fields = ['last-update' => DateTimeFormat::utcNow(), 'failure_update' => DateTimeFormat::utcNow()];
+ $fields = ['last-update' => $updated, 'failure_update' => $updated];
self::updateContact($contact, $fields);
Contact::markForArchival($contact);
return;
if (!strstr($handshake_xml, '<')) {
Logger::log('response from ' . $url . ' did not contain XML.');
- $fields = ['last-update' => DateTimeFormat::utcNow(), 'failure_update' => DateTimeFormat::utcNow()];
+ $fields = ['last-update' => $updated, 'failure_update' => $updated];
self::updateContact($contact, $fields);
Contact::markForArchival($contact);
return;
Logger::log("$url replied status 1 - marking for death ");
// set the last-update so we don't keep polling
- $fields = ['last-update' => DateTimeFormat::utcNow(), 'failure_update' => DateTimeFormat::utcNow()];
+ $fields = ['last-update' => $updated, 'failure_update' => $updated];
self::updateContact($contact, $fields);
Contact::markForArchival($contact);
} elseif ($contact['term-date'] > DBA::NULL_DATETIME) {
if ((intval($res->status) != 0) || !strlen($res->challenge) || !strlen($res->dfrn_id)) {
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
Logger::log('Contact status is ' . $res->status);
return;
}
Logger::log('ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
Contact::markForArchival($contact);
return;
}
$xml = Network::post($contact['poll'], $postvars)->getBody();
- } elseif (($contact['network'] === Protocol::OSTATUS)
- || ($contact['network'] === Protocol::DIASPORA)
- || ($contact['network'] === Protocol::FEED)) {
+ } elseif (($protocol === Protocol::OSTATUS)
+ || ($protocol === Protocol::DIASPORA)
+ || ($protocol === Protocol::FEED)) {
// Upgrading DB fields from an older Friendica version
// Will only do this once per notify-enabled OStatus contact
$stat_writeable = ((($contact['notify']) && ($contact['rel'] == Contact::FOLLOWER || $contact['rel'] == Contact::FRIEND)) ? 1 : 0);
// Contacts from OStatus are always writable
- if ($contact['network'] === Protocol::OSTATUS) {
+ if ($protocol === Protocol::OSTATUS) {
$stat_writeable = 1;
}
// Are we allowed to import from this person?
if ($contact['rel'] == Contact::FOLLOWER || $contact['blocked']) {
// set the last-update so we don't keep polling
- DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
+ DBA::update('contact', ['last-update' => $updated], ['id' => $contact['id']]);
Logger::log('Contact is blocked or only a follower');
return;
}
if ($curlResult->isTimeout()) {
// set the last-update so we don't keep polling
- self::updateContact($contact, ['last-update' => DateTimeFormat::utcNow()]);
+ self::updateContact($contact, ['last-update' => $updated]);
Contact::markForArchival($contact);
Logger::log('Contact archived');
return;
$xml = $curlResult->getBody();
- } elseif ($contact['network'] === Protocol::MAIL) {
+ } elseif ($protocol === Protocol::MAIL) {
Logger::log("Mail: Fetching for ".$contact['addr'], Logger::DEBUG);
$mail_disabled = ((function_exists('imap_open') && !Config::get('system', 'imap_disabled')) ? 0 : 1);
if ($mail_disabled) {
// set the last-update so we don't keep polling
- self::updateContact($contact, ['last-update' => DateTimeFormat::utcNow()]);
+ self::updateContact($contact, ['last-update' => $updated]);
Contact::markForArchival($contact);
Logger::log('Contact archived');
return;
unset($password);
Logger::log("Mail: Connect to " . $mailconf['user']);
if ($mbox) {
- $fields = ['last_check' => DateTimeFormat::utcNow()];
+ $fields = ['last_check' => $updated];
DBA::update('mailacct', $fields, ['id' => $mailconf['id']]);
Logger::log("Mail: Connected to " . $mailconf['user']);
} else {
// Only delete when mails aren't automatically moved or deleted
if (($mailconf['action'] != 1) && ($mailconf['action'] != 3))
if ($meta->deleted && ! $item['deleted']) {
- $fields = ['deleted' => true, 'changed' => DateTimeFormat::utcNow()];
+ $fields = ['deleted' => true, 'changed' => $updated];
Item::update($fields, ['id' => $item['id']]);
}
if ($datarray['parent-uri'] === $datarray['uri']) {
$datarray['private'] = 1;
}
- if (($contact['network'] === Protocol::MAIL) && !PConfig::get($importer_uid, 'system', 'allow_public_email_replies')) {
+ if (($protocol === Protocol::MAIL) && !PConfig::get($importer_uid, 'system', 'allow_public_email_replies')) {
$datarray['private'] = 1;
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
}
if (!strstr($xml, '<')) {
Logger::log('post_handshake: response from ' . $url . ' did not contain XML.');
- $fields = ['last-update' => DateTimeFormat::utcNow(), 'failure_update' => DateTimeFormat::utcNow()];
+ $fields = ['last-update' => $updated, 'failure_update' => $updated];
self::updateContact($contact, $fields);
Contact::markForArchival($contact);
return;
consume_feed($xml, $importer, $contact, $hub);
// do it a second time for DFRN so that any children find their parents.
- if ($contact['network'] === Protocol::DFRN) {
+ if ($protocol === Protocol::DFRN) {
consume_feed($xml, $importer, $contact, $hub);
}
$hubmode = 'subscribe';
- if ($contact['network'] === Protocol::DFRN || $contact['blocked']) {
+ if ($protocol === Protocol::DFRN || $contact['blocked']) {
$hubmode = 'unsubscribe';
}
- if (($contact['network'] === Protocol::OSTATUS || $contact['network'] == Protocol::FEED) && (! $contact['hub-verify'])) {
+ if (($protocol === Protocol::OSTATUS || $protocol == Protocol::FEED) && (! $contact['hub-verify'])) {
$hub_update = true;
}
$hub_update = true;
}
- Logger::log("Contact ".$contact['id']." returned hub: ".$hub." Network: ".$contact['network']." Relation: ".$contact['rel']." Update: ".$hub_update);
+ Logger::log("Contact ".$contact['id']." returned hub: ".$hub." Network: ".$protocol." Relation: ".$contact['rel']." Update: ".$hub_update);
- if (strlen($hub) && $hub_update && (($contact['rel'] != Contact::FOLLOWER) || $contact['network'] == Protocol::FEED)) {
+ if (strlen($hub) && $hub_update && (($contact['rel'] != Contact::FOLLOWER) || $protocol == Protocol::FEED)) {
Logger::log('hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
$hubs = explode(',', $hub);
}
}
- $updated = DateTimeFormat::utcNow();
-
self::updateContact($contact, ['last-update' => $updated, 'success_update' => $updated]);
DBA::update('gcontact', ['last_contact' => $updated], ['nurl' => $contact['nurl']]);
Contact::unmarkForArchival($contact);
} elseif (in_array($contact["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::FEED])) {
- $updated = DateTimeFormat::utcNow();
-
self::updateContact($contact, ['last-update' => $updated, 'failure_update' => $updated]);
DBA::update('gcontact', ['last_failure' => $updated], ['nurl' => $contact['nurl']]);
Contact::markForArchival($contact);
} else {
- self::updateContact($contact, ['last-update' => DateTimeFormat::utcNow()]);
+ self::updateContact($contact, ['last-update' => $updated]);
}
Logger::log('End');
cursor: pointer;
}
-/* General designing elements */
+/* General design elements */
.btn {
outline: none;
-moz-box-shadow: inset 0px 1px 0px 0px #ffffff;
.wall-item-container .wall-item-content .type-link img.attachment-image,
.type-link img.attachment-image, .type-video img.attachment-image {
- /* max-width: 640px; */
max-width: 100%;
max-height: initial;
float: initial;
height: 1.2em;
vertical-align: middle;
}
+
+/* Exception page */
+
+#exception {
+ overflow: hidden;
+ background-image: url('../images/friendica-404_svg_hare-bottom-light-inside.png');
+ background-position: 50px bottom;
+ background-repeat: no-repeat;
+}
+
+#exception .hare {
+ float: right;
+}
+
+@media screen and (max-width: 600px) {
+ #exception .hare {
+ display: none;
+ }
+}
<div id="exception" class="generic-page-wrapper">
+ <img class="hare" src="images/friendica-404_svg_flexy-o-hare.png"/>
<h1>{{$title}}</h1>
<p>{{$message}}</p>
+ <p><button type="button" onclick="window.history.back()" class="btn btn-primary">{{$back}}</button></p>
</div>
-<h2>Feed Test</h2>
-<form action="feedtest" method="get" class="panel panel-default">
- <div class="panel-body">
- <div class="form-group">
- {{include file="field_input.tpl" field=$url}}
- </div>
- <p><button type="submit" class="btn btn-primary">Submit</button></p>
- </div>
-</form>
-
-{{if $result}}
-<div class="feedtest-result">
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Output Items</h3>
- </div>
+<div id="feedtest" class="generic-page-wrapper">
+ <h2>Feed Test</h2>
+ <form action="feedtest" method="get" class="panel panel-default">
<div class="panel-body">
- <pre>{{$result.output}}</pre>
+ <div class="form-group">
+ {{include file="field_input.tpl" field=$url}}
+ </div>
+ <p><button type="submit" class="btn btn-primary">Submit</button></p>
</div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Input Feed XML</h3>
+ </form>
+
+ {{if $result}}
+ <div class="feedtest-result">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h3 class="panel-title">Output Items</h3>
+ </div>
+ <div class="panel-body">
+ <pre>{{$result.output}}</pre>
+ </div>
</div>
- <div class="panel-body">
- {{$result.input}}
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h3 class="panel-title">Input Feed XML</h3>
+ </div>
+ <div class="panel-body">
+ {{$result.input}}
+ </div>
</div>
</div>
+ {{/if}}
</div>
-{{/if}}
\ No newline at end of file
--- /dev/null
+<div id="friendica" class="generic-page-wrapper">
+ <h1>Friendica</h1>
+ <br>
+ <p>{{$about nofilter}}</p>
+ <br>
+ <p>{{$friendica nofilter}}</p>
+ <br>
+ <p>{{$bugs nofilter}}</p>
+ <br>
+ <p>{{$info nofilter}}</p>
+ <br>
+
+ <p>{{$visible_addons.title nofilter}}</p>
+ {{if $visible_addons.list}}
+ <div style="margin-left: 25px; margin-right: 25px; margin-bottom: 25px;">{{$visible_addons.list nofilter}}</div>
+ {{/if}}
+
+ {{if $tos}}
+ <p>{{$tos nofilter}}</p>
+ {{/if}}
+
+ {{if $block_list}}
+ <div id="about_blocklist">
+ <p>{{$block_list.title nofilter}}</p>
+ <br>
+ <table class="table">
+ <thead>
+ <tr>
+ <th>{{$block_list.header[0] nofilter}}</th>
+ <th>{{$block_list.header[1] nofilter}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{foreach $block_list.list as $blocked}}
+ <tr>
+ <td>{{$blocked.domain nofilter}}</td>
+ <td>{{$blocked.reason nofilter}}</td>
+ </tr>
+ {{/foreach}}
+ </tbody>
+ </table>
+ </div>
+
+ {{/if}}
+
+{{$hooked nofilter}}
+</div>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
- <service>
- <engineName>Friendica</engineName>
- <engineLink>http://friendica.com/</engineLink>
- <apis>
- <api name="Twitter" preferred="true" apiLink="{{$baseurl}}/api/" blogID="">
- <settings>
- <docs>http://status.net/wiki/TwitterCompatibleAPI</docs>
- <setting name="OAuth">false</setting>
- </settings>
- </api>
- </apis>
- </service>
-</rsd>
* mobile aside
*/
@media screen and (max-width: 990px) {
+ body {
+ padding-top: 105px;
+ }
aside{
position: fixed!important;
top: 0!important;
display: flex;
}
+#friendica-logo-mask {
+ display: block;
+}
+
/* Notification Menu */
#topbar-first #nav-notifications-menu {