diff --git a/database.sql b/database.sql
index 10b18d4ca..01bd84b00 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2022.09-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1472
+-- DB_UPDATE_VERSION 1473
-- ------------------------------------------
@@ -297,6 +297,7 @@ CREATE TABLE IF NOT EXISTS `2fa_trusted_browser` (
`cookie_hash` varchar(80) NOT NULL COMMENT 'Trusted cookie hash',
`uid` mediumint unsigned NOT NULL COMMENT 'User ID',
`user_agent` text COMMENT 'User agent string',
+ `trusted` boolean NOT NULL DEFAULT '1' COMMENT 'Whenever this browser should be trusted or not',
`created` datetime NOT NULL COMMENT 'Datetime the trusted browser was recorded',
`last_used` datetime COMMENT 'Datetime the trusted browser was last used',
PRIMARY KEY(`cookie_hash`),
diff --git a/doc/database/db_2fa_trusted_browser.md b/doc/database/db_2fa_trusted_browser.md
index d12d9e1fc..18126b49f 100644
--- a/doc/database/db_2fa_trusted_browser.md
+++ b/doc/database/db_2fa_trusted_browser.md
@@ -6,13 +6,14 @@ Two-factor authentication trusted browsers
Fields
------
-| Field | Description | Type | Null | Key | Default | Extra |
-| ----------- | ------------------------------------------ | ------------------ | ---- | --- | ------- | ----- |
-| cookie_hash | Trusted cookie hash | varchar(80) | NO | PRI | NULL | |
-| uid | User ID | mediumint unsigned | NO | | NULL | |
-| user_agent | User agent string | text | YES | | NULL | |
-| created | Datetime the trusted browser was recorded | datetime | NO | | NULL | |
-| last_used | Datetime the trusted browser was last used | datetime | YES | | NULL | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| ----------- | ---------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
+| cookie_hash | Trusted cookie hash | varchar(80) | NO | PRI | NULL | |
+| uid | User ID | mediumint unsigned | NO | | NULL | |
+| user_agent | User agent string | text | YES | | NULL | |
+| trusted | Whenever this browser should be trusted or not | boolean | NO | | 1 | |
+| created | Datetime the trusted browser was recorded | datetime | NO | | NULL | |
+| last_used | Datetime the trusted browser was last used | datetime | YES | | NULL | |
Indexes
------------
diff --git a/src/Model/User/Cookie.php b/src/Model/User/Cookie.php
index aabb02820..4359d2107 100644
--- a/src/Model/User/Cookie.php
+++ b/src/Model/User/Cookie.php
@@ -124,6 +124,19 @@ class Cookie
}
}
+ /**
+ * Resets the cookie to a given data set
+ *
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function reset(array $data): bool
+ {
+ return $this->clear() &&
+ $this->setMultiple($data);
+ }
+
/**
* Clears the Friendica cookie
*/
@@ -131,7 +144,7 @@ class Cookie
{
$this->data = [];
// make sure cookie is deleted on browser close, as a security measure
- return $this->setCookie( '', -3600, $this->sslEnabled);
+ return $this->setCookie('', -3600, $this->sslEnabled);
}
/**
@@ -161,7 +174,7 @@ class Cookie
*
*/
protected function setCookie(string $value = null, int $expire = null,
- bool $secure = null): bool
+ bool $secure = null): bool
{
return setcookie(self::NAME, $value, $expire, self::PATH, self::DOMAIN, $secure, self::HTTPONLY);
}
diff --git a/src/Module/Security/Logout.php b/src/Module/Security/Logout.php
index 1ec076483..004292cb5 100644
--- a/src/Module/Security/Logout.php
+++ b/src/Module/Security/Logout.php
@@ -31,7 +31,6 @@ use Friendica\Core\System;
use Friendica\Model\Profile;
use Friendica\Model\User\Cookie;
use Friendica\Module\Response;
-use Friendica\Security\TwoFactor;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
@@ -46,17 +45,14 @@ class Logout extends BaseModule
protected $cookie;
/** @var IHandleSessions */
protected $session;
- /** @var TwoFactor\Repository\TrustedBrowser */
- protected $trustedBrowserRepo;
- public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, TwoFactor\Repository\TrustedBrowser $trustedBrowserRepo, ICanCache $cache, Cookie $cookie, IHandleSessions $session, array $server, array $parameters = [])
+ public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, ICanCache $cache, Cookie $cookie, IHandleSessions $session, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
- $this->cache = $cache;
- $this->cookie = $cookie;
- $this->session = $session;
- $this->trustedBrowserRepo = $trustedBrowserRepo;
+ $this->cache = $cache;
+ $this->cookie = $cookie;
+ $this->session = $session;
}
@@ -73,9 +69,9 @@ class Logout extends BaseModule
Hook::callAll("logging_out");
- // Remove this trusted browser as it won't be able to be used ever again after the cookie is cleared
- if ($this->cookie->get('trusted')) {
- $this->trustedBrowserRepo->removeForUser(local_user(), $this->cookie->get('trusted'));
+ // If this is a trusted browser, redirect to the 2fa signout page
+ if ($this->cookie->get('2fa_cookie_hash')) {
+ $this->baseUrl->redirect('2fa/signout');
}
$this->cookie->clear();
diff --git a/src/Module/Security/TwoFactor/SignOut.php b/src/Module/Security/TwoFactor/SignOut.php
new file mode 100644
index 000000000..20b7f039d
--- /dev/null
+++ b/src/Module/Security/TwoFactor/SignOut.php
@@ -0,0 +1,129 @@
+.
+ *
+ */
+
+namespace Friendica\Module\Security\TwoFactor;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleSessions;
+use Friendica\Model\User\Cookie;
+use Friendica\Module\Response;
+use Friendica\Network\HTTPException\NotFoundException;
+use Friendica\Util\Profiler;
+use Friendica\Security\TwoFactor;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Page 4: Logout dialog for trusted browsers
+ *
+ * @package Friendica\Module\TwoFactor
+ */
+class SignOut extends BaseModule
+{
+ protected $errors = [];
+
+ /** @var IHandleSessions */
+ protected $session;
+ /** @var Cookie */
+ protected $cookie;
+ /** @var TwoFactor\Repository\TrustedBrowser */
+ protected $trustedBrowserRepository;
+
+ public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, IHandleSessions $session, Cookie $cookie, TwoFactor\Repository\TrustedBrowser $trustedBrowserRepository, Profiler $profiler, Response $response, array $server, array $parameters = [])
+ {
+ parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
+
+ $this->session = $session;
+ $this->cookie = $cookie;
+ $this->trustedBrowserRepository = $trustedBrowserRepository;
+ }
+
+ protected function post(array $request = [])
+ {
+ if (!local_user() || !($this->cookie->get('2fa_cookie_hash'))) {
+ return;
+ }
+
+ $action = $request['action'] ?? '';
+
+ if (!empty($action)) {
+ self::checkFormSecurityTokenRedirectOnError('2fa', 'twofactor_signout');
+
+ switch ($action) {
+ case 'trust_and_sign_out':
+ $trusted = $this->cookie->get('2fa_cookie_hash');
+ $this->cookie->reset(['2fa_cookie_hash' => $trusted]);
+ $this->session->clear();
+
+ info($this->t('Logged out.'));
+ $this->baseUrl->redirect();
+ break;
+ case 'sign_out':
+ $this->trustedBrowserRepository->removeForUser(local_user(), $this->cookie->get('2fa_cookie_hash'));
+ $this->cookie->clear();
+ $this->session->clear();
+
+ info($this->t('Logged out.'));
+ $this->baseUrl->redirect();
+ break;
+ default:
+ $this->baseUrl->redirect();
+ }
+ }
+ }
+
+ protected function content(array $request = []): string
+ {
+ if (!local_user() || !($this->cookie->get('2fa_cookie_hash'))) {
+ $this->baseUrl->redirect();
+ }
+
+ try {
+ $trustedBrowser = $this->trustedBrowserRepository->selectOneByHash($this->cookie->get('2fa_cookie_hash'));
+ if (!$trustedBrowser->trusted) {
+ $trusted = $this->cookie->get('2fa_cookie_hash');
+ $this->cookie->reset(['2fa_cookie_hash' => $trusted]);
+ $this->session->clear();
+
+ info($this->t('Logged out.'));
+ $this->baseUrl->redirect();
+ }
+ } catch (NotFoundException $exception) {
+ $this->cookie->clear();
+ $this->session->clear();
+
+ info($this->t('Logged out.'));
+ $this->baseUrl->redirect();
+ }
+
+ return Renderer::replaceMacros(Renderer::getMarkupTemplate('twofactor/signout.tpl'), [
+ '$form_security_token' => self::getFormSecurityToken('twofactor_signout'),
+
+ '$title' => $this->t('Sign out of this browser?'),
+ '$message' => $this->t('
If you trust this browser, you will not be asked for verification code the next time you sign in.
'),
+ '$sign_out_label' => $this->t('Sign out'),
+ '$cancel_label' => $this->t('Cancel'),
+ '$trust_and_sign_out_label' => $this->t('Trust and sign out'),
+ ]);
+ }
+}
diff --git a/src/Module/Security/TwoFactor/Trust.php b/src/Module/Security/TwoFactor/Trust.php
new file mode 100644
index 000000000..a245e6be5
--- /dev/null
+++ b/src/Module/Security/TwoFactor/Trust.php
@@ -0,0 +1,126 @@
+.
+ *
+ */
+
+namespace Friendica\Module\Security\TwoFactor;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleSessions;
+use Friendica\Model\User;
+use Friendica\Model\User\Cookie;
+use Friendica\Module\Response;
+use Friendica\Network\HTTPException\NotFoundException;
+use Friendica\Security\Authentication;
+use Friendica\Util\Profiler;
+use Friendica\Security\TwoFactor;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Page 2: Trust Browser dialog
+ *
+ * @package Friendica\Module\TwoFactor
+ */
+class Trust extends BaseModule
+{
+ /** @var App */
+ protected $app;
+ /** @var Authentication */
+ protected $auth;
+ /** @var IHandleSessions */
+ protected $session;
+ /** @var Cookie */
+ protected $cookie;
+ /** @var TwoFactor\Factory\TrustedBrowser */
+ protected $trustedBrowserFactory;
+ /** @var TwoFactor\Repository\TrustedBrowser */
+ protected $trustedBrowserRepositoy;
+
+ public function __construct(App $app, Authentication $auth, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, IHandleSessions $session, Cookie $cookie, TwoFactor\Factory\TrustedBrowser $trustedBrowserFactory, TwoFactor\Repository\TrustedBrowser $trustedBrowserRepositoy, Response $response, array $server, array $parameters = [])
+ {
+ parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
+
+ $this->app = $app;
+ $this->auth = $auth;
+ $this->session = $session;
+ $this->cookie = $cookie;
+ $this->trustedBrowserFactory = $trustedBrowserFactory;
+ $this->trustedBrowserRepositoy = $trustedBrowserRepositoy;
+ }
+
+ protected function post(array $request = [])
+ {
+ if (!local_user() || !$this->session->get('2fa')) {
+ return;
+ }
+
+ $action = $request['action'] ?? '';
+
+ if (!empty($action)) {
+ self::checkFormSecurityTokenRedirectOnError('2fa', 'twofactor_trust');
+
+ switch ($action) {
+ case 'trust':
+ case 'dont_trust':
+ $trustedBrowser = $this->trustedBrowserFactory->createForUserWithUserAgent(local_user(), $this->server['HTTP_USER_AGENT'], $action === 'trust');
+ $this->trustedBrowserRepositoy->save($trustedBrowser);
+
+ // The string is sent to the browser to be sent back with each request
+ if (!$this->cookie->set('2fa_cookie_hash', $trustedBrowser->cookie_hash)) {
+ notice($this->t('Couldn\'t save browser to Cookie.'));
+ };
+ break;
+ }
+
+ $this->auth->setForUser($this->app, User::getById($this->app->getLoggedInUserId()), true, true);
+ }
+ }
+
+ protected function content(array $request = []): string
+ {
+ if (!local_user() || !$this->session->get('2fa')) {
+ $this->baseUrl->redirect();
+ }
+
+ if ($this->cookie->get('2fa_cookie_hash')) {
+ try {
+ $trustedBrowser = $this->trustedBrowserRepositoy->selectOneByHash($this->cookie->get('2fa_cookie_hash'));
+ if (!$trustedBrowser->trusted) {
+ $this->auth->setForUser($this->app, User::getById($this->app->getLoggedInUserId()), true, true);
+ $this->baseUrl->redirect();
+ }
+ } catch (NotFoundException $exception) {
+ $this->logger->notice('Trusted Browser of the cookie not found.', ['cookie_hash' => $this->cookie->get('trusted'), 'uid' => $this->app->getLoggedInUserId(), 'exception' => $exception]);
+ }
+ }
+
+ return Renderer::replaceMacros(Renderer::getMarkupTemplate('twofactor/trust.tpl'), [
+ '$form_security_token' => self::getFormSecurityToken('twofactor_trust'),
+
+ '$title' => $this->t('Trust this browser?'),
+ '$message' => $this->t('If you choose to trust this browser, you will not be asked for a verification code the next time you sign in.
'),
+ '$not_now_label' => $this->t('Not now'),
+ '$dont_trust_label' => $this->t('Don\'t trust'),
+ '$trust_label' => $this->t('Trust'),
+ ]);
+ }
+}
diff --git a/src/Module/Security/TwoFactor/Verify.php b/src/Module/Security/TwoFactor/Verify.php
index c6d129432..d0850aedc 100644
--- a/src/Module/Security/TwoFactor/Verify.php
+++ b/src/Module/Security/TwoFactor/Verify.php
@@ -21,13 +21,17 @@
namespace Friendica\Module\Security\TwoFactor;
+use Friendica\App;
use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Renderer;
-use Friendica\Core\Session;
-use Friendica\DI;
-use Friendica\Model\User;
+use Friendica\Core\Session\Capability\IHandleSessions;
+use Friendica\Module\Response;
+use Friendica\Util\Profiler;
use PragmaRX\Google2FA\Google2FA;
use Friendica\Security\TwoFactor;
+use Psr\Log\LoggerInterface;
/**
* Page 1: Authenticator code verification
@@ -36,7 +40,20 @@ use Friendica\Security\TwoFactor;
*/
class Verify extends BaseModule
{
- private static $errors = [];
+ protected $errors = [];
+
+ /** @var IHandleSessions */
+ protected $session;
+ /** @var IManagePersonalConfigValues */
+ protected $pConfig;
+
+ public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, IHandleSessions $session, array $server, array $parameters = [])
+ {
+ parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
+
+ $this->session = $session;
+ $this->pConfig = $pConfig;
+ }
protected function post(array $request = [])
{
@@ -44,36 +61,20 @@ class Verify extends BaseModule
return;
}
- if (($_POST['action'] ?? '') == 'verify') {
+ if (($request['action'] ?? '') === 'verify') {
self::checkFormSecurityTokenRedirectOnError('2fa', 'twofactor_verify');
- $a = DI::app();
+ $code = $request['verify_code'] ?? '';
- $code = $_POST['verify_code'] ?? '';
-
- $valid = (new Google2FA())->verifyKey(DI::pConfig()->get(local_user(), '2fa', 'secret'), $code);
+ $valid = (new Google2FA())->verifyKey($this->pConfig->get(local_user(), '2fa', 'secret'), $code);
// The same code can't be used twice even if it's valid
- if ($valid && Session::get('2fa') !== $code) {
- Session::set('2fa', $code);
+ if ($valid && $this->session->get('2fa') !== $code) {
+ $this->session->set('2fa', $code);
- // Trust this browser feature
- if (!empty($_REQUEST['trust_browser'])) {
- $trustedBrowserFactory = new TwoFactor\Factory\TrustedBrowser(DI::logger());
- $trustedBrowserRepository = new TwoFactor\Repository\TrustedBrowser(DI::dba(), DI::logger(), $trustedBrowserFactory);
-
- $trustedBrowser = $trustedBrowserFactory->createForUserWithUserAgent(local_user(), $_SERVER['HTTP_USER_AGENT']);
-
- $trustedBrowserRepository->save($trustedBrowser);
-
- // The string is sent to the browser to be sent back with each request
- DI::cookie()->set('trusted', $trustedBrowser->cookie_hash);
- }
-
- // Resume normal login workflow
- DI::auth()->setForUser($a, User::getById($a->getLoggedInUserId()), true, true);
+ $this->baseUrl->redirect('2fa/trust');
} else {
- self::$errors[] = DI::l10n()->t('Invalid code, please retry.');
+ $this->errors[] = $this->t('Invalid code, please retry.');
}
}
}
@@ -81,25 +82,24 @@ class Verify extends BaseModule
protected function content(array $request = []): string
{
if (!local_user()) {
- DI::baseUrl()->redirect();
+ $this->baseUrl->redirect();
}
// Already authenticated with 2FA token
- if (Session::get('2fa')) {
- DI::baseUrl()->redirect();
+ if ($this->session->get('2fa')) {
+ $this->baseUrl->redirect();
}
return Renderer::replaceMacros(Renderer::getMarkupTemplate('twofactor/verify.tpl'), [
'$form_security_token' => self::getFormSecurityToken('twofactor_verify'),
- '$title' => DI::l10n()->t('Two-factor authentication'),
- '$message' => DI::l10n()->t('Open the two-factor authentication app on your device to get an authentication code and verify your identity.
'),
- '$errors_label' => DI::l10n()->tt('Error', 'Errors', count(self::$errors)),
- '$errors' => self::$errors,
- '$recovery_message' => DI::l10n()->t('Don’t have your phone? Enter a two-factor recovery code ', '2fa/recovery'),
- '$verify_code' => ['verify_code', DI::l10n()->t('Please enter a code from your authentication app'), '', '', DI::l10n()->t('Required'), 'autofocus autocomplete="off" placeholder="000000"', 'tel'],
- '$trust_browser' => ['trust_browser', DI::l10n()->t('This is my two-factor authenticator app device'), !empty($_REQUEST['trust_browser'])],
- '$verify_label' => DI::l10n()->t('Verify code and complete login'),
+ '$title' => $this->t('Two-factor authentication'),
+ '$message' => $this->t('Open the two-factor authentication app on your device to get an authentication code and verify your identity.
'),
+ '$errors_label' => $this->tt('Error', 'Errors', count($this->errors)),
+ '$errors' => $this->errors,
+ '$recovery_message' => $this->t('If you do not have access to your authentication code you can use a two-factor recovery code .', '2fa/recovery'),
+ '$verify_code' => ['verify_code', $this->t('Please enter a code from your authentication app'), '', '', $this->t('Required'), 'autofocus autocomplete="one-time-code" placeholder="000000" inputmode="numeric" pattern="[0-9]*"'],
+ '$verify_label' => $this->t('Verify code and complete login'),
]);
}
}
diff --git a/src/Module/Settings/TwoFactor/Index.php b/src/Module/Settings/TwoFactor/Index.php
index 35c5d3cf9..0da49f317 100644
--- a/src/Module/Settings/TwoFactor/Index.php
+++ b/src/Module/Settings/TwoFactor/Index.php
@@ -24,6 +24,7 @@ namespace Friendica\Module\Settings\TwoFactor;
use Friendica\Core\Renderer;
use Friendica\Core\Session;
use Friendica\DI;
+use Friendica\Network\HTTPException\FoundException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Security\TwoFactor\Model\RecoveryCode;
use Friendica\Model\User;
@@ -44,8 +45,8 @@ class Index extends BaseSettings
try {
User::getIdFromPasswordAuthentication(local_user(), $_POST['password'] ?? '');
- $has_secret = (bool) DI::pConfig()->get(local_user(), '2fa', 'secret');
- $verified = DI::pConfig()->get(local_user(), '2fa', 'verified');
+ $has_secret = (bool)DI::pConfig()->get(local_user(), '2fa', 'secret');
+ $verified = DI::pConfig()->get(local_user(), '2fa', 'verified');
switch ($_POST['action'] ?? '') {
case 'enable':
@@ -54,7 +55,8 @@ class Index extends BaseSettings
DI::pConfig()->set(local_user(), '2fa', 'secret', $Google2FA->generateSecretKey(32));
- DI::baseUrl()->redirect('settings/2fa/recovery?t=' . self::getFormSecurityToken('settings_2fa_password'));
+ DI::baseUrl()
+ ->redirect('settings/2fa/recovery?t=' . self::getFormSecurityToken('settings_2fa_password'));
}
break;
case 'disable':
@@ -70,27 +72,33 @@ class Index extends BaseSettings
break;
case 'recovery':
if ($has_secret) {
- DI::baseUrl()->redirect('settings/2fa/recovery?t=' . self::getFormSecurityToken('settings_2fa_password'));
+ DI::baseUrl()
+ ->redirect('settings/2fa/recovery?t=' . self::getFormSecurityToken('settings_2fa_password'));
}
break;
case 'app_specific':
if ($has_secret) {
- DI::baseUrl()->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
+ DI::baseUrl()
+ ->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
}
break;
case 'trusted':
if ($has_secret) {
- DI::baseUrl()->redirect('settings/2fa/trusted?t=' . self::getFormSecurityToken('settings_2fa_password'));
+ DI::baseUrl()
+ ->redirect('settings/2fa/trusted?t=' . self::getFormSecurityToken('settings_2fa_password'));
}
break;
case 'configure':
if (!$verified) {
- DI::baseUrl()->redirect('settings/2fa/verify?t=' . self::getFormSecurityToken('settings_2fa_password'));
+ DI::baseUrl()
+ ->redirect('settings/2fa/verify?t=' . self::getFormSecurityToken('settings_2fa_password'));
}
break;
}
+ } catch (FoundException $exception) {
+ // Nothing to do here
} catch (\Exception $e) {
- notice(DI::l10n()->t('Wrong Password'));
+ notice(DI::l10n()->t($e->getMessage()));
}
}
diff --git a/src/Module/Settings/TwoFactor/Trusted.php b/src/Module/Settings/TwoFactor/Trusted.php
index 12327a591..d1c0476de 100644
--- a/src/Module/Settings/TwoFactor/Trusted.php
+++ b/src/Module/Settings/TwoFactor/Trusted.php
@@ -121,6 +121,7 @@ class Trusted extends BaseSettings
'os' => $result->os->family,
'device' => $result->device->family,
'browser' => $result->ua->family,
+ 'trusted_labeled' => $trustedBrowser->trusted ? $this->t('Yes') : $this->t('No'),
];
return $trustedBrowser->toArray() + $dates + $uaData;
@@ -135,7 +136,8 @@ class Trusted extends BaseSettings
'$device_label' => $this->t('Device'),
'$os_label' => $this->t('OS'),
'$browser_label' => $this->t('Browser'),
- '$created_label' => $this->t('Trusted'),
+ '$trusted_label' => $this->t('Trusted'),
+ '$created_label' => $this->t('Created At'),
'$last_used_label' => $this->t('Last Use'),
'$remove_label' => $this->t('Remove'),
'$remove_all_label' => $this->t('Remove All'),
diff --git a/src/Security/Authentication.php b/src/Security/Authentication.php
index aca4f2c23..a23d0c955 100644
--- a/src/Security/Authentication.php
+++ b/src/Security/Authentication.php
@@ -144,7 +144,7 @@ class Authentication
// Renew the cookie
$this->cookie->send();
- // Do the authentification if not done by now
+ // Do the authentication if not done by now
if (!$this->session->get('authenticated')) {
$this->setForUser($a, $user);
@@ -269,7 +269,11 @@ class Authentication
}
if (!$remember) {
+ $trusted = $this->cookie->get('2fa_cookie_hash') ?? null;
$this->cookie->clear();
+ if ($trusted) {
+ $this->cookie->set('2fa_cookie_hash', $trusted);
+ }
}
// if we haven't failed up this point, log them in.
@@ -407,11 +411,11 @@ class Authentication
}
// Case 1b: Check for trusted browser
- if ($this->cookie->get('trusted')) {
+ if ($this->cookie->get('2fa_cookie_hash')) {
// Retrieve a trusted_browser model based on cookie hash
$trustedBrowserRepository = new TrustedBrowser($this->dba, $this->logger);
try {
- $trustedBrowser = $trustedBrowserRepository->selectOneByHash($this->cookie->get('trusted'));
+ $trustedBrowser = $trustedBrowserRepository->selectOneByHash($this->cookie->get('2fa_cookie_hash'));
// Verify record ownership
if ($trustedBrowser->uid === $uid) {
// Update last_used date
@@ -420,10 +424,13 @@ class Authentication
// Save it to the database
$trustedBrowserRepository->save($trustedBrowser);
- // Set 2fa session key and return
- $this->session->set('2fa', true);
+ // Only use this entry, if its really trusted, otherwise just update the record and proceed
+ if ($trustedBrowser->trusted) {
+ // Set 2fa session key and return
+ $this->session->set('2fa', true);
- return;
+ return;
+ }
} else {
// Invalid trusted cookie value, removing it
$this->cookie->unset('trusted');
diff --git a/src/Security/TwoFactor/Factory/TrustedBrowser.php b/src/Security/TwoFactor/Factory/TrustedBrowser.php
index 61ec154fc..21961f7ef 100644
--- a/src/Security/TwoFactor/Factory/TrustedBrowser.php
+++ b/src/Security/TwoFactor/Factory/TrustedBrowser.php
@@ -27,7 +27,7 @@ use Friendica\Util\Strings;
class TrustedBrowser extends BaseFactory
{
- public function createForUserWithUserAgent($uid, $userAgent): \Friendica\Security\TwoFactor\Model\TrustedBrowser
+ public function createForUserWithUserAgent(int $uid, string $userAgent, bool $trusted): \Friendica\Security\TwoFactor\Model\TrustedBrowser
{
$trustedHash = Strings::getRandomHex();
@@ -35,6 +35,7 @@ class TrustedBrowser extends BaseFactory
$trustedHash,
$uid,
$userAgent,
+ $trusted,
DateTimeFormat::utcNow()
);
}
@@ -45,6 +46,7 @@ class TrustedBrowser extends BaseFactory
$row['cookie_hash'],
$row['uid'],
$row['user_agent'],
+ $row['trusted'],
$row['created'],
$row['last_used']
);
diff --git a/src/Security/TwoFactor/Model/TrustedBrowser.php b/src/Security/TwoFactor/Model/TrustedBrowser.php
index d0a654d5f..cd9d2007e 100644
--- a/src/Security/TwoFactor/Model/TrustedBrowser.php
+++ b/src/Security/TwoFactor/Model/TrustedBrowser.php
@@ -31,6 +31,7 @@ use Friendica\Util\DateTimeFormat;
* @property-read $cookie_hash
* @property-read $uid
* @property-read $user_agent
+ * @property-read $trusted
* @property-read $created
* @property-read $last_used
* @package Friendica\Model\TwoFactor
@@ -40,6 +41,7 @@ class TrustedBrowser extends BaseEntity
protected $cookie_hash;
protected $uid;
protected $user_agent;
+ protected $trusted;
protected $created;
protected $last_used;
@@ -51,16 +53,18 @@ class TrustedBrowser extends BaseEntity
* @param string $cookie_hash
* @param int $uid
* @param string $user_agent
+ * @param bool $trusted
* @param string $created
* @param string|null $last_used
*/
- public function __construct(string $cookie_hash, int $uid, string $user_agent, string $created, string $last_used = null)
+ public function __construct(string $cookie_hash, int $uid, string $user_agent, bool $trusted, string $created, string $last_used = null)
{
$this->cookie_hash = $cookie_hash;
- $this->uid = $uid;
- $this->user_agent = $user_agent;
- $this->created = $created;
- $this->last_used = $last_used;
+ $this->uid = $uid;
+ $this->user_agent = $user_agent;
+ $this->trusted = $trusted;
+ $this->created = $created;
+ $this->last_used = $last_used;
}
public function recordUse()
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index c48da6a09..758c33d0d 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -55,7 +55,7 @@
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1472);
+ define('DB_UPDATE_VERSION', 1473);
}
return [
@@ -358,6 +358,7 @@ return [
"cookie_hash" => ["type" => "varchar(80)", "not null" => "1", "primary" => "1", "comment" => "Trusted cookie hash"],
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "foreign" => ["user" => "uid"], "comment" => "User ID"],
"user_agent" => ["type" => "text", "comment" => "User agent string"],
+ "trusted" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "Whenever this browser should be trusted or not"],
"created" => ["type" => "datetime", "not null" => "1", "comment" => "Datetime the trusted browser was recorded"],
"last_used" => ["type" => "datetime", "comment" => "Datetime the trusted browser was last used"],
],
diff --git a/static/routes.config.php b/static/routes.config.php
index 72964d230..dac56a125 100644
--- a/static/routes.config.php
+++ b/static/routes.config.php
@@ -165,6 +165,8 @@ return [
'/2fa' => [
'[/]' => [Module\Security\TwoFactor\Verify::class, [R::GET, R::POST]],
'/recovery' => [Module\Security\TwoFactor\Recovery::class, [R::GET, R::POST]],
+ '/trust' => [Module\Security\TwoFactor\Trust::class, [R::GET, R::POST]],
+ '/signout' => [Module\Security\TwoFactor\SignOut::class, [R::GET, R::POST]],
],
'/api' => [
diff --git a/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php b/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php
index 84a118eb8..7bb07a133 100644
--- a/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php
+++ b/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php
@@ -38,6 +38,7 @@ class TrustedBrowserTest extends MockedTest
'uid' => 42,
'user_agent' => 'PHPUnit',
'created' => DateTimeFormat::utcNow(),
+ 'trusted' => true,
'last_used' => null,
];
@@ -57,6 +58,7 @@ class TrustedBrowserTest extends MockedTest
'uid' => null,
'user_agent' => null,
'created' => null,
+ 'trusted' => true,
'last_used' => null,
];
@@ -69,14 +71,15 @@ class TrustedBrowserTest extends MockedTest
{
$factory = new TrustedBrowser(new NullLogger());
- $uid = 42;
+ $uid = 42;
$userAgent = 'PHPUnit';
- $trustedBrowser = $factory->createForUserWithUserAgent($uid, $userAgent);
+ $trustedBrowser = $factory->createForUserWithUserAgent($uid, $userAgent, true);
$this->assertNotEmpty($trustedBrowser->cookie_hash);
$this->assertEquals($uid, $trustedBrowser->uid);
$this->assertEquals($userAgent, $trustedBrowser->user_agent);
+ $this->assertTrue($trustedBrowser->trusted);
$this->assertNotEmpty($trustedBrowser->created);
}
}
diff --git a/tests/src/Security/TwoFactor/Model/TrustedBrowserTest.php b/tests/src/Security/TwoFactor/Model/TrustedBrowserTest.php
index 0c91ea5e5..cf5db0ffd 100644
--- a/tests/src/Security/TwoFactor/Model/TrustedBrowserTest.php
+++ b/tests/src/Security/TwoFactor/Model/TrustedBrowserTest.php
@@ -36,12 +36,14 @@ class TrustedBrowserTest extends MockedTest
$hash,
42,
'PHPUnit',
+ true,
DateTimeFormat::utcNow()
);
$this->assertEquals($hash, $trustedBrowser->cookie_hash);
$this->assertEquals(42, $trustedBrowser->uid);
$this->assertEquals('PHPUnit', $trustedBrowser->user_agent);
+ $this->assertTrue($trustedBrowser->trusted);
$this->assertNotEmpty($trustedBrowser->created);
}
@@ -54,6 +56,7 @@ class TrustedBrowserTest extends MockedTest
$hash,
42,
'PHPUnit',
+ true,
$past,
$past
);
diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po
index 333a0aaa6..3a29f7768 100644
--- a/view/lang/C/messages.po
+++ b/view/lang/C/messages.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2022.09-dev\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-06-13 05:45+0000\n"
+"POT-Creation-Date: 2022-06-25 22:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -28,7 +28,7 @@ msgid "Access denied."
msgstr ""
#: mod/cal.php:63 mod/cal.php:80 mod/photos.php:69 mod/photos.php:140
-#: mod/photos.php:798 src/Model/Profile.php:231 src/Module/Feed.php:72
+#: mod/photos.php:798 src/Model/Profile.php:232 src/Module/Feed.php:72
#: src/Module/HCard.php:52 src/Module/Profile/Common.php:41
#: src/Module/Profile/Common.php:52 src/Module/Profile/Contacts.php:40
#: src/Module/Profile/Contacts.php:50 src/Module/Profile/Media.php:38
@@ -62,21 +62,21 @@ msgstr ""
msgid "Next"
msgstr ""
-#: mod/cal.php:249 mod/events.php:383 src/Model/Event.php:457
+#: mod/cal.php:249 mod/events.php:383 src/Model/Event.php:456
msgid "today"
msgstr ""
-#: mod/cal.php:250 mod/events.php:384 src/Model/Event.php:458
+#: mod/cal.php:250 mod/events.php:384 src/Model/Event.php:457
#: src/Util/Temporal.php:334
msgid "month"
msgstr ""
-#: mod/cal.php:251 mod/events.php:385 src/Model/Event.php:459
+#: mod/cal.php:251 mod/events.php:385 src/Model/Event.php:458
#: src/Util/Temporal.php:335
msgid "week"
msgstr ""
-#: mod/cal.php:252 mod/events.php:386 src/Model/Event.php:460
+#: mod/cal.php:252 mod/events.php:386 src/Model/Event.php:459
#: src/Util/Temporal.php:336
msgid "day"
msgstr ""
@@ -106,7 +106,7 @@ msgstr ""
#: mod/display.php:143 mod/photos.php:802
#: src/Module/Conversation/Community.php:175 src/Module/Directory.php:49
-#: src/Module/Search/Index.php:50
+#: src/Module/Search/Index.php:65
msgid "Public access denied."
msgstr ""
@@ -159,13 +159,13 @@ msgstr ""
msgid "Edit post"
msgstr ""
-#: mod/editpost.php:91 mod/notes.php:56 src/Content/Text/HTML.php:875
+#: mod/editpost.php:91 mod/notes.php:56 src/Content/Text/HTML.php:882
#: src/Module/Admin/Storage.php:142 src/Module/Filer/SaveTag.php:73
msgid "Save"
msgstr ""
#: mod/editpost.php:92 mod/photos.php:1338 src/Content/Conversation.php:338
-#: src/Module/Contact/Poke.php:176 src/Object/Post.php:989
+#: src/Module/Contact/Poke.php:176 src/Object/Post.php:993
msgid "Loading..."
msgstr ""
@@ -231,7 +231,7 @@ msgstr ""
#: mod/editpost.php:107 mod/message.php:200 mod/message.php:358
#: mod/photos.php:1489 mod/wallmessage.php:142 src/Content/Conversation.php:368
#: src/Content/Conversation.php:713 src/Module/Item/Compose.php:177
-#: src/Object/Post.php:528
+#: src/Object/Post.php:538
msgid "Please wait"
msgstr ""
@@ -263,7 +263,7 @@ msgstr ""
#: mod/editpost.php:128 mod/events.php:513 mod/photos.php:1337
#: mod/photos.php:1393 mod/photos.php:1467 src/Content/Conversation.php:383
-#: src/Module/Item/Compose.php:172 src/Object/Post.php:999
+#: src/Module/Item/Compose.php:172 src/Object/Post.php:1003
msgid "Preview"
msgstr ""
@@ -271,52 +271,53 @@ msgstr ""
#: mod/follow.php:144 mod/photos.php:1004 mod/photos.php:1105 mod/tagrm.php:35
#: mod/tagrm.php:127 mod/unfollow.php:97 src/Content/Conversation.php:386
#: src/Module/Contact/Revoke.php:108 src/Module/RemoteFollow.php:127
+#: src/Module/Security/TwoFactor/Signout.php:125
msgid "Cancel"
msgstr ""
#: mod/editpost.php:134 src/Content/Conversation.php:343
-#: src/Module/Item/Compose.php:163 src/Object/Post.php:990
+#: src/Module/Item/Compose.php:163 src/Object/Post.php:994
msgid "Bold"
msgstr ""
#: mod/editpost.php:135 src/Content/Conversation.php:344
-#: src/Module/Item/Compose.php:164 src/Object/Post.php:991
+#: src/Module/Item/Compose.php:164 src/Object/Post.php:995
msgid "Italic"
msgstr ""
#: mod/editpost.php:136 src/Content/Conversation.php:345
-#: src/Module/Item/Compose.php:165 src/Object/Post.php:992
+#: src/Module/Item/Compose.php:165 src/Object/Post.php:996
msgid "Underline"
msgstr ""
#: mod/editpost.php:137 src/Content/Conversation.php:346
-#: src/Module/Item/Compose.php:166 src/Object/Post.php:993
+#: src/Module/Item/Compose.php:166 src/Object/Post.php:997
msgid "Quote"
msgstr ""
#: mod/editpost.php:138 src/Content/Conversation.php:347
-#: src/Module/Item/Compose.php:167 src/Object/Post.php:994
+#: src/Module/Item/Compose.php:167 src/Object/Post.php:998
msgid "Code"
msgstr ""
#: mod/editpost.php:139 src/Content/Conversation.php:349
-#: src/Module/Item/Compose.php:169 src/Object/Post.php:996
+#: src/Module/Item/Compose.php:169 src/Object/Post.php:1000
msgid "Link"
msgstr ""
#: mod/editpost.php:140 src/Content/Conversation.php:350
-#: src/Module/Item/Compose.php:170 src/Object/Post.php:997
+#: src/Module/Item/Compose.php:170 src/Object/Post.php:1001
msgid "Link or Media"
msgstr ""
#: mod/editpost.php:143 src/Content/Conversation.php:393
-#: src/Content/Widget/VCard.php:113 src/Model/Profile.php:462
+#: src/Content/Widget/VCard.php:113 src/Model/Profile.php:463
#: src/Module/Admin/Logs/View.php:93
msgid "Message"
msgstr ""
#: mod/editpost.php:144 src/Content/Conversation.php:394
-#: src/Module/Settings/TwoFactor/Trusted.php:137
+#: src/Module/Settings/TwoFactor/Trusted.php:138
msgid "Browser"
msgstr ""
@@ -366,8 +367,8 @@ msgstr ""
#: src/Module/Install.php:286 src/Module/Install.php:291
#: src/Module/Install.php:305 src/Module/Install.php:320
#: src/Module/Install.php:347 src/Module/Register.php:148
-#: src/Module/Security/TwoFactor/Verify.php:100
-#: src/Module/Settings/TwoFactor/Index.php:133
+#: src/Module/Security/TwoFactor/Verify.php:101
+#: src/Module/Settings/TwoFactor/Index.php:136
#: src/Module/Settings/TwoFactor/Verify.php:154
msgid "Required"
msgstr ""
@@ -386,8 +387,8 @@ msgid "Description:"
msgstr ""
#: mod/events.php:504 src/Content/Widget/VCard.php:104 src/Model/Event.php:80
-#: src/Model/Event.php:107 src/Model/Event.php:466 src/Model/Event.php:915
-#: src/Model/Profile.php:370 src/Module/Contact/Profile.php:369
+#: src/Model/Event.php:107 src/Model/Event.php:465 src/Model/Event.php:915
+#: src/Model/Profile.php:371 src/Module/Contact/Profile.php:369
#: src/Module/Directory.php:148 src/Module/Notifications/Introductions.php:185
#: src/Module/Profile/Profile.php:194
msgid "Location:"
@@ -413,7 +414,7 @@ msgstr ""
#: src/Module/Install.php:252 src/Module/Install.php:294
#: src/Module/Install.php:331 src/Module/Invite.php:178
#: src/Module/Item/Compose.php:162 src/Module/Profile/Profile.php:247
-#: src/Module/Settings/Profile/Index.php:222 src/Object/Post.php:988
+#: src/Module/Settings/Profile/Index.php:222 src/Object/Post.php:992
#: view/theme/duepuntozero/config.php:69 view/theme/frio/config.php:160
#: view/theme/quattro/config.php:71 view/theme/vier/config.php:119
msgid "Submit"
@@ -466,8 +467,8 @@ msgstr ""
msgid "OStatus support is disabled. Contact can't be added."
msgstr ""
-#: mod/follow.php:138 src/Content/Item.php:443 src/Content/Widget.php:78
-#: src/Model/Contact.php:1102 src/Model/Contact.php:1114
+#: mod/follow.php:138 src/Content/Item.php:443 src/Content/Widget.php:80
+#: src/Model/Contact.php:1103 src/Model/Contact.php:1115
#: view/theme/vier/theme.php:172
msgid "Connect/Follow"
msgstr ""
@@ -1068,16 +1069,16 @@ msgstr ""
#: mod/photos.php:1333 mod/photos.php:1389 mod/photos.php:1463
#: src/Module/Contact.php:544 src/Module/Item/Compose.php:160
-#: src/Object/Post.php:985
+#: src/Object/Post.php:989
msgid "This is you"
msgstr ""
#: mod/photos.php:1335 mod/photos.php:1391 mod/photos.php:1465
-#: src/Object/Post.php:522 src/Object/Post.php:987
+#: src/Object/Post.php:532 src/Object/Post.php:991
msgid "Comment"
msgstr ""
-#: mod/photos.php:1424 src/Content/Conversation.php:629 src/Object/Post.php:247
+#: mod/photos.php:1424 src/Content/Conversation.php:629 src/Object/Post.php:256
msgid "Select"
msgstr ""
@@ -1087,19 +1088,19 @@ msgstr ""
msgid "Delete"
msgstr ""
-#: mod/photos.php:1486 src/Object/Post.php:369
+#: mod/photos.php:1486 src/Object/Post.php:379
msgid "Like"
msgstr ""
-#: mod/photos.php:1487 src/Object/Post.php:369
+#: mod/photos.php:1487 src/Object/Post.php:379
msgid "I like this (toggle)"
msgstr ""
-#: mod/photos.php:1488 src/Object/Post.php:370
+#: mod/photos.php:1488 src/Object/Post.php:380
msgid "Dislike"
msgstr ""
-#: mod/photos.php:1490 src/Object/Post.php:370
+#: mod/photos.php:1490 src/Object/Post.php:380
msgid "I don't like this (toggle)"
msgstr ""
@@ -1128,7 +1129,7 @@ msgstr ""
msgid "Contact not found."
msgstr ""
-#: mod/removeme.php:65 src/Navigation/Notifications/Repository/Notify.php:482
+#: mod/removeme.php:65 src/Navigation/Notifications/Repository/Notify.php:483
msgid "[Friendica System Notify]"
msgstr ""
@@ -1166,7 +1167,7 @@ msgid "Resubscribing to OStatus contacts"
msgstr ""
#: mod/repair_ostatus.php:46 src/Module/Debug/ActivityPubConversion.php:134
-#: src/Module/Debug/Babel.php:293 src/Module/Security/TwoFactor/Verify.php:97
+#: src/Module/Debug/Babel.php:293 src/Module/Security/TwoFactor/Verify.php:98
msgid "Error"
msgid_plural "Errors"
msgstr[0] ""
@@ -1404,11 +1405,11 @@ msgid ""
"hours."
msgstr ""
-#: mod/suggest.php:55 src/Content/Widget.php:81 view/theme/vier/theme.php:175
+#: mod/suggest.php:55 src/Content/Widget.php:83 view/theme/vier/theme.php:175
msgid "Friend Suggestions"
msgstr ""
-#: mod/tagger.php:78 src/Content/Item.php:342 src/Model/Item.php:2699
+#: mod/tagger.php:78 src/Content/Item.php:342 src/Model/Item.php:2728
msgid "photo"
msgstr ""
@@ -1430,7 +1431,7 @@ msgid "Select a tag to remove: "
msgstr ""
#: mod/tagrm.php:126 src/Module/Settings/Delegation.php:179
-#: src/Module/Settings/TwoFactor/Trusted.php:140
+#: src/Module/Settings/TwoFactor/Trusted.php:142
msgid "Remove"
msgstr ""
@@ -1522,7 +1523,7 @@ msgstr ""
msgid "File upload failed."
msgstr ""
-#: mod/wall_upload.php:218 src/Model/Photo.php:1061
+#: mod/wall_upload.php:218 src/Model/Photo.php:1085
msgid "Wall Photos"
msgstr ""
@@ -1546,11 +1547,11 @@ msgid ""
"your site allow private mail from unknown senders."
msgstr ""
-#: src/App.php:463
+#: src/App.php:473
msgid "No system theme config value set."
msgstr ""
-#: src/App.php:584
+#: src/App.php:594
msgid "Apologies but the website is unavailable at the moment."
msgstr ""
@@ -1568,56 +1569,56 @@ msgstr ""
msgid "toggle mobile"
msgstr ""
-#: src/App/Router.php:275
+#: src/App/Router.php:282
#, php-format
msgid "Method not allowed for this module. Allowed method(s): %s"
msgstr ""
-#: src/App/Router.php:277 src/Module/HTTPException/PageNotFound.php:34
+#: src/App/Router.php:284 src/Module/HTTPException/PageNotFound.php:49
msgid "Page not found."
msgstr ""
-#: src/App/Router.php:305
+#: src/App/Router.php:312
msgid "You must be logged in to use addons. "
msgstr ""
-#: src/BaseModule.php:377
+#: src/BaseModule.php:392
msgid ""
"The form security token was not correct. This probably happened because the "
"form has been opened for too long (>3 hours) before submitting it."
msgstr ""
-#: src/BaseModule.php:404
+#: src/BaseModule.php:419
msgid "All contacts"
msgstr ""
-#: src/BaseModule.php:409 src/Content/Widget.php:233 src/Core/ACL.php:194
+#: src/BaseModule.php:424 src/Content/Widget.php:235 src/Core/ACL.php:194
#: src/Module/Contact.php:367 src/Module/PermissionTooltip.php:122
#: src/Module/PermissionTooltip.php:144
msgid "Followers"
msgstr ""
-#: src/BaseModule.php:414 src/Content/Widget.php:234 src/Module/Contact.php:368
+#: src/BaseModule.php:429 src/Content/Widget.php:236 src/Module/Contact.php:368
msgid "Following"
msgstr ""
-#: src/BaseModule.php:419 src/Content/Widget.php:235 src/Module/Contact.php:369
+#: src/BaseModule.php:434 src/Content/Widget.php:237 src/Module/Contact.php:369
msgid "Mutual friends"
msgstr ""
-#: src/BaseModule.php:427
+#: src/BaseModule.php:442
msgid "Common"
msgstr ""
-#: src/Console/Addon.php:177 src/Console/Addon.php:202
+#: src/Console/Addon.php:175 src/Console/Addon.php:199
msgid "Addon not found"
msgstr ""
-#: src/Console/Addon.php:181
+#: src/Console/Addon.php:179
msgid "Addon already enabled"
msgstr ""
-#: src/Console/Addon.php:206
+#: src/Console/Addon.php:203
msgid "Addon already disabled"
msgstr ""
@@ -1840,78 +1841,78 @@ msgstr ""
msgid "Monthly"
msgstr ""
-#: src/Content/ContactSelector.php:123
+#: src/Content/ContactSelector.php:126
msgid "DFRN"
msgstr ""
-#: src/Content/ContactSelector.php:124
+#: src/Content/ContactSelector.php:127
msgid "OStatus"
msgstr ""
-#: src/Content/ContactSelector.php:125
+#: src/Content/ContactSelector.php:128
msgid "RSS/Atom"
msgstr ""
-#: src/Content/ContactSelector.php:126 src/Module/Admin/Users/Active.php:129
+#: src/Content/ContactSelector.php:129 src/Module/Admin/Users/Active.php:129
#: src/Module/Admin/Users/Blocked.php:130 src/Module/Admin/Users/Create.php:73
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:142
#: src/Module/Admin/Users/Index.php:162 src/Module/Admin/Users/Pending.php:104
msgid "Email"
msgstr ""
-#: src/Content/ContactSelector.php:127 src/Module/Debug/Babel.php:307
+#: src/Content/ContactSelector.php:130 src/Module/Debug/Babel.php:307
msgid "Diaspora"
msgstr ""
-#: src/Content/ContactSelector.php:128
+#: src/Content/ContactSelector.php:131
msgid "Zot!"
msgstr ""
-#: src/Content/ContactSelector.php:129
+#: src/Content/ContactSelector.php:132
msgid "LinkedIn"
msgstr ""
-#: src/Content/ContactSelector.php:130
+#: src/Content/ContactSelector.php:133
msgid "XMPP/IM"
msgstr ""
-#: src/Content/ContactSelector.php:131
+#: src/Content/ContactSelector.php:134
msgid "MySpace"
msgstr ""
-#: src/Content/ContactSelector.php:132
+#: src/Content/ContactSelector.php:135
msgid "Google+"
msgstr ""
-#: src/Content/ContactSelector.php:133
+#: src/Content/ContactSelector.php:136
msgid "pump.io"
msgstr ""
-#: src/Content/ContactSelector.php:134
+#: src/Content/ContactSelector.php:137
msgid "Twitter"
msgstr ""
-#: src/Content/ContactSelector.php:135
+#: src/Content/ContactSelector.php:138
msgid "Discourse"
msgstr ""
-#: src/Content/ContactSelector.php:136
+#: src/Content/ContactSelector.php:139
msgid "Diaspora Connector"
msgstr ""
-#: src/Content/ContactSelector.php:137
+#: src/Content/ContactSelector.php:140
msgid "GNU Social Connector"
msgstr ""
-#: src/Content/ContactSelector.php:138
+#: src/Content/ContactSelector.php:141
msgid "ActivityPub"
msgstr ""
-#: src/Content/ContactSelector.php:139
+#: src/Content/ContactSelector.php:142
msgid "pnut"
msgstr ""
-#: src/Content/ContactSelector.php:175
+#: src/Content/ContactSelector.php:178
#, php-format
msgid "%s (via %s)"
msgstr ""
@@ -2016,7 +2017,7 @@ msgid "Visible to everybody "
msgstr ""
#: src/Content/Conversation.php:308 src/Module/Item/Compose.php:171
-#: src/Object/Post.php:998
+#: src/Object/Post.php:1002
msgid "Please enter a image/video/audio/webpage URL:"
msgstr ""
@@ -2049,7 +2050,7 @@ msgid "Share"
msgstr ""
#: src/Content/Conversation.php:348 src/Module/Item/Compose.php:168
-#: src/Object/Post.php:995
+#: src/Object/Post.php:999
msgid "Image"
msgstr ""
@@ -2061,25 +2062,25 @@ msgstr ""
msgid "Scheduled at"
msgstr ""
-#: src/Content/Conversation.php:657 src/Object/Post.php:235
+#: src/Content/Conversation.php:657 src/Object/Post.php:244
msgid "Pinned item"
msgstr ""
-#: src/Content/Conversation.php:673 src/Object/Post.php:476
-#: src/Object/Post.php:477
+#: src/Content/Conversation.php:673 src/Object/Post.php:486
+#: src/Object/Post.php:487
#, php-format
msgid "View %s's profile @ %s"
msgstr ""
-#: src/Content/Conversation.php:686 src/Object/Post.php:464
+#: src/Content/Conversation.php:686 src/Object/Post.php:474
msgid "Categories:"
msgstr ""
-#: src/Content/Conversation.php:687 src/Object/Post.php:465
+#: src/Content/Conversation.php:687 src/Object/Post.php:475
msgid "Filed under:"
msgstr ""
-#: src/Content/Conversation.php:695 src/Object/Post.php:490
+#: src/Content/Conversation.php:695 src/Object/Post.php:500
#, php-format
msgid "%s from %s"
msgstr ""
@@ -2250,7 +2251,7 @@ msgid "Display membership date in profile"
msgstr ""
#: src/Content/ForumManager.php:151 src/Content/Nav.php:239
-#: src/Content/Text/HTML.php:896 src/Content/Widget.php:522
+#: src/Content/Text/HTML.php:903 src/Content/Widget.php:524
msgid "Forums"
msgstr ""
@@ -2258,12 +2259,12 @@ msgstr ""
msgid "External link to forum"
msgstr ""
-#: src/Content/ForumManager.php:156 src/Content/Widget.php:501
+#: src/Content/ForumManager.php:156 src/Content/Widget.php:503
msgid "show less"
msgstr ""
-#: src/Content/ForumManager.php:157 src/Content/Widget.php:403
-#: src/Content/Widget.php:502
+#: src/Content/ForumManager.php:157 src/Content/Widget.php:405
+#: src/Content/Widget.php:504
msgid "show more"
msgstr ""
@@ -2272,7 +2273,7 @@ msgstr ""
msgid "%1$s poked %2$s"
msgstr ""
-#: src/Content/Item.php:334 src/Model/Item.php:2697
+#: src/Content/Item.php:334 src/Model/Item.php:2726
msgid "event"
msgstr ""
@@ -2280,31 +2281,31 @@ msgstr ""
msgid "Follow Thread"
msgstr ""
-#: src/Content/Item.php:423 src/Model/Contact.php:1107
+#: src/Content/Item.php:423 src/Model/Contact.php:1108
msgid "View Status"
msgstr ""
-#: src/Content/Item.php:424 src/Content/Item.php:446 src/Model/Contact.php:1041
-#: src/Model/Contact.php:1099 src/Model/Contact.php:1108
+#: src/Content/Item.php:424 src/Content/Item.php:446 src/Model/Contact.php:1042
+#: src/Model/Contact.php:1100 src/Model/Contact.php:1109
#: src/Module/Directory.php:158 src/Module/Settings/Profile/Index.php:225
msgid "View Profile"
msgstr ""
-#: src/Content/Item.php:425 src/Model/Contact.php:1109
+#: src/Content/Item.php:425 src/Model/Contact.php:1110
msgid "View Photos"
msgstr ""
-#: src/Content/Item.php:426 src/Model/Contact.php:1100
-#: src/Model/Contact.php:1110
+#: src/Content/Item.php:426 src/Model/Contact.php:1101
+#: src/Model/Contact.php:1111
msgid "Network Posts"
msgstr ""
-#: src/Content/Item.php:427 src/Model/Contact.php:1101
-#: src/Model/Contact.php:1111
+#: src/Content/Item.php:427 src/Model/Contact.php:1102
+#: src/Model/Contact.php:1112
msgid "View Contact"
msgstr ""
-#: src/Content/Item.php:428 src/Model/Contact.php:1112
+#: src/Content/Item.php:428 src/Model/Contact.php:1113
msgid "Send PM"
msgstr ""
@@ -2323,11 +2324,11 @@ msgstr ""
msgid "Ignore"
msgstr ""
-#: src/Content/Item.php:434 src/Object/Post.php:445
+#: src/Content/Item.php:434 src/Object/Post.php:455
msgid "Languages"
msgstr ""
-#: src/Content/Item.php:438 src/Model/Contact.php:1113
+#: src/Content/Item.php:438 src/Model/Contact.php:1114
msgid "Poke"
msgstr ""
@@ -2343,7 +2344,7 @@ msgstr ""
msgid "Clear notifications"
msgstr ""
-#: src/Content/Nav.php:96 src/Content/Text/HTML.php:883
+#: src/Content/Nav.php:96 src/Content/Text/HTML.php:890
msgid "@name, !forum, #tags, content"
msgstr ""
@@ -2366,7 +2367,7 @@ msgstr ""
#: src/Content/Nav.php:190 src/Module/BaseProfile.php:56
#: src/Module/Contact.php:433 src/Module/Contact/Profile.php:380
-#: src/Module/Settings/TwoFactor/Index.php:112 view/theme/frio/theme.php:225
+#: src/Module/Settings/TwoFactor/Index.php:115 view/theme/frio/theme.php:225
msgid "Status"
msgstr ""
@@ -2427,7 +2428,7 @@ msgstr ""
#: src/Content/Nav.php:222 src/Module/Help.php:67
#: src/Module/Settings/TwoFactor/AppSpecific.php:127
-#: src/Module/Settings/TwoFactor/Index.php:111
+#: src/Module/Settings/TwoFactor/Index.php:114
#: src/Module/Settings/TwoFactor/Recovery.php:105
#: src/Module/Settings/TwoFactor/Verify.php:145 view/theme/vier/theme.php:217
msgid "Help"
@@ -2445,8 +2446,8 @@ msgstr ""
msgid "Addon applications, utilities, games"
msgstr ""
-#: src/Content/Nav.php:230 src/Content/Text/HTML.php:881
-#: src/Module/Admin/Logs/View.php:87 src/Module/Search/Index.php:97
+#: src/Content/Nav.php:230 src/Content/Text/HTML.php:888
+#: src/Module/Admin/Logs/View.php:87 src/Module/Search/Index.php:112
msgid "Search"
msgstr ""
@@ -2454,17 +2455,17 @@ msgstr ""
msgid "Search site content"
msgstr ""
-#: src/Content/Nav.php:233 src/Content/Text/HTML.php:890
+#: src/Content/Nav.php:233 src/Content/Text/HTML.php:897
msgid "Full Text"
msgstr ""
-#: src/Content/Nav.php:234 src/Content/Text/HTML.php:891
+#: src/Content/Nav.php:234 src/Content/Text/HTML.php:898
#: src/Content/Widget/TagCloud.php:68
msgid "Tags"
msgstr ""
#: src/Content/Nav.php:235 src/Content/Nav.php:294
-#: src/Content/Text/HTML.php:892 src/Module/BaseProfile.php:125
+#: src/Content/Text/HTML.php:899 src/Module/BaseProfile.php:125
#: src/Module/BaseProfile.php:128 src/Module/Contact.php:370
#: src/Module/Contact.php:464 view/theme/frio/theme.php:236
msgid "Contacts"
@@ -2491,7 +2492,7 @@ msgstr ""
msgid "People directory"
msgstr ""
-#: src/Content/Nav.php:263 src/Module/BaseAdmin.php:85
+#: src/Content/Nav.php:263 src/Module/BaseAdmin.php:88
msgid "Information"
msgstr ""
@@ -2500,7 +2501,7 @@ msgid "Information about this friendica instance"
msgstr ""
#: src/Content/Nav.php:266 src/Module/Admin/Tos.php:76
-#: src/Module/BaseAdmin.php:96 src/Module/Register.php:176
+#: src/Module/BaseAdmin.php:99 src/Module/Register.php:176
#: src/Module/Tos.php:87
msgid "Terms of Service"
msgstr ""
@@ -2572,7 +2573,7 @@ msgstr ""
msgid "Manage/edit friends and contacts"
msgstr ""
-#: src/Content/Nav.php:299 src/Module/BaseAdmin.php:126
+#: src/Content/Nav.php:299 src/Module/BaseAdmin.php:129
msgid "Admin"
msgstr ""
@@ -2612,8 +2613,8 @@ msgstr ""
msgid "last"
msgstr ""
-#: src/Content/Text/BBCode.php:990 src/Content/Text/BBCode.php:1784
-#: src/Content/Text/BBCode.php:1785
+#: src/Content/Text/BBCode.php:990 src/Content/Text/BBCode.php:1808
+#: src/Content/Text/BBCode.php:1809
msgid "Image/photo"
msgstr ""
@@ -2623,41 +2624,41 @@ msgid ""
"%2$s %3$s"
msgstr ""
-#: src/Content/Text/BBCode.php:1188 src/Model/Item.php:3271
-#: src/Model/Item.php:3277 src/Model/Item.php:3278
+#: src/Content/Text/BBCode.php:1188 src/Model/Item.php:3301
+#: src/Model/Item.php:3307 src/Model/Item.php:3308
msgid "Link to source"
msgstr ""
-#: src/Content/Text/BBCode.php:1702 src/Content/Text/HTML.php:933
+#: src/Content/Text/BBCode.php:1726 src/Content/Text/HTML.php:940
msgid "Click to open/close"
msgstr ""
-#: src/Content/Text/BBCode.php:1733
+#: src/Content/Text/BBCode.php:1757
msgid "$1 wrote:"
msgstr ""
-#: src/Content/Text/BBCode.php:1789 src/Content/Text/BBCode.php:1790
+#: src/Content/Text/BBCode.php:1813 src/Content/Text/BBCode.php:1814
msgid "Encrypted content"
msgstr ""
-#: src/Content/Text/BBCode.php:2008
+#: src/Content/Text/BBCode.php:2032
msgid "Invalid source protocol"
msgstr ""
-#: src/Content/Text/BBCode.php:2023
+#: src/Content/Text/BBCode.php:2047
msgid "Invalid link protocol"
msgstr ""
-#: src/Content/Text/HTML.php:797
+#: src/Content/Text/HTML.php:805
msgid "Loading more entries..."
msgstr ""
-#: src/Content/Text/HTML.php:798
+#: src/Content/Text/HTML.php:806
msgid "The end"
msgstr ""
-#: src/Content/Text/HTML.php:875 src/Content/Widget/VCard.php:109
-#: src/Model/Profile.php:456
+#: src/Content/Text/HTML.php:882 src/Content/Widget/VCard.php:109
+#: src/Model/Profile.php:457
msgid "Follow"
msgstr ""
@@ -2677,117 +2678,117 @@ msgstr ""
msgid "Connect"
msgstr ""
-#: src/Content/Widget.php:70
+#: src/Content/Widget.php:72
#, php-format
msgid "%d invitation available"
msgid_plural "%d invitations available"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Widget.php:76 view/theme/vier/theme.php:170
+#: src/Content/Widget.php:78 view/theme/vier/theme.php:170
msgid "Find People"
msgstr ""
-#: src/Content/Widget.php:77 view/theme/vier/theme.php:171
+#: src/Content/Widget.php:79 view/theme/vier/theme.php:171
msgid "Enter name or interest"
msgstr ""
-#: src/Content/Widget.php:79 view/theme/vier/theme.php:173
+#: src/Content/Widget.php:81 view/theme/vier/theme.php:173
msgid "Examples: Robert Morgenstein, Fishing"
msgstr ""
-#: src/Content/Widget.php:80 src/Module/Contact.php:391
+#: src/Content/Widget.php:82 src/Module/Contact.php:391
#: src/Module/Directory.php:97 view/theme/vier/theme.php:174
msgid "Find"
msgstr ""
-#: src/Content/Widget.php:82 view/theme/vier/theme.php:176
+#: src/Content/Widget.php:84 view/theme/vier/theme.php:176
msgid "Similar Interests"
msgstr ""
-#: src/Content/Widget.php:83 view/theme/vier/theme.php:177
+#: src/Content/Widget.php:85 view/theme/vier/theme.php:177
msgid "Random Profile"
msgstr ""
-#: src/Content/Widget.php:84 view/theme/vier/theme.php:178
+#: src/Content/Widget.php:86 view/theme/vier/theme.php:178
msgid "Invite Friends"
msgstr ""
-#: src/Content/Widget.php:85 src/Module/Directory.php:89
+#: src/Content/Widget.php:87 src/Module/Directory.php:89
#: view/theme/vier/theme.php:179
msgid "Global Directory"
msgstr ""
-#: src/Content/Widget.php:87 view/theme/vier/theme.php:181
+#: src/Content/Widget.php:89 view/theme/vier/theme.php:181
msgid "Local Directory"
msgstr ""
-#: src/Content/Widget.php:209 src/Model/Group.php:570
+#: src/Content/Widget.php:211 src/Model/Group.php:583
#: src/Module/Contact.php:354 src/Module/Welcome.php:76
msgid "Groups"
msgstr ""
-#: src/Content/Widget.php:211
+#: src/Content/Widget.php:213
msgid "Everyone"
msgstr ""
-#: src/Content/Widget.php:240
+#: src/Content/Widget.php:242
msgid "Relationships"
msgstr ""
-#: src/Content/Widget.php:242 src/Module/Contact.php:306
+#: src/Content/Widget.php:244 src/Module/Contact.php:306
#: src/Module/Group.php:293
msgid "All Contacts"
msgstr ""
-#: src/Content/Widget.php:281
+#: src/Content/Widget.php:283
msgid "Protocols"
msgstr ""
-#: src/Content/Widget.php:283
+#: src/Content/Widget.php:285
msgid "All Protocols"
msgstr ""
-#: src/Content/Widget.php:311
+#: src/Content/Widget.php:313
msgid "Saved Folders"
msgstr ""
-#: src/Content/Widget.php:313 src/Content/Widget.php:344
+#: src/Content/Widget.php:315 src/Content/Widget.php:346
msgid "Everything"
msgstr ""
-#: src/Content/Widget.php:342
+#: src/Content/Widget.php:344
msgid "Categories"
msgstr ""
-#: src/Content/Widget.php:399
+#: src/Content/Widget.php:401
#, php-format
msgid "%d contact in common"
msgid_plural "%d contacts in common"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Widget.php:495
+#: src/Content/Widget.php:497
msgid "Archives"
msgstr ""
-#: src/Content/Widget.php:519
+#: src/Content/Widget.php:521
msgid "Persons"
msgstr ""
-#: src/Content/Widget.php:520
+#: src/Content/Widget.php:522
msgid "Organisations"
msgstr ""
-#: src/Content/Widget.php:521 src/Model/Contact.php:1537
+#: src/Content/Widget.php:523 src/Model/Contact.php:1538
msgid "News"
msgstr ""
-#: src/Content/Widget.php:525 src/Module/Settings/Account.php:455
+#: src/Content/Widget.php:527 src/Module/Settings/Account.php:455
msgid "Account Types"
msgstr ""
-#: src/Content/Widget.php:526 src/Module/Admin/BaseUsers.php:51
+#: src/Content/Widget.php:528 src/Module/Admin/BaseUsers.php:51
msgid "All"
msgstr ""
@@ -2837,22 +2838,22 @@ msgstr[1] ""
msgid "More Trending Tags"
msgstr ""
-#: src/Content/Widget/VCard.php:102 src/Model/Profile.php:375
+#: src/Content/Widget/VCard.php:102 src/Model/Profile.php:376
#: src/Module/Contact/Profile.php:371 src/Module/Profile/Profile.php:176
msgid "XMPP:"
msgstr ""
-#: src/Content/Widget/VCard.php:103 src/Model/Profile.php:376
+#: src/Content/Widget/VCard.php:103 src/Model/Profile.php:377
#: src/Module/Contact/Profile.php:373 src/Module/Profile/Profile.php:180
msgid "Matrix:"
msgstr ""
-#: src/Content/Widget/VCard.php:107 src/Model/Profile.php:468
+#: src/Content/Widget/VCard.php:107 src/Model/Profile.php:469
#: src/Module/Notifications/Introductions.php:199
msgid "Network:"
msgstr ""
-#: src/Content/Widget/VCard.php:111 src/Model/Profile.php:458
+#: src/Content/Widget/VCard.php:111 src/Model/Profile.php:459
msgid "Unfollow"
msgstr ""
@@ -3213,206 +3214,206 @@ msgstr ""
msgid "Could not connect to database."
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:425
+#: src/Core/L10n.php:399 src/Model/Event.php:424
#: src/Module/Settings/Display.php:182
msgid "Monday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:426
+#: src/Core/L10n.php:399 src/Model/Event.php:425
msgid "Tuesday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:427
+#: src/Core/L10n.php:399 src/Model/Event.php:426
msgid "Wednesday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:428
+#: src/Core/L10n.php:399 src/Model/Event.php:427
msgid "Thursday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:429
+#: src/Core/L10n.php:399 src/Model/Event.php:428
msgid "Friday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:430
+#: src/Core/L10n.php:399 src/Model/Event.php:429
msgid "Saturday"
msgstr ""
-#: src/Core/L10n.php:400 src/Model/Event.php:424
+#: src/Core/L10n.php:399 src/Model/Event.php:423
#: src/Module/Settings/Display.php:182
msgid "Sunday"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:445
+#: src/Core/L10n.php:403 src/Model/Event.php:444
msgid "January"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:446
+#: src/Core/L10n.php:403 src/Model/Event.php:445
msgid "February"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:447
+#: src/Core/L10n.php:403 src/Model/Event.php:446
msgid "March"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:448
+#: src/Core/L10n.php:403 src/Model/Event.php:447
msgid "April"
msgstr ""
-#: src/Core/L10n.php:404 src/Core/L10n.php:424 src/Model/Event.php:436
+#: src/Core/L10n.php:403 src/Core/L10n.php:422 src/Model/Event.php:435
msgid "May"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:449
+#: src/Core/L10n.php:403 src/Model/Event.php:448
msgid "June"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:450
+#: src/Core/L10n.php:403 src/Model/Event.php:449
msgid "July"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:451
+#: src/Core/L10n.php:403 src/Model/Event.php:450
msgid "August"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:452
+#: src/Core/L10n.php:403 src/Model/Event.php:451
msgid "September"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:453
+#: src/Core/L10n.php:403 src/Model/Event.php:452
msgid "October"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:454
+#: src/Core/L10n.php:403 src/Model/Event.php:453
msgid "November"
msgstr ""
-#: src/Core/L10n.php:404 src/Model/Event.php:455
+#: src/Core/L10n.php:403 src/Model/Event.php:454
msgid "December"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:417
+#: src/Core/L10n.php:418 src/Model/Event.php:416
msgid "Mon"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:418
+#: src/Core/L10n.php:418 src/Model/Event.php:417
msgid "Tue"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:419
+#: src/Core/L10n.php:418 src/Model/Event.php:418
msgid "Wed"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:420
+#: src/Core/L10n.php:418 src/Model/Event.php:419
msgid "Thu"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:421
+#: src/Core/L10n.php:418 src/Model/Event.php:420
msgid "Fri"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:422
+#: src/Core/L10n.php:418 src/Model/Event.php:421
msgid "Sat"
msgstr ""
-#: src/Core/L10n.php:420 src/Model/Event.php:416
+#: src/Core/L10n.php:418 src/Model/Event.php:415
msgid "Sun"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:432
+#: src/Core/L10n.php:422 src/Model/Event.php:431
msgid "Jan"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:433
+#: src/Core/L10n.php:422 src/Model/Event.php:432
msgid "Feb"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:434
+#: src/Core/L10n.php:422 src/Model/Event.php:433
msgid "Mar"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:435
+#: src/Core/L10n.php:422 src/Model/Event.php:434
msgid "Apr"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:437
+#: src/Core/L10n.php:422 src/Model/Event.php:436
msgid "Jun"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:438
+#: src/Core/L10n.php:422 src/Model/Event.php:437
msgid "Jul"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:439
+#: src/Core/L10n.php:422 src/Model/Event.php:438
msgid "Aug"
msgstr ""
-#: src/Core/L10n.php:424
+#: src/Core/L10n.php:422
msgid "Sep"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:441
+#: src/Core/L10n.php:422 src/Model/Event.php:440
msgid "Oct"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:442
+#: src/Core/L10n.php:422 src/Model/Event.php:441
msgid "Nov"
msgstr ""
-#: src/Core/L10n.php:424 src/Model/Event.php:443
+#: src/Core/L10n.php:422 src/Model/Event.php:442
msgid "Dec"
msgstr ""
-#: src/Core/L10n.php:443
+#: src/Core/L10n.php:441
msgid "poke"
msgstr ""
-#: src/Core/L10n.php:443
+#: src/Core/L10n.php:441
msgid "poked"
msgstr ""
-#: src/Core/L10n.php:444
+#: src/Core/L10n.php:442
msgid "ping"
msgstr ""
-#: src/Core/L10n.php:444
+#: src/Core/L10n.php:442
msgid "pinged"
msgstr ""
-#: src/Core/L10n.php:445
+#: src/Core/L10n.php:443
msgid "prod"
msgstr ""
-#: src/Core/L10n.php:445
+#: src/Core/L10n.php:443
msgid "prodded"
msgstr ""
-#: src/Core/L10n.php:446
+#: src/Core/L10n.php:444
msgid "slap"
msgstr ""
-#: src/Core/L10n.php:446
+#: src/Core/L10n.php:444
msgid "slapped"
msgstr ""
-#: src/Core/L10n.php:447
+#: src/Core/L10n.php:445
msgid "finger"
msgstr ""
-#: src/Core/L10n.php:447
+#: src/Core/L10n.php:445
msgid "fingered"
msgstr ""
-#: src/Core/L10n.php:448
+#: src/Core/L10n.php:446
msgid "rebuff"
msgstr ""
-#: src/Core/L10n.php:448
+#: src/Core/L10n.php:446
msgid "rebuffed"
msgstr ""
#: src/Core/Renderer.php:89 src/Core/Renderer.php:118 src/Core/Renderer.php:145
-#: src/Core/Renderer.php:179 src/Render/FriendicaSmartyEngine.php:56
+#: src/Core/Renderer.php:179 src/Render/FriendicaSmartyEngine.php:69
msgid ""
"Friendica can't display this page at the moment, please contact the "
"administrator."
@@ -3497,35 +3498,35 @@ msgid ""
"\t\t\t\t\tThe friendica database was successfully updated from %s to %s."
msgstr ""
-#: src/Core/UserImport.php:125
+#: src/Core/UserImport.php:126
msgid "Error decoding account file"
msgstr ""
-#: src/Core/UserImport.php:131
+#: src/Core/UserImport.php:132
msgid "Error! No version data in file! This is not a Friendica account file?"
msgstr ""
-#: src/Core/UserImport.php:139
+#: src/Core/UserImport.php:140
#, php-format
msgid "User '%s' already exists on this server!"
msgstr ""
-#: src/Core/UserImport.php:175
+#: src/Core/UserImport.php:176
msgid "User creation error"
msgstr ""
-#: src/Core/UserImport.php:220
+#: src/Core/UserImport.php:221
#, php-format
msgid "%d contact not imported"
msgid_plural "%d contacts not imported"
msgstr[0] ""
msgstr[1] ""
-#: src/Core/UserImport.php:273
+#: src/Core/UserImport.php:274
msgid "User profile creation error"
msgstr ""
-#: src/Core/UserImport.php:326
+#: src/Core/UserImport.php:327
msgid "Done. You can now login with your username and password"
msgstr ""
@@ -3555,7 +3556,7 @@ msgstr ""
msgid "There are no tables on MyISAM or InnoDB with the Antelope file format."
msgstr ""
-#: src/Database/DBStructure.php:158
+#: src/Database/DBStructure.php:157
#, php-format
msgid ""
"\n"
@@ -3563,20 +3564,20 @@ msgid ""
"%s\n"
msgstr ""
-#: src/Database/DBStructure.php:161
+#: src/Database/DBStructure.php:160
msgid "Errors encountered performing database changes: "
msgstr ""
-#: src/Database/DBStructure.php:549
+#: src/Database/DBStructure.php:563
msgid "Another database update is currently running."
msgstr ""
-#: src/Database/DBStructure.php:553
+#: src/Database/DBStructure.php:567
#, php-format
msgid "%s: Database update"
msgstr ""
-#: src/Database/DBStructure.php:803
+#: src/Database/DBStructure.php:817
#, php-format
msgid "%s: updating %s table."
msgstr ""
@@ -3607,81 +3608,81 @@ msgstr ""
msgid "Legacy module file not found: %s"
msgstr ""
-#: src/Model/Contact.php:1103 src/Model/Contact.php:1115
+#: src/Model/Contact.php:1104 src/Model/Contact.php:1116
msgid "UnFollow"
msgstr ""
-#: src/Model/Contact.php:1121 src/Module/Admin/Users/Pending.php:107
+#: src/Model/Contact.php:1122 src/Module/Admin/Users/Pending.php:107
#: src/Module/Notifications/Introductions.php:130
#: src/Module/Notifications/Introductions.php:202
msgid "Approve"
msgstr ""
-#: src/Model/Contact.php:1533
+#: src/Model/Contact.php:1534
msgid "Organisation"
msgstr ""
-#: src/Model/Contact.php:1541
+#: src/Model/Contact.php:1542
msgid "Forum"
msgstr ""
-#: src/Model/Contact.php:2550
+#: src/Model/Contact.php:2625
msgid "Disallowed profile URL."
msgstr ""
-#: src/Model/Contact.php:2555 src/Module/Friendica.php:81
+#: src/Model/Contact.php:2630 src/Module/Friendica.php:81
msgid "Blocked domain"
msgstr ""
-#: src/Model/Contact.php:2560
+#: src/Model/Contact.php:2635
msgid "Connect URL missing."
msgstr ""
-#: src/Model/Contact.php:2569
+#: src/Model/Contact.php:2644
msgid ""
"The contact could not be added. Please check the relevant network "
"credentials in your Settings -> Social Networks page."
msgstr ""
-#: src/Model/Contact.php:2611
+#: src/Model/Contact.php:2686
msgid "The profile address specified does not provide adequate information."
msgstr ""
-#: src/Model/Contact.php:2613
+#: src/Model/Contact.php:2688
msgid "No compatible communication protocols or feeds were discovered."
msgstr ""
-#: src/Model/Contact.php:2616
+#: src/Model/Contact.php:2691
msgid "An author or name was not found."
msgstr ""
-#: src/Model/Contact.php:2619
+#: src/Model/Contact.php:2694
msgid "No browser URL could be matched to this address."
msgstr ""
-#: src/Model/Contact.php:2622
+#: src/Model/Contact.php:2697
msgid ""
"Unable to match @-style Identity Address with a known protocol or email "
"contact."
msgstr ""
-#: src/Model/Contact.php:2623
+#: src/Model/Contact.php:2698
msgid "Use mailto: in front of address to force email check."
msgstr ""
-#: src/Model/Contact.php:2629
+#: src/Model/Contact.php:2704
msgid ""
"The profile address specified belongs to a network which has been disabled "
"on this site."
msgstr ""
-#: src/Model/Contact.php:2634
+#: src/Model/Contact.php:2709
msgid ""
"Limited profile. This person will be unable to receive direct/personal "
"notifications from you."
msgstr ""
-#: src/Model/Contact.php:2693
+#: src/Model/Contact.php:2768
msgid "Unable to retrieve contact information."
msgstr ""
@@ -3689,41 +3690,41 @@ msgstr ""
msgid "l F d, Y \\@ g:i A \\G\\M\\TP (e)"
msgstr ""
-#: src/Model/Event.php:73 src/Model/Event.php:90 src/Model/Event.php:464
+#: src/Model/Event.php:73 src/Model/Event.php:90 src/Model/Event.php:463
#: src/Model/Event.php:897
msgid "Starts:"
msgstr ""
-#: src/Model/Event.php:76 src/Model/Event.php:96 src/Model/Event.php:465
+#: src/Model/Event.php:76 src/Model/Event.php:96 src/Model/Event.php:464
#: src/Model/Event.php:901
msgid "Finishes:"
msgstr ""
-#: src/Model/Event.php:414
+#: src/Model/Event.php:413
msgid "all-day"
msgstr ""
-#: src/Model/Event.php:440
+#: src/Model/Event.php:439
msgid "Sept"
msgstr ""
-#: src/Model/Event.php:462
+#: src/Model/Event.php:461
msgid "No events to display"
msgstr ""
-#: src/Model/Event.php:578
+#: src/Model/Event.php:577
msgid "l, F j"
msgstr ""
-#: src/Model/Event.php:609
+#: src/Model/Event.php:608
msgid "Edit event"
msgstr ""
-#: src/Model/Event.php:610
+#: src/Model/Event.php:609
msgid "Duplicate event"
msgstr ""
-#: src/Model/Event.php:611
+#: src/Model/Event.php:610
msgid "Delete event"
msgstr ""
@@ -3747,112 +3748,112 @@ msgstr ""
msgid "Hide map"
msgstr ""
-#: src/Model/Event.php:1009
+#: src/Model/Event.php:1010
#, php-format
msgid "%s's birthday"
msgstr ""
-#: src/Model/Event.php:1010
+#: src/Model/Event.php:1011
#, php-format
msgid "Happy Birthday %s"
msgstr ""
-#: src/Model/Group.php:95
+#: src/Model/Group.php:105
msgid ""
"A deleted group with this name was revived. Existing item permissions "
"may apply to this group and any future members. If this is "
"not what you intended, please create another group with a different name."
msgstr ""
-#: src/Model/Group.php:486
+#: src/Model/Group.php:499
msgid "Default privacy group for new contacts"
msgstr ""
-#: src/Model/Group.php:518
+#: src/Model/Group.php:531
msgid "Everybody"
msgstr ""
-#: src/Model/Group.php:537
+#: src/Model/Group.php:550
msgid "edit"
msgstr ""
-#: src/Model/Group.php:569
+#: src/Model/Group.php:582
msgid "add"
msgstr ""
-#: src/Model/Group.php:574
+#: src/Model/Group.php:587
msgid "Edit group"
msgstr ""
-#: src/Model/Group.php:575 src/Module/Group.php:194
+#: src/Model/Group.php:588 src/Module/Group.php:194
msgid "Contacts not in any group"
msgstr ""
-#: src/Model/Group.php:577
+#: src/Model/Group.php:590
msgid "Create a new group"
msgstr ""
-#: src/Model/Group.php:578 src/Module/Group.php:179 src/Module/Group.php:202
+#: src/Model/Group.php:591 src/Module/Group.php:179 src/Module/Group.php:202
#: src/Module/Group.php:277
msgid "Group Name: "
msgstr ""
-#: src/Model/Group.php:579
+#: src/Model/Group.php:592
msgid "Edit groups"
msgstr ""
-#: src/Model/Item.php:1795
+#: src/Model/Item.php:1823
#, php-format
msgid "Detected languages in this post:\\n%s"
msgstr ""
-#: src/Model/Item.php:2701
+#: src/Model/Item.php:2730
msgid "activity"
msgstr ""
-#: src/Model/Item.php:2703
+#: src/Model/Item.php:2732
msgid "comment"
msgstr ""
-#: src/Model/Item.php:2706
+#: src/Model/Item.php:2735
msgid "post"
msgstr ""
-#: src/Model/Item.php:2821
+#: src/Model/Item.php:2851
#, php-format
msgid "Content warning: %s"
msgstr ""
-#: src/Model/Item.php:3180
+#: src/Model/Item.php:3210
msgid "bytes"
msgstr ""
-#: src/Model/Item.php:3214
+#: src/Model/Item.php:3244
#, php-format
msgid "%s (%d%s, %d votes)"
msgstr ""
-#: src/Model/Item.php:3216
+#: src/Model/Item.php:3246
#, php-format
msgid "%s (%d votes)"
msgstr ""
-#: src/Model/Item.php:3221
+#: src/Model/Item.php:3251
#, php-format
msgid "%d voters. Poll end: %s"
msgstr ""
-#: src/Model/Item.php:3223
+#: src/Model/Item.php:3253
#, php-format
msgid "%d voters."
msgstr ""
-#: src/Model/Item.php:3225
+#: src/Model/Item.php:3255
#, php-format
msgid "Poll end: %s"
msgstr ""
-#: src/Model/Item.php:3259 src/Model/Item.php:3260
+#: src/Model/Item.php:3289 src/Model/Item.php:3290
msgid "View on separate page"
msgstr ""
@@ -3860,147 +3861,147 @@ msgstr ""
msgid "[no subject]"
msgstr ""
-#: src/Model/Profile.php:358 src/Module/Profile/Profile.php:256
+#: src/Model/Profile.php:359 src/Module/Profile/Profile.php:256
#: src/Module/Profile/Profile.php:258
msgid "Edit profile"
msgstr ""
-#: src/Model/Profile.php:360
+#: src/Model/Profile.php:361
msgid "Change profile photo"
msgstr ""
-#: src/Model/Profile.php:373 src/Module/Directory.php:153
+#: src/Model/Profile.php:374 src/Module/Directory.php:153
#: src/Module/Profile/Profile.php:184
msgid "Homepage:"
msgstr ""
-#: src/Model/Profile.php:374 src/Module/Contact/Profile.php:375
+#: src/Model/Profile.php:375 src/Module/Contact/Profile.php:375
#: src/Module/Notifications/Introductions.php:187
msgid "About:"
msgstr ""
-#: src/Model/Profile.php:460
+#: src/Model/Profile.php:461
msgid "Atom feed"
msgstr ""
-#: src/Model/Profile.php:504
+#: src/Model/Profile.php:505
msgid "F d"
msgstr ""
-#: src/Model/Profile.php:568 src/Model/Profile.php:652
+#: src/Model/Profile.php:569 src/Model/Profile.php:653
msgid "[today]"
msgstr ""
-#: src/Model/Profile.php:577
+#: src/Model/Profile.php:578
msgid "Birthday Reminders"
msgstr ""
-#: src/Model/Profile.php:578
+#: src/Model/Profile.php:579
msgid "Birthdays this week:"
msgstr ""
-#: src/Model/Profile.php:601
+#: src/Model/Profile.php:602
msgid "g A l F d"
msgstr ""
-#: src/Model/Profile.php:639
+#: src/Model/Profile.php:640
msgid "[No description]"
msgstr ""
-#: src/Model/Profile.php:665
+#: src/Model/Profile.php:666
msgid "Event Reminders"
msgstr ""
-#: src/Model/Profile.php:666
+#: src/Model/Profile.php:667
msgid "Upcoming events the next 7 days:"
msgstr ""
-#: src/Model/Profile.php:854
+#: src/Model/Profile.php:855
#, php-format
msgid "OpenWebAuth: %1$s welcomes %2$s"
msgstr ""
-#: src/Model/Profile.php:980
+#: src/Model/Profile.php:981
msgid "Hometown:"
msgstr ""
-#: src/Model/Profile.php:981
+#: src/Model/Profile.php:982
msgid "Marital Status:"
msgstr ""
-#: src/Model/Profile.php:982
+#: src/Model/Profile.php:983
msgid "With:"
msgstr ""
-#: src/Model/Profile.php:983
+#: src/Model/Profile.php:984
msgid "Since:"
msgstr ""
-#: src/Model/Profile.php:984
+#: src/Model/Profile.php:985
msgid "Sexual Preference:"
msgstr ""
-#: src/Model/Profile.php:985
+#: src/Model/Profile.php:986
msgid "Political Views:"
msgstr ""
-#: src/Model/Profile.php:986
+#: src/Model/Profile.php:987
msgid "Religious Views:"
msgstr ""
-#: src/Model/Profile.php:987
+#: src/Model/Profile.php:988
msgid "Likes:"
msgstr ""
-#: src/Model/Profile.php:988
+#: src/Model/Profile.php:989
msgid "Dislikes:"
msgstr ""
-#: src/Model/Profile.php:989
+#: src/Model/Profile.php:990
msgid "Title/Description:"
msgstr ""
-#: src/Model/Profile.php:990 src/Module/Admin/Summary.php:234
+#: src/Model/Profile.php:991 src/Module/Admin/Summary.php:234
msgid "Summary"
msgstr ""
-#: src/Model/Profile.php:991
+#: src/Model/Profile.php:992
msgid "Musical interests"
msgstr ""
-#: src/Model/Profile.php:992
+#: src/Model/Profile.php:993
msgid "Books, literature"
msgstr ""
-#: src/Model/Profile.php:993
+#: src/Model/Profile.php:994
msgid "Television"
msgstr ""
-#: src/Model/Profile.php:994
+#: src/Model/Profile.php:995
msgid "Film/dance/culture/entertainment"
msgstr ""
-#: src/Model/Profile.php:995
+#: src/Model/Profile.php:996
msgid "Hobbies/Interests"
msgstr ""
-#: src/Model/Profile.php:996
+#: src/Model/Profile.php:997
msgid "Love/romance"
msgstr ""
-#: src/Model/Profile.php:997
+#: src/Model/Profile.php:998
msgid "Work/employment"
msgstr ""
-#: src/Model/Profile.php:998
+#: src/Model/Profile.php:999
msgid "School/education"
msgstr ""
-#: src/Model/Profile.php:999
+#: src/Model/Profile.php:1000
msgid "Contact information and Social Networks"
msgstr ""
-#: src/Model/User.php:210 src/Model/User.php:1058
+#: src/Model/User.php:212 src/Model/User.php:1058
msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr ""
@@ -4047,13 +4048,13 @@ msgstr ""
msgid "Invalid OpenID url"
msgstr ""
-#: src/Model/User.php:970 src/Security/Authentication.php:235
+#: src/Model/User.php:970 src/Security/Authentication.php:240
msgid ""
"We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID."
msgstr ""
-#: src/Model/User.php:970 src/Security/Authentication.php:235
+#: src/Model/User.php:970 src/Security/Authentication.php:240
msgid "The error message was:"
msgstr ""
@@ -4135,7 +4136,7 @@ msgstr ""
msgid "Profile Photos"
msgstr ""
-#: src/Model/User.php:1368
+#: src/Model/User.php:1367
#, php-format
msgid ""
"\n"
@@ -4143,7 +4144,7 @@ msgid ""
"\t\t\tthe administrator of %2$s has set up an account for you."
msgstr ""
-#: src/Model/User.php:1371
+#: src/Model/User.php:1370
#, php-format
msgid ""
"\n"
@@ -4180,12 +4181,12 @@ msgid ""
"\t\tThank you and welcome to %4$s."
msgstr ""
-#: src/Model/User.php:1404 src/Model/User.php:1511
+#: src/Model/User.php:1403 src/Model/User.php:1510
#, php-format
msgid "Registration details for %s"
msgstr ""
-#: src/Model/User.php:1424
+#: src/Model/User.php:1423
#, php-format
msgid ""
"\n"
@@ -4201,12 +4202,12 @@ msgid ""
"\t\t"
msgstr ""
-#: src/Model/User.php:1443
+#: src/Model/User.php:1442
#, php-format
msgid "Registration at %s"
msgstr ""
-#: src/Model/User.php:1467
+#: src/Model/User.php:1466
#, php-format
msgid ""
"\n"
@@ -4215,7 +4216,7 @@ msgid ""
"\t\t\t"
msgstr ""
-#: src/Model/User.php:1475
+#: src/Model/User.php:1474
#, php-format
msgid ""
"\n"
@@ -4295,7 +4296,7 @@ msgid "Administration"
msgstr ""
#: src/Module/Admin/Addons/Details.php:112 src/Module/Admin/Addons/Index.php:68
-#: src/Module/BaseAdmin.php:93 src/Module/BaseSettings.php:85
+#: src/Module/BaseAdmin.php:96 src/Module/BaseSettings.php:85
msgid "Addons"
msgstr ""
@@ -4774,7 +4775,7 @@ msgid ""
"only reflect the part of the network your node is aware of."
msgstr ""
-#: src/Module/Admin/Federation.php:197 src/Module/BaseAdmin.php:87
+#: src/Module/Admin/Federation.php:197 src/Module/BaseAdmin.php:90
msgid "Federation Statistics"
msgstr ""
@@ -4790,7 +4791,7 @@ msgstr ""
msgid "Item marked for deletion."
msgstr ""
-#: src/Module/Admin/Item/Delete.php:65 src/Module/BaseAdmin.php:106
+#: src/Module/Admin/Item/Delete.php:65 src/Module/BaseAdmin.php:109
msgid "Delete Item"
msgstr ""
@@ -4819,7 +4820,7 @@ msgstr ""
msgid "The GUID of the item you want to delete."
msgstr ""
-#: src/Module/Admin/Item/Source.php:57 src/Module/BaseAdmin.php:116
+#: src/Module/Admin/Item/Source.php:57 src/Module/BaseAdmin.php:119
msgid "Item Source"
msgstr ""
@@ -4882,8 +4883,8 @@ msgstr ""
msgid "PHP log currently disabled."
msgstr ""
-#: src/Module/Admin/Logs/Settings.php:80 src/Module/BaseAdmin.php:108
-#: src/Module/BaseAdmin.php:109
+#: src/Module/Admin/Logs/Settings.php:80 src/Module/BaseAdmin.php:111
+#: src/Module/BaseAdmin.php:112
msgid "Logs"
msgstr ""
@@ -4936,7 +4937,7 @@ msgid ""
"is readable."
msgstr ""
-#: src/Module/Admin/Logs/View.php:85 src/Module/BaseAdmin.php:110
+#: src/Module/Admin/Logs/View.php:85 src/Module/BaseAdmin.php:113
msgid "View Logs"
msgstr ""
@@ -5118,7 +5119,7 @@ msgstr ""
msgid "Interactors"
msgstr ""
-#: src/Module/Admin/Site.php:432 src/Module/BaseAdmin.php:90
+#: src/Module/Admin/Site.php:432 src/Module/BaseAdmin.php:93
msgid "Site"
msgstr ""
@@ -5907,7 +5908,7 @@ msgid ""
msgstr ""
#: src/Module/Admin/Site.php:542 src/Module/Contact/Profile.php:273
-#: src/Module/Settings/TwoFactor/Index.php:118
+#: src/Module/Settings/TwoFactor/Index.php:121
msgid "Disabled"
msgstr ""
@@ -5971,7 +5972,7 @@ msgstr ""
msgid "Storage Configuration"
msgstr ""
-#: src/Module/Admin/Storage.php:141 src/Module/BaseAdmin.php:91
+#: src/Module/Admin/Storage.php:141 src/Module/BaseAdmin.php:94
msgid "Storage"
msgstr ""
@@ -6187,7 +6188,7 @@ msgid "Screenshot"
msgstr ""
#: src/Module/Admin/Themes/Details.php:91 src/Module/Admin/Themes/Index.php:112
-#: src/Module/BaseAdmin.php:94
+#: src/Module/BaseAdmin.php:97
msgid "Themes"
msgstr ""
@@ -6388,7 +6389,7 @@ msgid "Permanent deletion"
msgstr ""
#: src/Module/Admin/Users/Index.php:150 src/Module/Admin/Users/Index.php:160
-#: src/Module/BaseAdmin.php:92
+#: src/Module/BaseAdmin.php:95
msgid "Users"
msgstr ""
@@ -6494,89 +6495,89 @@ msgstr ""
msgid "Item was not found."
msgstr ""
-#: src/Module/BaseAdmin.php:54 src/Module/BaseAdmin.php:58
+#: src/Module/BaseAdmin.php:57 src/Module/BaseAdmin.php:61
msgid "Please login to continue."
msgstr ""
-#: src/Module/BaseAdmin.php:63
+#: src/Module/BaseAdmin.php:66
msgid "You don't have access to administration pages."
msgstr ""
-#: src/Module/BaseAdmin.php:67
+#: src/Module/BaseAdmin.php:70
msgid ""
"Submanaged account can't access the administration pages. Please log back in "
"as the main account."
msgstr ""
-#: src/Module/BaseAdmin.php:86
+#: src/Module/BaseAdmin.php:89
msgid "Overview"
msgstr ""
-#: src/Module/BaseAdmin.php:89
+#: src/Module/BaseAdmin.php:92
msgid "Configuration"
msgstr ""
-#: src/Module/BaseAdmin.php:95 src/Module/BaseSettings.php:63
+#: src/Module/BaseAdmin.php:98 src/Module/BaseSettings.php:63
msgid "Additional features"
msgstr ""
-#: src/Module/BaseAdmin.php:98
+#: src/Module/BaseAdmin.php:101
msgid "Database"
msgstr ""
-#: src/Module/BaseAdmin.php:99
+#: src/Module/BaseAdmin.php:102
msgid "DB updates"
msgstr ""
-#: src/Module/BaseAdmin.php:100
+#: src/Module/BaseAdmin.php:103
msgid "Inspect Deferred Workers"
msgstr ""
-#: src/Module/BaseAdmin.php:101
+#: src/Module/BaseAdmin.php:104
msgid "Inspect worker Queue"
msgstr ""
-#: src/Module/BaseAdmin.php:103
+#: src/Module/BaseAdmin.php:106
msgid "Tools"
msgstr ""
-#: src/Module/BaseAdmin.php:104
+#: src/Module/BaseAdmin.php:107
msgid "Contact Blocklist"
msgstr ""
-#: src/Module/BaseAdmin.php:105
+#: src/Module/BaseAdmin.php:108
msgid "Server Blocklist"
msgstr ""
-#: src/Module/BaseAdmin.php:112
+#: src/Module/BaseAdmin.php:115
msgid "Diagnostics"
msgstr ""
-#: src/Module/BaseAdmin.php:113
+#: src/Module/BaseAdmin.php:116
msgid "PHP Info"
msgstr ""
-#: src/Module/BaseAdmin.php:114
+#: src/Module/BaseAdmin.php:117
msgid "probe address"
msgstr ""
-#: src/Module/BaseAdmin.php:115
+#: src/Module/BaseAdmin.php:118
msgid "check webfinger"
msgstr ""
-#: src/Module/BaseAdmin.php:117
+#: src/Module/BaseAdmin.php:120
msgid "Babel"
msgstr ""
-#: src/Module/BaseAdmin.php:118 src/Module/Debug/ActivityPubConversion.php:142
+#: src/Module/BaseAdmin.php:121 src/Module/Debug/ActivityPubConversion.php:142
msgid "ActivityPub Conversion"
msgstr ""
-#: src/Module/BaseAdmin.php:127
+#: src/Module/BaseAdmin.php:130
msgid "Addon Features"
msgstr ""
-#: src/Module/BaseAdmin.php:128
+#: src/Module/BaseAdmin.php:131
msgid "User registrations waiting for confirmation"
msgstr ""
@@ -6638,8 +6639,8 @@ msgstr ""
msgid "Account"
msgstr ""
-#: src/Module/BaseSettings.php:48 src/Module/Security/TwoFactor/Verify.php:95
-#: src/Module/Settings/TwoFactor/Index.php:110
+#: src/Module/BaseSettings.php:48 src/Module/Security/TwoFactor/Verify.php:96
+#: src/Module/Settings/TwoFactor/Index.php:113
msgid "Two-factor authentication"
msgstr ""
@@ -6691,7 +6692,7 @@ msgid "Only show blocked contacts"
msgstr ""
#: src/Module/Contact.php:330 src/Module/Contact.php:377
-#: src/Object/Post.php:329
+#: src/Object/Post.php:339
msgid "Ignored"
msgstr ""
@@ -6723,7 +6724,7 @@ msgstr ""
msgid "Search your contacts"
msgstr ""
-#: src/Module/Contact.php:390 src/Module/Search/Index.php:192
+#: src/Module/Contact.php:390 src/Module/Search/Index.php:207
#, php-format
msgid "Results for: %s"
msgstr ""
@@ -7088,7 +7089,7 @@ msgid ""
msgstr ""
#: src/Module/Contact/Profile.php:378
-#: src/Module/Settings/TwoFactor/Index.php:132
+#: src/Module/Settings/TwoFactor/Index.php:135
msgid "Actions"
msgstr ""
@@ -7147,6 +7148,7 @@ msgstr ""
#: src/Module/Contact/Revoke.php:107
#: src/Module/Notifications/Introductions.php:142
#: src/Module/OAuth/Acknowledge.php:53 src/Module/Register.php:130
+#: src/Module/Settings/TwoFactor/Trusted.php:124
msgid "Yes"
msgstr ""
@@ -7178,8 +7180,8 @@ msgstr ""
msgid "Hide"
msgstr ""
-#: src/Module/Conversation/Community.php:137 src/Module/Search/Index.php:137
-#: src/Module/Search/Index.php:179
+#: src/Module/Conversation/Community.php:137 src/Module/Search/Index.php:152
+#: src/Module/Search/Index.php:194
msgid "No results."
msgstr ""
@@ -7239,7 +7241,7 @@ msgstr ""
msgid "Posts that mention or involve you"
msgstr ""
-#: src/Module/Conversation/Network.php:287 src/Object/Post.php:341
+#: src/Module/Conversation/Network.php:287 src/Object/Post.php:351
msgid "Starred"
msgstr ""
@@ -8060,6 +8062,7 @@ msgstr ""
#: src/Module/Notifications/Introductions.php:142
#: src/Module/OAuth/Acknowledge.php:54 src/Module/Register.php:131
+#: src/Module/Settings/TwoFactor/Trusted.php:124
msgid "No"
msgstr ""
@@ -8293,19 +8296,19 @@ msgstr ""
#: src/Module/Profile/Profile.php:326 src/Module/Profile/Profile.php:329
#: src/Module/Profile/Status.php:66 src/Module/Profile/Status.php:69
-#: src/Protocol/Feed.php:1017 src/Protocol/OStatus.php:1245
+#: src/Protocol/Feed.php:1018 src/Protocol/OStatus.php:1276
#, php-format
msgid "%s's timeline"
msgstr ""
#: src/Module/Profile/Profile.php:327 src/Module/Profile/Status.php:67
-#: src/Protocol/Feed.php:1021 src/Protocol/OStatus.php:1249
+#: src/Protocol/Feed.php:1022 src/Protocol/OStatus.php:1281
#, php-format
msgid "%s's posts"
msgstr ""
#: src/Module/Profile/Profile.php:328 src/Module/Profile/Status.php:68
-#: src/Protocol/Feed.php:1024 src/Protocol/OStatus.php:1252
+#: src/Protocol/Feed.php:1025 src/Protocol/OStatus.php:1285
#, php-format
msgid "%s's comments"
msgstr ""
@@ -8505,15 +8508,15 @@ msgstr ""
msgid "Your Webfinger address or profile URL:"
msgstr ""
-#: src/Module/Search/Index.php:54
+#: src/Module/Search/Index.php:69
msgid "Only logged in users are permitted to perform a search."
msgstr ""
-#: src/Module/Search/Index.php:74
+#: src/Module/Search/Index.php:89
msgid "Only one search per minute is permitted for not logged in users."
msgstr ""
-#: src/Module/Search/Index.php:190
+#: src/Module/Search/Index.php:205
#, php-format
msgid "Items tagged with: %s"
msgstr ""
@@ -8576,7 +8579,11 @@ msgstr ""
msgid "privacy policy"
msgstr ""
-#: src/Module/Security/Logout.php:87
+#: src/Module/Security/Logout.php:83
+#: src/Module/Security/TwoFactor/Signout.php:78
+#: src/Module/Security/TwoFactor/Signout.php:86
+#: src/Module/Security/TwoFactor/Signout.php:108
+#: src/Module/Security/TwoFactor/Signout.php:115
msgid "Logged out."
msgstr ""
@@ -8602,7 +8609,7 @@ msgid "Remaining recovery codes: %d"
msgstr ""
#: src/Module/Security/TwoFactor/Recovery.php:77
-#: src/Module/Security/TwoFactor/Verify.php:76
+#: src/Module/Security/TwoFactor/Verify.php:77
#: src/Module/Settings/TwoFactor/Verify.php:94
msgid "Invalid code, please retry."
msgstr ""
@@ -8618,7 +8625,6 @@ msgid ""
msgstr ""
#: src/Module/Security/TwoFactor/Recovery.php:98
-#: src/Module/Security/TwoFactor/Verify.php:99
#, php-format
msgid ""
"Don’t have your phone? Enter a two-factor recovery code "
@@ -8632,19 +8638,66 @@ msgstr ""
msgid "Submit recovery code and complete login"
msgstr ""
-#: src/Module/Security/TwoFactor/Verify.php:96
+#: src/Module/Security/TwoFactor/Signout.php:122
+msgid "Sign out of this browser?"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Signout.php:123
+msgid ""
+"If you trust this browser, you will not be asked for verification code "
+"the next time you sign in.
"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Signout.php:124
+msgid "Sign out"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Signout.php:126
+msgid "Trust and sign out"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:89
+msgid "Couldn't save browser to Cookie."
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:119
+msgid "Trust this browser?"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:120
+msgid ""
+"If you choose to trust this browser, you will not be asked for a "
+"verification code the next time you sign in.
"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:121
+msgid "Not now"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:122
+msgid "Don't trust"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Trust.php:123
+msgid "Trust"
+msgstr ""
+
+#: src/Module/Security/TwoFactor/Verify.php:97
msgid ""
"Open the two-factor authentication app on your device to get an "
"authentication code and verify your identity.
"
msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:100
-#: src/Module/Settings/TwoFactor/Verify.php:154
-msgid "Please enter a code from your authentication app"
+#, php-format
+msgid ""
+"If you do not have access to your authentication code you can use a two-factor recovery code ."
msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101
-msgid "This is my two-factor authenticator app device"
+#: src/Module/Settings/TwoFactor/Verify.php:154
+msgid "Please enter a code from your authentication app"
msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:102
@@ -9651,99 +9704,95 @@ msgstr ""
msgid "Generate"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:67
+#: src/Module/Settings/TwoFactor/Index.php:68
msgid "Two-factor authentication successfully disabled."
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:93
-msgid "Wrong Password"
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Index.php:113
+#: src/Module/Settings/TwoFactor/Index.php:116
msgid ""
"Use an application on a mobile device to get two-factor authentication "
"codes when prompted on login.
"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:117
+#: src/Module/Settings/TwoFactor/Index.php:120
msgid "Authenticator app"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:118
+#: src/Module/Settings/TwoFactor/Index.php:121
msgid "Configured"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:118
+#: src/Module/Settings/TwoFactor/Index.php:121
msgid "Not Configured"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:119
+#: src/Module/Settings/TwoFactor/Index.php:122
msgid "You haven't finished configuring your authenticator app.
"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:120
+#: src/Module/Settings/TwoFactor/Index.php:123
msgid "Your authenticator app is correctly configured.
"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:122
+#: src/Module/Settings/TwoFactor/Index.php:125
msgid "Recovery codes"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:123
+#: src/Module/Settings/TwoFactor/Index.php:126
msgid "Remaining valid codes"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:125
+#: src/Module/Settings/TwoFactor/Index.php:128
msgid ""
"These one-use codes can replace an authenticator app code in case you "
"have lost access to it.
"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:127
+#: src/Module/Settings/TwoFactor/Index.php:130
msgid "App-specific passwords"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:128
+#: src/Module/Settings/TwoFactor/Index.php:131
msgid "Generated app-specific passwords"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:130
+#: src/Module/Settings/TwoFactor/Index.php:133
msgid ""
"These randomly generated passwords allow you to authenticate on apps not "
"supporting two-factor authentication.
"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:133
+#: src/Module/Settings/TwoFactor/Index.php:136
msgid "Current password:"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:133
+#: src/Module/Settings/TwoFactor/Index.php:136
msgid ""
"You need to provide your current password to change two-factor "
"authentication settings."
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:134
+#: src/Module/Settings/TwoFactor/Index.php:137
msgid "Enable two-factor authentication"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:135
+#: src/Module/Settings/TwoFactor/Index.php:138
msgid "Disable two-factor authentication"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:136
+#: src/Module/Settings/TwoFactor/Index.php:139
msgid "Show recovery codes"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:137
+#: src/Module/Settings/TwoFactor/Index.php:140
msgid "Manage app-specific passwords"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:138
+#: src/Module/Settings/TwoFactor/Index.php:141
msgid "Manage trusted browsers"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:139
+#: src/Module/Settings/TwoFactor/Index.php:142
msgid "Finish app configuration"
msgstr ""
@@ -9785,34 +9834,38 @@ msgstr ""
msgid "Trusted browser successfully removed."
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:133
+#: src/Module/Settings/TwoFactor/Trusted.php:134
msgid "Two-factor Trusted Browsers"
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:134
+#: src/Module/Settings/TwoFactor/Trusted.php:135
msgid ""
"Trusted browsers are individual browsers you chose to skip two-factor "
"authentication to access Friendica. Please use this feature sparingly, as it "
"can negate the benefit of two-factor authentication."
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:135
+#: src/Module/Settings/TwoFactor/Trusted.php:136
msgid "Device"
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:136
+#: src/Module/Settings/TwoFactor/Trusted.php:137
msgid "OS"
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:138
+#: src/Module/Settings/TwoFactor/Trusted.php:139
msgid "Trusted"
msgstr ""
-#: src/Module/Settings/TwoFactor/Trusted.php:139
-msgid "Last Use"
+#: src/Module/Settings/TwoFactor/Trusted.php:140
+msgid "Created At"
msgstr ""
#: src/Module/Settings/TwoFactor/Trusted.php:141
+msgid "Last Use"
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Trusted.php:143
msgid "Remove All"
msgstr ""
@@ -10285,205 +10338,205 @@ msgstr ""
msgid "%1$s commented on your thread %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:221
-#: src/Navigation/Notifications/Repository/Notify.php:735
+#: src/Navigation/Notifications/Repository/Notify.php:222
+#: src/Navigation/Notifications/Repository/Notify.php:736
msgid "[Friendica:Notify]"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:285
+#: src/Navigation/Notifications/Repository/Notify.php:286
#, php-format
msgid "%s New mail received at %s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:287
+#: src/Navigation/Notifications/Repository/Notify.php:288
#, php-format
msgid "%1$s sent you a new private message at %2$s."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:288
+#: src/Navigation/Notifications/Repository/Notify.php:289
msgid "a private message"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:288
+#: src/Navigation/Notifications/Repository/Notify.php:289
#, php-format
msgid "%1$s sent you %2$s."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:290
+#: src/Navigation/Notifications/Repository/Notify.php:291
#, php-format
msgid "Please visit %s to view and/or reply to your private messages."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:320
+#: src/Navigation/Notifications/Repository/Notify.php:321
#, php-format
msgid "%1$s commented on %2$s's %3$s %4$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:325
+#: src/Navigation/Notifications/Repository/Notify.php:326
#, php-format
msgid "%1$s commented on your %2$s %3$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:329
+#: src/Navigation/Notifications/Repository/Notify.php:330
#, php-format
msgid "%1$s commented on their %2$s %3$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:333
-#: src/Navigation/Notifications/Repository/Notify.php:769
+#: src/Navigation/Notifications/Repository/Notify.php:334
+#: src/Navigation/Notifications/Repository/Notify.php:770
#, php-format
msgid "%1$s Comment to conversation #%2$d by %3$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:335
+#: src/Navigation/Notifications/Repository/Notify.php:336
#, php-format
msgid "%s commented on an item/conversation you have been following."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:339
-#: src/Navigation/Notifications/Repository/Notify.php:354
-#: src/Navigation/Notifications/Repository/Notify.php:373
-#: src/Navigation/Notifications/Repository/Notify.php:784
+#: src/Navigation/Notifications/Repository/Notify.php:340
+#: src/Navigation/Notifications/Repository/Notify.php:355
+#: src/Navigation/Notifications/Repository/Notify.php:374
+#: src/Navigation/Notifications/Repository/Notify.php:785
#, php-format
msgid "Please visit %s to view and/or reply to the conversation."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:346
+#: src/Navigation/Notifications/Repository/Notify.php:347
#, php-format
msgid "%s %s posted to your profile wall"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:348
+#: src/Navigation/Notifications/Repository/Notify.php:349
#, php-format
msgid "%1$s posted to your profile wall at %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:349
+#: src/Navigation/Notifications/Repository/Notify.php:350
#, php-format
msgid "%1$s posted to [url=%2$s]your wall[/url]"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:361
+#: src/Navigation/Notifications/Repository/Notify.php:362
#, php-format
msgid "%1$s %2$s poked you"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:363
+#: src/Navigation/Notifications/Repository/Notify.php:364
#, php-format
msgid "%1$s poked you at %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:364
+#: src/Navigation/Notifications/Repository/Notify.php:365
#, php-format
msgid "%1$s [url=%2$s]poked you[/url]."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:381
+#: src/Navigation/Notifications/Repository/Notify.php:382
#, php-format
msgid "%s Introduction received"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:383
+#: src/Navigation/Notifications/Repository/Notify.php:384
#, php-format
msgid "You've received an introduction from '%1$s' at %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:384
+#: src/Navigation/Notifications/Repository/Notify.php:385
#, php-format
msgid "You've received [url=%1$s]an introduction[/url] from %2$s."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:389
-#: src/Navigation/Notifications/Repository/Notify.php:435
+#: src/Navigation/Notifications/Repository/Notify.php:390
+#: src/Navigation/Notifications/Repository/Notify.php:436
#, php-format
msgid "You may visit their profile at %s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:391
+#: src/Navigation/Notifications/Repository/Notify.php:392
#, php-format
msgid "Please visit %s to approve or reject the introduction."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:398
+#: src/Navigation/Notifications/Repository/Notify.php:399
#, php-format
msgid "%s A new person is sharing with you"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:400
#: src/Navigation/Notifications/Repository/Notify.php:401
+#: src/Navigation/Notifications/Repository/Notify.php:402
#, php-format
msgid "%1$s is sharing with you at %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:408
+#: src/Navigation/Notifications/Repository/Notify.php:409
#, php-format
msgid "%s You have a new follower"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:410
#: src/Navigation/Notifications/Repository/Notify.php:411
+#: src/Navigation/Notifications/Repository/Notify.php:412
#, php-format
msgid "You have a new follower at %2$s : %1$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:424
+#: src/Navigation/Notifications/Repository/Notify.php:425
#, php-format
msgid "%s Friend suggestion received"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:426
+#: src/Navigation/Notifications/Repository/Notify.php:427
#, php-format
msgid "You've received a friend suggestion from '%1$s' at %2$s"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:427
+#: src/Navigation/Notifications/Repository/Notify.php:428
#, php-format
msgid "You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:433
+#: src/Navigation/Notifications/Repository/Notify.php:434
msgid "Name:"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:434
+#: src/Navigation/Notifications/Repository/Notify.php:435
msgid "Photo:"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:437
+#: src/Navigation/Notifications/Repository/Notify.php:438
#, php-format
msgid "Please visit %s to approve or reject the suggestion."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:445
-#: src/Navigation/Notifications/Repository/Notify.php:460
+#: src/Navigation/Notifications/Repository/Notify.php:446
+#: src/Navigation/Notifications/Repository/Notify.php:461
#, php-format
msgid "%s Connection accepted"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:447
-#: src/Navigation/Notifications/Repository/Notify.php:462
-#, php-format
-msgid "'%1$s' has accepted your connection request at %2$s"
-msgstr ""
-
#: src/Navigation/Notifications/Repository/Notify.php:448
#: src/Navigation/Notifications/Repository/Notify.php:463
#, php-format
+msgid "'%1$s' has accepted your connection request at %2$s"
+msgstr ""
+
+#: src/Navigation/Notifications/Repository/Notify.php:449
+#: src/Navigation/Notifications/Repository/Notify.php:464
+#, php-format
msgid "%2$s has accepted your [url=%1$s]connection request[/url]."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:453
+#: src/Navigation/Notifications/Repository/Notify.php:454
msgid ""
"You are now mutual friends and may exchange status updates, photos, and "
"email without restriction."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:455
+#: src/Navigation/Notifications/Repository/Notify.php:456
#, php-format
msgid "Please visit %s if you wish to make any changes to this relationship."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:468
+#: src/Navigation/Notifications/Repository/Notify.php:469
#, php-format
msgid ""
"'%1$s' has chosen to accept you a fan, which restricts some forms of "
@@ -10492,33 +10545,33 @@ msgid ""
"automatically."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:470
+#: src/Navigation/Notifications/Repository/Notify.php:471
#, php-format
msgid ""
"'%1$s' may choose to extend this into a two-way or more permissive "
"relationship in the future."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:472
+#: src/Navigation/Notifications/Repository/Notify.php:473
#, php-format
msgid "Please visit %s if you wish to make any changes to this relationship."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:482
+#: src/Navigation/Notifications/Repository/Notify.php:483
msgid "registration request"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:484
-#, php-format
-msgid "You've received a registration request from '%1$s' at %2$s"
-msgstr ""
-
#: src/Navigation/Notifications/Repository/Notify.php:485
#, php-format
+msgid "You've received a registration request from '%1$s' at %2$s"
+msgstr ""
+
+#: src/Navigation/Notifications/Repository/Notify.php:486
+#, php-format
msgid "You've received a [url=%1$s]registration request[/url] from %2$s."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:490
+#: src/Navigation/Notifications/Repository/Notify.php:491
#, php-format
msgid ""
"Full Name:\t%s\n"
@@ -10526,17 +10579,17 @@ msgid ""
"Login Name:\t%s (%s)"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:496
+#: src/Navigation/Notifications/Repository/Notify.php:497
#, php-format
msgid "Please visit %s to approve or reject the request."
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:763
+#: src/Navigation/Notifications/Repository/Notify.php:764
#, php-format
msgid "%s %s tagged you"
msgstr ""
-#: src/Navigation/Notifications/Repository/Notify.php:766
+#: src/Navigation/Notifications/Repository/Notify.php:767
#, php-format
msgid "%s %s shared a new post"
msgstr ""
@@ -10563,244 +10616,244 @@ msgstr ""
msgid "%s posted an update."
msgstr ""
-#: src/Object/Post.php:134
+#: src/Object/Post.php:136
msgid "Private Message"
msgstr ""
-#: src/Object/Post.php:137
+#: src/Object/Post.php:140
msgid "Public Message"
msgstr ""
-#: src/Object/Post.php:140
+#: src/Object/Post.php:144
msgid "Unlisted Message"
msgstr ""
-#: src/Object/Post.php:170
+#: src/Object/Post.php:179
msgid "This entry was edited"
msgstr ""
-#: src/Object/Post.php:198
+#: src/Object/Post.php:207
msgid "Connector Message"
msgstr ""
-#: src/Object/Post.php:213 src/Object/Post.php:215
+#: src/Object/Post.php:222 src/Object/Post.php:224
msgid "Edit"
msgstr ""
-#: src/Object/Post.php:239
+#: src/Object/Post.php:248
msgid "Delete globally"
msgstr ""
-#: src/Object/Post.php:239
+#: src/Object/Post.php:248
msgid "Remove locally"
msgstr ""
-#: src/Object/Post.php:255
+#: src/Object/Post.php:264
#, php-format
msgid "Block %s"
msgstr ""
-#: src/Object/Post.php:260
+#: src/Object/Post.php:269
msgid "Save to folder"
msgstr ""
-#: src/Object/Post.php:294
+#: src/Object/Post.php:304
msgid "I will attend"
msgstr ""
-#: src/Object/Post.php:294
+#: src/Object/Post.php:304
msgid "I will not attend"
msgstr ""
-#: src/Object/Post.php:294
+#: src/Object/Post.php:304
msgid "I might attend"
msgstr ""
-#: src/Object/Post.php:324
+#: src/Object/Post.php:334
msgid "Ignore thread"
msgstr ""
-#: src/Object/Post.php:325
+#: src/Object/Post.php:335
msgid "Unignore thread"
msgstr ""
-#: src/Object/Post.php:326
+#: src/Object/Post.php:336
msgid "Toggle ignore status"
msgstr ""
-#: src/Object/Post.php:336
+#: src/Object/Post.php:346
msgid "Add star"
msgstr ""
-#: src/Object/Post.php:337
+#: src/Object/Post.php:347
msgid "Remove star"
msgstr ""
-#: src/Object/Post.php:338
+#: src/Object/Post.php:348
msgid "Toggle star status"
msgstr ""
-#: src/Object/Post.php:349
+#: src/Object/Post.php:359
msgid "Pin"
msgstr ""
-#: src/Object/Post.php:350
+#: src/Object/Post.php:360
msgid "Unpin"
msgstr ""
-#: src/Object/Post.php:351
+#: src/Object/Post.php:361
msgid "Toggle pin status"
msgstr ""
-#: src/Object/Post.php:354
+#: src/Object/Post.php:364
msgid "Pinned"
msgstr ""
-#: src/Object/Post.php:359
+#: src/Object/Post.php:369
msgid "Add tag"
msgstr ""
-#: src/Object/Post.php:372
+#: src/Object/Post.php:382
msgid "Quote share this"
msgstr ""
-#: src/Object/Post.php:372
+#: src/Object/Post.php:382
msgid "Quote Share"
msgstr ""
-#: src/Object/Post.php:375
+#: src/Object/Post.php:385
msgid "Reshare this"
msgstr ""
-#: src/Object/Post.php:375
+#: src/Object/Post.php:385
msgid "Reshare"
msgstr ""
-#: src/Object/Post.php:376
+#: src/Object/Post.php:386
msgid "Cancel your Reshare"
msgstr ""
-#: src/Object/Post.php:376
+#: src/Object/Post.php:386
msgid "Unshare"
msgstr ""
-#: src/Object/Post.php:423
+#: src/Object/Post.php:433
#, php-format
msgid "%s (Received %s)"
msgstr ""
-#: src/Object/Post.php:428
+#: src/Object/Post.php:438
msgid "Comment this item on your system"
msgstr ""
-#: src/Object/Post.php:428
+#: src/Object/Post.php:438
msgid "Remote comment"
msgstr ""
-#: src/Object/Post.php:449
+#: src/Object/Post.php:459
msgid "Share via ..."
msgstr ""
-#: src/Object/Post.php:449
+#: src/Object/Post.php:459
msgid "Share via external services"
msgstr ""
-#: src/Object/Post.php:478
+#: src/Object/Post.php:488
msgid "to"
msgstr ""
-#: src/Object/Post.php:479
+#: src/Object/Post.php:489
msgid "via"
msgstr ""
-#: src/Object/Post.php:480
+#: src/Object/Post.php:490
msgid "Wall-to-Wall"
msgstr ""
-#: src/Object/Post.php:481
+#: src/Object/Post.php:491
msgid "via Wall-To-Wall:"
msgstr ""
-#: src/Object/Post.php:523
+#: src/Object/Post.php:533
#, php-format
msgid "Reply to %s"
msgstr ""
-#: src/Object/Post.php:526
+#: src/Object/Post.php:536
msgid "More"
msgstr ""
-#: src/Object/Post.php:544
+#: src/Object/Post.php:554
msgid "Notifier task is pending"
msgstr ""
-#: src/Object/Post.php:545
+#: src/Object/Post.php:555
msgid "Delivery to remote servers is pending"
msgstr ""
-#: src/Object/Post.php:546
+#: src/Object/Post.php:556
msgid "Delivery to remote servers is underway"
msgstr ""
-#: src/Object/Post.php:547
+#: src/Object/Post.php:557
msgid "Delivery to remote servers is mostly done"
msgstr ""
-#: src/Object/Post.php:548
+#: src/Object/Post.php:558
msgid "Delivery to remote servers is done"
msgstr ""
-#: src/Object/Post.php:568
+#: src/Object/Post.php:578
#, php-format
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
-#: src/Object/Post.php:569
+#: src/Object/Post.php:579
msgid "Show more"
msgstr ""
-#: src/Object/Post.php:570
+#: src/Object/Post.php:580
msgid "Show fewer"
msgstr ""
-#: src/Protocol/OStatus.php:1648
+#: src/Protocol/OStatus.php:1705
#, php-format
msgid "%s is now following %s."
msgstr ""
-#: src/Protocol/OStatus.php:1649
+#: src/Protocol/OStatus.php:1706
msgid "following"
msgstr ""
-#: src/Protocol/OStatus.php:1652
+#: src/Protocol/OStatus.php:1709
#, php-format
msgid "%s stopped following %s."
msgstr ""
-#: src/Protocol/OStatus.php:1653
+#: src/Protocol/OStatus.php:1710
msgid "stopped following"
msgstr ""
-#: src/Render/FriendicaSmartyEngine.php:52
+#: src/Render/FriendicaSmartyEngine.php:65
msgid "The folder view/smarty3/ must be writable by webserver."
msgstr ""
-#: src/Security/Authentication.php:221
+#: src/Security/Authentication.php:226
msgid "Login failed."
msgstr ""
-#: src/Security/Authentication.php:262
+#: src/Security/Authentication.php:267
msgid "Login failed. Please check your credentials."
msgstr ""
-#: src/Security/Authentication.php:360
+#: src/Security/Authentication.php:369
#, php-format
msgid "Welcome %s"
msgstr ""
-#: src/Security/Authentication.php:361
+#: src/Security/Authentication.php:370
msgid "Please upload a profile photo."
msgstr ""
@@ -10898,15 +10951,15 @@ msgstr ""
msgid "%1$d %2$s ago"
msgstr ""
-#: src/Worker/Delivery.php:524
+#: src/Worker/Delivery.php:525
msgid "(no subject)"
msgstr ""
-#: src/Worker/PushSubscription.php:103
+#: src/Worker/PushSubscription.php:112
msgid "Notification from Friendica"
msgstr ""
-#: src/Worker/PushSubscription.php:104
+#: src/Worker/PushSubscription.php:113
msgid "Empty Post"
msgstr ""
@@ -11052,39 +11105,39 @@ msgstr ""
msgid "Leave background image and color empty for theme defaults"
msgstr ""
-#: view/theme/frio/php/Image.php:40
+#: view/theme/frio/php/Image.php:39
msgid "Top Banner"
msgstr ""
-#: view/theme/frio/php/Image.php:40
+#: view/theme/frio/php/Image.php:39
msgid ""
"Resize image to the width of the screen and show background color below on "
"long pages."
msgstr ""
-#: view/theme/frio/php/Image.php:41
+#: view/theme/frio/php/Image.php:40
msgid "Full screen"
msgstr ""
-#: view/theme/frio/php/Image.php:41
+#: view/theme/frio/php/Image.php:40
msgid ""
"Resize image to fill entire screen, clipping either the right or the bottom."
msgstr ""
-#: view/theme/frio/php/Image.php:42
+#: view/theme/frio/php/Image.php:41
msgid "Single row mosaic"
msgstr ""
-#: view/theme/frio/php/Image.php:42
+#: view/theme/frio/php/Image.php:41
msgid ""
"Resize image to repeat it on a single row, either vertical or horizontal."
msgstr ""
-#: view/theme/frio/php/Image.php:43
+#: view/theme/frio/php/Image.php:42
msgid "Mosaic"
msgstr ""
-#: view/theme/frio/php/Image.php:43
+#: view/theme/frio/php/Image.php:42
msgid "Repeat image to fill the screen."
msgstr ""
diff --git a/view/templates/settings/twofactor/trusted_browsers.tpl b/view/templates/settings/twofactor/trusted_browsers.tpl
index 29d2ab29c..1a9ae91fe 100644
--- a/view/templates/settings/twofactor/trusted_browsers.tpl
+++ b/view/templates/settings/twofactor/trusted_browsers.tpl
@@ -10,6 +10,7 @@
{{$device_label}}
{{$os_label}}
{{$browser_label}}
+ {{$trusted_label}}
{{$created_label}}
{{$last_used_label}}
{{$remove_all_label}}
@@ -28,6 +29,9 @@
{{$trusted_browser.browser}}
+ {{$trusted_browser.trusted_labeled}}
+
+
{{$trusted_browser.created_ago}}
diff --git a/view/templates/twofactor/signout.tpl b/view/templates/twofactor/signout.tpl
new file mode 100644
index 000000000..f2a211102
--- /dev/null
+++ b/view/templates/twofactor/signout.tpl
@@ -0,0 +1,14 @@
+
+
{{$title}}
+
{{$message nofilter}}
+
+
+
diff --git a/view/templates/twofactor/trust.tpl b/view/templates/twofactor/trust.tpl
new file mode 100644
index 000000000..6bfe307d5
--- /dev/null
+++ b/view/templates/twofactor/trust.tpl
@@ -0,0 +1,14 @@
+
+
{{$title}}
+
{{$message nofilter}}
+
+
+
diff --git a/view/templates/twofactor/verify.tpl b/view/templates/twofactor/verify.tpl
index 938f98da0..2b1fe3142 100644
--- a/view/templates/twofactor/verify.tpl
+++ b/view/templates/twofactor/verify.tpl
@@ -18,8 +18,6 @@
{{include file="field_input.tpl" field=$verify_code}}
- {{include file="field_checkbox.tpl" field=$trust_browser}}
-
{{$verify_label}}