Merge pull request #13314 from MrPetovan/bug/13311-removeme-delegate

Add safeguards to user self-removal feature
This commit is contained in:
Michael Vogel 2023-10-14 20:53:09 +02:00 committed by GitHub
commit e0d4646c18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 606 additions and 467 deletions

View File

@ -0,0 +1,70 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Content\Widget;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Network\HTTPException;
use Friendica\Util\Strings;
class Hovercard
{
/**
* @param array $contact
* @param int $localUid Used to show user actions
* @return string
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\ServiceUnavailableException
* @throws \ImagickException
*/
public static function getHTML(array $contact, int $localUid = 0): string
{
if ($localUid) {
$actions = Contact::photoMenu($contact, $localUid);
} else {
$actions = [];
}
// Move the contact data to the profile array so we can deliver it to
$tpl = Renderer::getMarkupTemplate('hovercard.tpl');
return Renderer::replaceMacros($tpl, [
'$profile' => [
'name' => $contact['name'],
'nick' => $contact['nick'],
'addr' => $contact['addr'] ?: $contact['url'],
'thumb' => Contact::getThumb($contact),
'url' => Contact::magicLinkByContact($contact),
'nurl' => $contact['nurl'],
'location' => $contact['location'],
'about' => $contact['about'],
'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']),
'tags' => $contact['keywords'],
'bd' => $contact['bd'] <= DBA::NULL_DATE ? '' : $contact['bd'],
'account_type' => Contact::getAccountType($contact['contact-type']),
'contact_type' => $contact['contact-type'],
'actions' => $actions,
'self' => $contact['self'],
],
]);
}
}

View File

@ -37,11 +37,10 @@ use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Module; use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\Delivery; use Friendica\Protocol\Delivery;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images; use Friendica\Util\Images;
@ -1638,16 +1637,24 @@ class User
* @param int $uid user to remove * @param int $uid user to remove
* @return bool * @return bool
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException
*/ */
public static function remove(int $uid): bool public static function remove(int $uid): bool
{ {
if (empty($uid)) { if (empty($uid)) {
return false; throw new \InvalidArgumentException('uid needs to be greater than 0');
} }
Logger::notice('Removing user', ['user' => $uid]); Logger::notice('Removing user', ['user' => $uid]);
$user = DBA::selectFirst('user', [], ['uid' => $uid]); $user = self::getById($uid);
if (!$user) {
throw new HTTPException\NotFoundException('User not found with uid: ' . $uid);
}
if (DBA::exists('user', ['parent-uid' => $uid])) {
throw new \RuntimeException(DI::l10n()->t("User with delegates can't be removed, please remove delegate users first"));
}
Hook::callAll('remove_user', $user); Hook::callAll('remove_user', $user);

View File

@ -23,17 +23,15 @@ namespace Friendica\Module\Contact;
use Friendica\App; use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Content\Widget;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Module\Response; use Friendica\Module\Response;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Strings;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
/** /**
@ -88,35 +86,6 @@ class Hovercard extends BaseModule
throw new HTTPException\NotFoundException(); throw new HTTPException\NotFoundException();
} }
// Get the photo_menu - the menu if possible contact actions $this->httpExit(Widget\Hovercard::getHTML($contact, $this->userSession->getLocalUserId()));
if ($this->userSession->isAuthenticated()) {
$actions = Contact::photoMenu($contact, $this->userSession->getLocalUserId());
} else {
$actions = [];
}
// Move the contact data to the profile array so we can deliver it to
$tpl = Renderer::getMarkupTemplate('hovercard.tpl');
$o = Renderer::replaceMacros($tpl, [
'$profile' => [
'name' => $contact['name'],
'nick' => $contact['nick'],
'addr' => $contact['addr'] ?: $contact['url'],
'thumb' => Contact::getThumb($contact),
'url' => Contact::magicLinkByContact($contact),
'nurl' => $contact['nurl'],
'location' => $contact['location'],
'about' => $contact['about'],
'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']),
'tags' => $contact['keywords'],
'bd' => $contact['bd'] <= DBA::NULL_DATE ? '' : $contact['bd'],
'account_type' => Contact::getAccountType($contact['contact-type']),
'contact_type' => $contact['contact-type'],
'actions' => $actions,
'self' => $contact['self'],
],
]);
$this->httpExit($o);
} }
} }

View File

@ -1,152 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Core\Hook;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Notification;
use Friendica\Model\User;
use Friendica\Network\HTTPException\ForbiddenException;
use Friendica\Util\Proxy;
/**
* Switches current user between delegates/parent user
*/
class Delegation extends BaseModule
{
protected function post(array $request = [])
{
if (!DI::userSession()->getLocalUserId()) {
return;
}
$uid = DI::userSession()->getLocalUserId();
$orig_record = User::getById(DI::app()->getLoggedInUserId());
if (DI::userSession()->getSubManagedUserId()) {
$user = User::getById(DI::userSession()->getSubManagedUserId());
if (DBA::isResult($user)) {
$uid = intval($user['uid']);
$orig_record = $user;
}
}
$identity = intval($request['identity'] ?? 0);
if (!$identity) {
return;
}
$limited_id = 0;
$original_id = $uid;
$manages = DBA::selectToArray('manage', ['mid'], ['uid' => $uid]);
foreach ($manages as $manage) {
if ($identity == $manage['mid']) {
$limited_id = $manage['mid'];
break;
}
}
if ($limited_id) {
$user = User::getById($limited_id);
} else {
// Check if the target user is one of our children
$user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]);
// Check if the target user is one of our siblings
if (!DBA::isResult($user) && $orig_record['parent-uid']) {
$user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]);
}
// Check if it's our parent or our own user
if (!DBA::isResult($user)
&& (
$orig_record['parent-uid'] && $orig_record['parent-uid'] === $identity
||
$orig_record['uid'] && $orig_record['uid'] === $identity
)
) {
$user = User::getById($identity);
}
}
if (!DBA::isResult($user)) {
return;
}
DI::session()->clear();
DI::auth()->setForUser(DI::app(), $user, true, true);
if ($limited_id) {
DI::userSession()->setSubManagedUserId($original_id);
}
$ret = [];
Hook::callAll('home_init', $ret);
DI::sysmsg()->addNotice($this->t('You are now logged in as %s', $user['username']));
DI::baseUrl()->redirect('network');
}
protected function content(array $request = []): string
{
if (!DI::userSession()->getLocalUserId()) {
throw new ForbiddenException(DI::l10n()->t('Permission denied.'));
}
$identities = User::identities(DI::userSession()->getSubManagedUserId() ?: DI::userSession()->getLocalUserId());
//getting additional information for each identity
foreach ($identities as $key => $identity) {
$identities[$key]['thumb'] = User::getAvatarUrl($identity, Proxy::SIZE_THUMB);
$identities[$key]['selected'] = ($identity['nickname'] === DI::app()->getLoggedInUserNickname());
$condition = ["`msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", Notification\Type::INTRO, Notification\Type::MAIL];
$params = ['distinct' => true, 'expression' => 'parent'];
$notifications = DI::notify()->countForUser($identity['uid'], $condition, $params);
$params = ['distinct' => true, 'expression' => 'convid'];
$notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params);
$notifications += DI::intro()->countActiveForUser($identity['uid']);
$identities[$key]['notifications'] = $notifications;
}
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegation.tpl'), [
'$title' => DI::l10n()->t('Switch between your accounts'),
'$settings_label' => DI::l10n()->t('Manage your accounts'),
'$desc' => DI::l10n()->t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'),
'$choose' => DI::l10n()->t('Select an identity to manage: '),
'$identities' => $identities,
'$submit' => DI::l10n()->t('Submit'),
]);
return $o;
}
}

View File

@ -21,29 +21,48 @@
namespace Friendica\Module\Settings; namespace Friendica\Module\Settings;
use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Database\DBA; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\DI; use Friendica\Database\Database;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\BaseSettings; use Friendica\Module\BaseSettings;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Psr\Log\LoggerInterface;
/** /**
* Account delegation settings module * Account delegation settings module
*/ */
class Delegation extends BaseSettings class Delegation extends BaseSettings
{ {
/** @var SystemMessages */
private $systemMessages;
/** @var Database */
private $db;
public function __construct(Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->systemMessages = $systemMessages;
$this->db = $db;
}
protected function post(array $request = []) protected function post(array $request = [])
{ {
if (!DI::app()->isLoggedIn()) { if (!$this->session->isAuthenticated()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); return;
} }
BaseModule::checkFormSecurityTokenRedirectOnError('settings/delegation', 'delegate'); BaseModule::checkFormSecurityTokenRedirectOnError('settings/delegation', 'delegate');
$parent_uid = $request['parent_user'] ?? null; $parent_uid = $request['parent_user'] ?? null;
$parent_password = $request['parent_password'] ?? ''; $parent_password = $request['parent_password'] ?? '';
if ($parent_uid) { if ($parent_uid) {
@ -51,66 +70,63 @@ class Delegation extends BaseSettings
// An integer value will trigger the direct user query on uid in User::getAuthenticationInfo // An integer value will trigger the direct user query on uid in User::getAuthenticationInfo
$parent_uid = (int)$parent_uid; $parent_uid = (int)$parent_uid;
User::getIdFromPasswordAuthentication($parent_uid, $parent_password); User::getIdFromPasswordAuthentication($parent_uid, $parent_password);
DI::sysmsg()->addInfo(DI::l10n()->t('Delegation successfully granted.')); $this->systemMessages->addInfo($this->t('Delegation successfully granted.'));
} catch (\Exception $ex) { } catch (\Exception $ex) {
DI::sysmsg()->addNotice(DI::l10n()->t('Parent user not found, unavailable or password doesn\'t match.')); $this->systemMessages->addNotice($this->t('Parent user not found, unavailable or password doesn\'t match.'));
return; return;
} }
} else { } else {
DI::sysmsg()->addInfo(DI::l10n()->t('Delegation successfully revoked.')); $this->systemMessages->addInfo($this->t('Delegation successfully revoked.'));
} }
DBA::update('user', ['parent-uid' => $parent_uid], ['uid' => DI::userSession()->getLocalUserId()]); $this->db->update('user', ['parent-uid' => $parent_uid], ['uid' => $this->session->getLocalUserId()]);
} }
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
parent::content(); parent::content();
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->isAuthenticated()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
} }
$args = DI::args(); $action = $this->parameters['action'] ?? '';
$user_id = $this->parameters['user_id'] ?? 0;
// @TODO Replace with router-provided arguments
$action = $args->get(2);
$user_id = $args->get(3);
if ($action === 'add' && $user_id) { if ($action === 'add' && $user_id) {
if (DI::userSession()->getSubManagedUserId()) { if ($this->session->getSubManagedUserId()) {
DI::sysmsg()->addNotice(DI::l10n()->t('Delegated administrators can view but not change delegation permissions.')); $this->systemMessages->addNotice($this->t('Delegated administrators can view but not change delegation permissions.'));
DI::baseUrl()->redirect('settings/delegation'); $this->baseUrl->redirect('settings/delegation');
} }
$user = User::getById($user_id, ['nickname']); $user = User::getById($user_id, ['nickname']);
if (DBA::isResult($user)) { if ($this->db->isResult($user)) {
$condition = [ $condition = [
'uid' => DI::userSession()->getLocalUserId(), 'uid' => $this->session->getLocalUserId(),
'nurl' => Strings::normaliseLink(DI::baseUrl() . '/profile/' . $user['nickname']) 'nurl' => Strings::normaliseLink($this->baseUrl . '/profile/' . $user['nickname'])
]; ];
if (DBA::exists('contact', $condition)) { if ($this->db->exists('contact', $condition)) {
DBA::insert('manage', ['uid' => $user_id, 'mid' => DI::userSession()->getLocalUserId()]); $this->db->insert('manage', ['uid' => $user_id, 'mid' => $this->session->getLocalUserId()]);
} }
} else { } else {
DI::sysmsg()->addNotice(DI::l10n()->t('Delegate user not found.')); $this->systemMessages->addNotice($this->t('Delegate user not found.'));
} }
DI::baseUrl()->redirect('settings/delegation'); $this->baseUrl->redirect('settings/delegation');
} }
if ($action === 'remove' && $user_id) { if ($action === 'remove' && $user_id) {
if (DI::userSession()->getSubManagedUserId()) { if ($this->session->getSubManagedUserId()) {
DI::sysmsg()->addNotice(DI::l10n()->t('Delegated administrators can view but not change delegation permissions.')); $this->systemMessages->addNotice($this->t('Delegated administrators can view but not change delegation permissions.'));
DI::baseUrl()->redirect('settings/delegation'); $this->baseUrl->redirect('settings/delegation');
} }
DBA::delete('manage', ['uid' => $user_id, 'mid' => DI::userSession()->getLocalUserId()]); $this->db->delete('manage', ['uid' => $user_id, 'mid' => $this->session->getLocalUserId()]);
DI::baseUrl()->redirect('settings/delegation'); $this->baseUrl->redirect('settings/delegation');
} }
// find everybody that currently has delegated management to this account/page // find everybody that currently has delegated management to this account/page
$delegates = DBA::selectToArray('user', [], ['`uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = ?)', DI::userSession()->getLocalUserId()]); $delegates = $this->db->selectToArray('user', [], ['`uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = ?)', $this->session->getLocalUserId()]);
$uids = []; $uids = [];
foreach ($delegates as $user) { foreach ($delegates as $user) {
@ -119,69 +135,76 @@ class Delegation extends BaseSettings
// find every contact who might be a candidate for delegation // find every contact who might be a candidate for delegation
$potentials = []; $potentials = [];
$nicknames = []; $nicknames = [];
$condition = ['baseurl' => DI::baseUrl(), 'self' => false, 'uid' => DI::userSession()->getLocalUserId(), 'blocked' => false]; $condition = ['baseurl' => $this->baseUrl, 'self' => false, 'uid' => $this->session->getLocalUserId(), 'blocked' => false];
$contacts = DBA::select('contact', ['nick'], $condition); $contacts = $this->db->select('contact', ['nick'], $condition);
while ($contact = DBA::fetch($contacts)) { while ($contact = $this->db->fetch($contacts)) {
$nicknames[] = $contact['nick']; $nicknames[] = $contact['nick'];
} }
DBA::close($contacts); $this->db->close($contacts);
// get user records for all potential page delegates who are not already delegates or managers // get user records for all potential page delegates who are not already delegates or managers
$potentialDelegateUsers = DBA::selectToArray('user', ['uid', 'username', 'nickname'], ['nickname' => $nicknames]); $potentialDelegateUsers = $this->db->selectToArray(
'user',
['uid', 'username', 'nickname'],
[
'nickname' => $nicknames,
'account_removed' => false,
'account_expired' => false,
'blocked' => false,
]
);
foreach ($potentialDelegateUsers as $user) { foreach ($potentialDelegateUsers as $user) {
if (!in_array($user['uid'], $uids)) { if (!in_array($user['uid'], $uids)) {
$potentials[] = $user; $potentials[] = $user;
} }
} }
$parent_user = null; $parent_user = null;
$parent_password = null; $parent_password = null;
$user = User::getById(DI::userSession()->getLocalUserId(), ['parent-uid', 'email']); $user = User::getById($this->session->getLocalUserId(), ['parent-uid', 'email']);
if (DBA::isResult($user) && !DBA::exists('user', ['parent-uid' => DI::userSession()->getLocalUserId()])) { if ($this->db->isResult($user) && !$this->db->exists('user', ['parent-uid' => $this->session->getLocalUserId()])) {
$parent_uid = $user['parent-uid']; $parent_uid = $user['parent-uid'];
$parents = [0 => DI::l10n()->t('No parent user')]; $parents = [0 => $this->t('No parent user')];
$fields = ['uid', 'username', 'nickname']; $fields = ['uid', 'username', 'nickname'];
$condition = ['email' => $user['email'], 'verified' => true, 'blocked' => false, 'parent-uid' => null]; $condition = ['email' => $user['email'], 'verified' => true, 'blocked' => false, 'parent-uid' => null];
$parent_users = DBA::selectToArray('user', $fields, $condition); $parent_users = $this->db->selectToArray('user', $fields, $condition);
foreach($parent_users as $parent) { foreach ($parent_users as $parent) {
if ($parent['uid'] != DI::userSession()->getLocalUserId()) { if ($parent['uid'] != $this->session->getLocalUserId()) {
$parents[$parent['uid']] = sprintf('%s (%s)', $parent['username'], $parent['nickname']); $parents[$parent['uid']] = sprintf('%s (%s)', $parent['username'], $parent['nickname']);
} }
} }
$parent_user = ['parent_user', DI::l10n()->t('Parent User'), $parent_uid, '', $parents]; $parent_user = ['parent_user', $this->t('Parent User'), $parent_uid, '', $parents];
$parent_password = ['parent_password', DI::l10n()->t('Parent Password:'), '', DI::l10n()->t('Please enter the password of the parent account to legitimize your request.')]; $parent_password = ['parent_password', $this->t('Parent Password:'), '', $this->t('Please enter the password of the parent account to legitimize your request.')];
} }
$is_child_user = !empty($user['parent-uid']); $is_child_user = !empty($user['parent-uid']);
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/delegation.tpl'), [ return Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/delegation.tpl'), [
'$form_security_token' => BaseModule::getFormSecurityToken('delegate'), '$l10n' => [
'$account_header' => DI::l10n()->t('Additional Accounts'), 'account_header' => $this->t('Additional Accounts'),
'$account_desc' => DI::l10n()->t('Register additional accounts that are automatically connected to your existing account so you can manage them from this account.'), 'account_desc' => $this->t('Register additional accounts that are automatically connected to your existing account so you can manage them from this account.'),
'$add_account' => DI::l10n()->t('Register an additional account'), 'add_account' => $this->t('Register an additional account'),
'$parent_header' => DI::l10n()->t('Parent User'), 'parent_header' => $this->t('Parent User'),
'$parent_user' => $parent_user, 'parent_desc' => $this->t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'),
'$parent_password' => $parent_password, 'submit' => $this->t('Save Settings'),
'$parent_desc' => DI::l10n()->t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'), 'header' => $this->t('Manage Accounts'),
'$is_child_user' => $is_child_user, 'delegates_header' => $this->t('Delegates'),
'$submit' => DI::l10n()->t('Save Settings'), 'desc' => $this->t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'),
'$header' => DI::l10n()->t('Manage Accounts'), 'head_delegates' => $this->t('Existing Page Delegates'),
'$delegates_header' => DI::l10n()->t('Delegates'), 'head_potentials' => $this->t('Potential Delegates'),
'$base' => DI::baseUrl(), 'none' => $this->t('No entries.'),
'$desc' => DI::l10n()->t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'), ],
'$head_delegates' => DI::l10n()->t('Existing Page Delegates'),
'$delegates' => $delegates,
'$head_potentials' => DI::l10n()->t('Potential Delegates'),
'$potentials' => $potentials,
'$remove' => DI::l10n()->t('Remove'),
'$add' => DI::l10n()->t('Add'),
'$none' => DI::l10n()->t('No entries.')
]);
return $o; '$form_security_token' => BaseModule::getFormSecurityToken('delegate'),
'$parent_user' => $parent_user,
'$parent_password' => $parent_password,
'$is_child_user' => $is_child_user,
'$delegates' => $delegates,
'$potentials' => $potentials,
]);
} }
} }

View File

@ -22,11 +22,10 @@
namespace Friendica\Module\Settings; namespace Friendica\Module\Settings;
use Friendica\App; use Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Content\Widget;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Model\User\Cookie; use Friendica\Model\User\Cookie;
@ -40,10 +39,6 @@ use Psr\Log\LoggerInterface;
class RemoveMe extends BaseSettings class RemoveMe extends BaseSettings
{ {
/** @var IManageConfigValues */
private $config;
/** @var Database */
private $database;
/** @var Emailer */ /** @var Emailer */
private $emailer; private $emailer;
/** @var SystemMessages */ /** @var SystemMessages */
@ -51,12 +46,10 @@ class RemoveMe extends BaseSettings
/** @var Cookie */ /** @var Cookie */
private $cookie; private $cookie;
public function __construct(Cookie $cookie, SystemMessages $systemMessages, Emailer $emailer, Database $database, IManageConfigValues $config, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) public function __construct(Cookie $cookie, SystemMessages $systemMessages, Emailer $emailer, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{ {
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->config = $config;
$this->database = $database;
$this->emailer = $emailer; $this->emailer = $emailer;
$this->systemMessages = $systemMessages; $this->systemMessages = $systemMessages;
$this->cookie = $cookie; $this->cookie = $cookie;
@ -79,6 +72,9 @@ class RemoveMe extends BaseSettings
try { try {
$userId = User::getIdFromPasswordAuthentication($this->session->getLocalUserId(), trim($request[$hash])); $userId = User::getIdFromPasswordAuthentication($this->session->getLocalUserId(), trim($request[$hash]));
if ($userId != $this->session->getLocalUserId()) {
throw new \RuntimeException($this->t("There was a validation error, please make sure you're logged in with the account you want to remove and try again.") . ' ' . $this->t('If this error persists, please contact your administrator.'));
}
} catch (\Throwable $e) { } catch (\Throwable $e) {
$this->systemMessages->addNotice($e->getMessage()); $this->systemMessages->addNotice($e->getMessage());
return; return;
@ -100,13 +96,19 @@ class RemoveMe extends BaseSettings
$this->emailer->send($email); $this->emailer->send($email);
} }
User::remove($userId); try {
User::remove($userId);
$this->session->clear(); $this->session->clear();
$this->cookie->clear(); $this->cookie->clear();
$this->systemMessages->addInfo($this->t('Your user account has been successfully removed. Bye bye!')); $this->systemMessages->addInfo($this->t('Your account has been successfully removed. Bye bye!'));
$this->baseUrl->redirect(); $this->baseUrl->redirect();
} catch (\RuntimeException $e) {
$this->systemMessages->addNotice($e->getMessage());
} finally {
return;
}
} }
protected function content(array $request = []): string protected function content(array $request = []): string
@ -128,6 +130,9 @@ class RemoveMe extends BaseSettings
'title' => DI::l10n()->t('Remove My Account'), 'title' => DI::l10n()->t('Remove My Account'),
'desc' => DI::l10n()->t('This will completely remove your account. Once this has been done it is not recoverable.'), 'desc' => DI::l10n()->t('This will completely remove your account. Once this has been done it is not recoverable.'),
], ],
'$hovercard' => Widget\Hovercard::getHTML(User::getOwnerDataById($this->session->getLocalUserId())),
'$password' => [$hash, $this->t('Please enter your password for verification:'), null, null, true], '$password' => [$hash, $this->t('Please enter your password for verification:'), null, null, true],
]); ]);
} }

View File

@ -0,0 +1,195 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\User;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Contact\Introduction\Repository\Introduction;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Model\Notification;
use Friendica\Model\User;
use Friendica\Module\Response;
use Friendica\Navigation\Notifications\Repository\Notify;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException\ForbiddenException;
use Friendica\Security\Authentication;
use Friendica\Util;
use Psr\Log\LoggerInterface;
/**
* Switches current user between delegates/parent user
*/
class Delegation extends BaseModule
{
/** @var IHandleUserSessions */
private $session;
/** @var Database */
private $db;
/** @var Authentication */
private $auth;
/** @var SystemMessages */
private $systemMessages;
/** @var Notify */
private $notify;
/** @var Introduction */
private $intro;
/** @var App */
private $app;
public function __construct(App $app, Introduction $intro, Notify $notify, SystemMessages $systemMessages, Authentication $auth, Database $db, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Util\Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->db = $db;
$this->auth = $auth;
$this->systemMessages = $systemMessages;
$this->notify = $notify;
$this->intro = $intro;
$this->app = $app;
}
protected function post(array $request = [])
{
if (!$this->session->getLocalUserId()) {
return;
}
$uid = $this->session->getLocalUserId();
$orig_record = User::getById($this->session->getLocalUserId());
if ($this->session->getSubManagedUserId()) {
$user = User::getById($this->session->getSubManagedUserId());
if ($this->db->isResult($user)) {
$uid = intval($user['uid']);
$orig_record = $user;
}
}
$identity = intval($request['identity'] ?? 0);
if (!$identity) {
return;
}
$limited_id = 0;
$original_id = $uid;
$manages = $this->db->selectToArray('manage', ['mid'], ['uid' => $uid]);
foreach ($manages as $manage) {
if ($identity == $manage['mid']) {
$limited_id = $manage['mid'];
break;
}
}
if ($limited_id) {
$user = User::getById($limited_id);
} else {
// Check if the target user is one of our children
$user = $this->db->selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]);
// Check if the target user is one of our siblings
if (!$this->db->isResult($user) && $orig_record['parent-uid']) {
$user = $this->db->selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]);
}
// Check if it's our parent or our own user
if (!$this->db->isResult($user)
&& (
$orig_record['parent-uid'] && $orig_record['parent-uid'] === $identity
||
$orig_record['uid'] && $orig_record['uid'] === $identity
)
) {
$user = User::getById($identity);
}
}
if (!$this->db->isResult($user)) {
return;
}
$this->session->clear();
$this->auth->setForUser($this->app, $user, true, true);
if ($limited_id) {
$this->session->setSubManagedUserId($original_id);
}
$ret = [];
Hook::callAll('home_init', $ret);
$this->systemMessages->addNotice($this->t('You are now logged in as %s', $user['username']));
$this->baseUrl->redirect('network');
}
protected function content(array $request = []): string
{
if (!$this->session->getLocalUserId()) {
throw new ForbiddenException($this->t('Permission denied.'));
}
$identities = User::identities($this->session->getSubManagedUserId() ?: $this->session->getLocalUserId());
//getting additional information for each identity
foreach ($identities as $key => $identity) {
$identities[$key]['thumb'] = User::getAvatarUrl($identity, Util\Proxy::SIZE_THUMB);
$identities[$key]['selected'] = ($identity['nickname'] === $this->session->getLocalUserNickname());
$notifications = $this->notify->countForUser(
$identity['uid'],
["`msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", Notification\Type::INTRO, Notification\Type::MAIL],
['distinct' => true, 'expression' => 'parent']
);
$notifications += $this->db->count(
'mail',
['uid' => $identity['uid'], 'seen' => false],
['distinct' => true, 'expression' => 'convid']
);
$notifications += $this->intro->countActiveForUser($identity['uid']);
$identities[$key]['notifications'] = $notifications;
}
$tpl = Renderer::getMarkupTemplate('delegation.tpl');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
'title' => $this->t('Switch between your accounts'),
'settings_label' => $this->t('Manage your accounts'),
'desc' => $this->t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'),
'choose' => $this->t('Select an identity to manage: '),
'submit' => $this->t('Submit'),
],
'$identities' => $identities,
]);
}
}

View File

@ -423,8 +423,8 @@ return [
], ],
'/credits' => [Module\Credits::class, [R::GET]], '/credits' => [Module\Credits::class, [R::GET]],
'/delegation' => [Module\Delegation::class, [R::GET, R::POST]], '/delegation' => [Module\User\Delegation::class, [R::GET, R::POST]],
'/dfrn_notify[/{nickname}]' => [Module\DFRN\Notify::class, [R::POST]], '/dfrn_notify[/{nickname}]' => [Module\DFRN\Notify::class, [ R::POST]],
'/dfrn_poll/{nickname}' => [Module\DFRN\Poll::class, [R::GET]], '/dfrn_poll/{nickname}' => [Module\DFRN\Poll::class, [R::GET]],
'/dirfind' => [Module\Search\Directory::class, [R::GET]], '/dirfind' => [Module\Search\Directory::class, [R::GET]],
'/directory' => [Module\Directory::class, [R::GET]], '/directory' => [Module\Directory::class, [R::GET]],

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2023.09-rc\n" "Project-Id-Version: 2023.09-rc\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-10-11 20:35+0000\n" "POT-Creation-Date: 2023-10-14 14:18-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -46,7 +46,7 @@ msgstr ""
#: mod/item.php:452 mod/message.php:67 mod/message.php:113 mod/notes.php:45 #: mod/item.php:452 mod/message.php:67 mod/message.php:113 mod/notes.php:45
#: mod/photos.php:152 mod/photos.php:670 src/Model/Event.php:520 #: mod/photos.php:152 mod/photos.php:670 src/Model/Event.php:520
#: src/Module/Attach.php:55 src/Module/BaseApi.php:99 #: src/Module/Attach.php:55 src/Module/BaseApi.php:103
#: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:50 #: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:50
#: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84 #: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84
#: src/Module/Calendar/Export.php:82 src/Module/Calendar/Show.php:82 #: src/Module/Calendar/Export.php:82 src/Module/Calendar/Show.php:82
@ -55,9 +55,9 @@ msgstr ""
#: src/Module/Contact/Follow.php:160 src/Module/Contact/MatchInterests.php:86 #: src/Module/Contact/Follow.php:160 src/Module/Contact/MatchInterests.php:86
#: src/Module/Contact/Suggestions.php:54 src/Module/Contact/Unfollow.php:66 #: src/Module/Contact/Suggestions.php:54 src/Module/Contact/Unfollow.php:66
#: src/Module/Contact/Unfollow.php:80 src/Module/Contact/Unfollow.php:112 #: src/Module/Contact/Unfollow.php:80 src/Module/Contact/Unfollow.php:112
#: src/Module/Delegation.php:118 src/Module/FollowConfirm.php:38 #: src/Module/FollowConfirm.php:38 src/Module/FriendSuggest.php:57
#: src/Module/FriendSuggest.php:57 src/Module/Invite.php:42 #: src/Module/Invite.php:42 src/Module/Invite.php:131
#: src/Module/Invite.php:131 src/Module/Notifications/Notification.php:76 #: src/Module/Notifications/Notification.php:76
#: src/Module/Notifications/Notification.php:107 #: src/Module/Notifications/Notification.php:107
#: src/Module/OStatus/Repair.php:60 src/Module/OStatus/Subscribe.php:66 #: src/Module/OStatus/Repair.php:60 src/Module/OStatus/Subscribe.php:66
#: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:75 #: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:75
@ -69,16 +69,16 @@ msgstr ""
#: src/Module/Register.php:245 src/Module/Search/Directory.php:37 #: src/Module/Register.php:245 src/Module/Search/Directory.php:37
#: src/Module/Settings/Account.php:50 src/Module/Settings/Account.php:408 #: src/Module/Settings/Account.php:50 src/Module/Settings/Account.php:408
#: src/Module/Settings/Channels.php:56 src/Module/Settings/Channels.php:114 #: src/Module/Settings/Channels.php:56 src/Module/Settings/Channels.php:114
#: src/Module/Settings/Delegation.php:41 src/Module/Settings/Delegation.php:71 #: src/Module/Settings/Delegation.php:90 src/Module/Settings/Display.php:90
#: src/Module/Settings/Display.php:90 src/Module/Settings/Display.php:193 #: src/Module/Settings/Display.php:193
#: src/Module/Settings/Profile/Photo/Crop.php:165 #: src/Module/Settings/Profile/Photo/Crop.php:165
#: src/Module/Settings/Profile/Photo/Index.php:111 #: src/Module/Settings/Profile/Photo/Index.php:111
#: src/Module/Settings/RemoveMe.php:117 src/Module/Settings/UserExport.php:80 #: src/Module/Settings/RemoveMe.php:119 src/Module/Settings/UserExport.php:80
#: src/Module/Settings/UserExport.php:114 #: src/Module/Settings/UserExport.php:114
#: src/Module/Settings/UserExport.php:215 #: src/Module/Settings/UserExport.php:215
#: src/Module/Settings/UserExport.php:235 #: src/Module/Settings/UserExport.php:235
#: src/Module/Settings/UserExport.php:300 src/Module/User/Import.php:84 #: src/Module/Settings/UserExport.php:300 src/Module/User/Delegation.php:154
#: src/Module/User/Import.php:91 #: src/Module/User/Import.php:84 src/Module/User/Import.php:91
msgid "Permission denied." msgid "Permission denied."
msgstr "" msgstr ""
@ -307,19 +307,20 @@ msgstr ""
#: src/Module/Debug/ActivityPubConversion.php:140 #: src/Module/Debug/ActivityPubConversion.php:140
#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64
#: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51 #: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51
#: src/Module/Delegation.php:147 src/Module/FriendSuggest.php:145 #: src/Module/FriendSuggest.php:145 src/Module/Install.php:234
#: src/Module/Install.php:234 src/Module/Install.php:274 #: src/Module/Install.php:274 src/Module/Install.php:309
#: src/Module/Install.php:309 src/Module/Invite.php:178 #: src/Module/Invite.php:178 src/Module/Item/Compose.php:189
#: src/Module/Item/Compose.php:189 src/Module/Moderation/Item/Source.php:79 #: src/Module/Moderation/Item/Source.php:79
#: src/Module/Moderation/Report/Create.php:168 #: src/Module/Moderation/Report/Create.php:168
#: src/Module/Moderation/Report/Create.php:183 #: src/Module/Moderation/Report/Create.php:183
#: src/Module/Moderation/Report/Create.php:211 #: src/Module/Moderation/Report/Create.php:211
#: src/Module/Moderation/Report/Create.php:263 #: src/Module/Moderation/Report/Create.php:263
#: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155 #: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155
#: src/Module/Settings/Profile/Index.php:257 #: src/Module/Settings/Profile/Index.php:257
#: src/Module/Settings/Server/Action.php:79 src/Object/Post.php:1106 #: src/Module/Settings/Server/Action.php:79 src/Module/User/Delegation.php:189
#: view/theme/duepuntozero/config.php:85 view/theme/frio/config.php:171 #: src/Object/Post.php:1106 view/theme/duepuntozero/config.php:85
#: view/theme/quattro/config.php:87 view/theme/vier/config.php:135 #: view/theme/frio/config.php:171 view/theme/quattro/config.php:87
#: view/theme/vier/config.php:135
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
@ -960,7 +961,7 @@ msgstr ""
msgid "Enter user nickname: " msgid "Enter user nickname: "
msgstr "" msgstr ""
#: src/Console/User.php:182 src/Model/User.php:711 #: src/Console/User.php:182 src/Model/User.php:710
#: src/Module/Api/Twitter/ContactEndpoint.php:74 #: src/Module/Api/Twitter/ContactEndpoint.php:74
#: src/Module/Moderation/Users/Active.php:71 #: src/Module/Moderation/Users/Active.php:71
#: src/Module/Moderation/Users/Blocked.php:71 #: src/Module/Moderation/Users/Blocked.php:71
@ -1748,7 +1749,7 @@ msgstr ""
#: src/Content/GroupManager.php:152 src/Content/Nav.php:278 #: src/Content/GroupManager.php:152 src/Content/Nav.php:278
#: src/Content/Text/HTML.php:880 src/Content/Widget.php:537 #: src/Content/Text/HTML.php:880 src/Content/Widget.php:537
#: src/Model/User.php:1273 #: src/Model/User.php:1272
msgid "Groups" msgid "Groups"
msgstr "" msgstr ""
@ -2205,11 +2206,11 @@ msgstr ""
msgid "Encrypted content" msgid "Encrypted content"
msgstr "" msgstr ""
#: src/Content/Text/BBCode.php:1957 #: src/Content/Text/BBCode.php:1953
msgid "Invalid source protocol" msgid "Invalid source protocol"
msgstr "" msgstr ""
#: src/Content/Text/BBCode.php:1976 #: src/Content/Text/BBCode.php:1972
msgid "Invalid link protocol" msgid "Invalid link protocol"
msgstr "" msgstr ""
@ -2724,8 +2725,8 @@ msgstr ""
#: src/Core/Installer.php:519 #: src/Core/Installer.php:519
msgid "" msgid ""
"The web installer needs to be able to create a file called \"local.config.php" "The web installer needs to be able to create a file called \"local.config."
"\" in the \"config\" folder of your web server and it is unable to do so." "php\" in the \"config\" folder of your web server and it is unable to do so."
msgstr "" msgstr ""
#: src/Core/Installer.php:520 #: src/Core/Installer.php:520
@ -3146,24 +3147,24 @@ msgstr ""
msgid "%s: updating %s table." msgid "%s: updating %s table."
msgstr "" msgstr ""
#: src/Factory/Api/Mastodon/Error.php:55 #: src/Factory/Api/Mastodon/Error.php:42
msgid "Record not found" msgid "Record not found"
msgstr "" msgstr ""
#: src/Factory/Api/Mastodon/Error.php:65 #: src/Factory/Api/Mastodon/Error.php:49
msgid "Unprocessable Entity" msgid "Unprocessable Entity"
msgstr "" msgstr ""
#: src/Factory/Api/Mastodon/Error.php:75 #: src/Factory/Api/Mastodon/Error.php:56
msgid "Unauthorized" msgid "Unauthorized"
msgstr "" msgstr ""
#: src/Factory/Api/Mastodon/Error.php:84 #: src/Factory/Api/Mastodon/Error.php:62
msgid "" msgid ""
"Token is not authorized with a valid user or is missing a required scope" "Token is not authorized with a valid user or is missing a required scope"
msgstr "" msgstr ""
#: src/Factory/Api/Mastodon/Error.php:94 #: src/Factory/Api/Mastodon/Error.php:69
msgid "Internal Server Error" msgid "Internal Server Error"
msgstr "" msgstr ""
@ -3624,145 +3625,145 @@ msgstr ""
msgid "Contact information and Social Networks" msgid "Contact information and Social Networks"
msgstr "" msgstr ""
#: src/Model/User.php:227 src/Model/User.php:1186 #: src/Model/User.php:226 src/Model/User.php:1185
msgid "SERIOUS ERROR: Generation of security keys failed." msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr "" msgstr ""
#: src/Model/User.php:620 src/Model/User.php:653 #: src/Model/User.php:619 src/Model/User.php:652
msgid "Login failed" msgid "Login failed"
msgstr "" msgstr ""
#: src/Model/User.php:685 #: src/Model/User.php:684
msgid "Not enough information to authenticate" msgid "Not enough information to authenticate"
msgstr "" msgstr ""
#: src/Model/User.php:806 #: src/Model/User.php:805
msgid "Password can't be empty" msgid "Password can't be empty"
msgstr "" msgstr ""
#: src/Model/User.php:848 #: src/Model/User.php:847
msgid "Empty passwords are not allowed." msgid "Empty passwords are not allowed."
msgstr "" msgstr ""
#: src/Model/User.php:852 #: src/Model/User.php:851
msgid "" msgid ""
"The new password has been exposed in a public data dump, please choose " "The new password has been exposed in a public data dump, please choose "
"another." "another."
msgstr "" msgstr ""
#: src/Model/User.php:856 #: src/Model/User.php:855
msgid "The password length is limited to 72 characters." msgid "The password length is limited to 72 characters."
msgstr "" msgstr ""
#: src/Model/User.php:860 #: src/Model/User.php:859
msgid "The password can't contain white spaces nor accentuated letters" msgid "The password can't contain white spaces nor accentuated letters"
msgstr "" msgstr ""
#: src/Model/User.php:1069 #: src/Model/User.php:1068
msgid "Passwords do not match. Password unchanged." msgid "Passwords do not match. Password unchanged."
msgstr "" msgstr ""
#: src/Model/User.php:1076 #: src/Model/User.php:1075
msgid "An invitation is required." msgid "An invitation is required."
msgstr "" msgstr ""
#: src/Model/User.php:1080 #: src/Model/User.php:1079
msgid "Invitation could not be verified." msgid "Invitation could not be verified."
msgstr "" msgstr ""
#: src/Model/User.php:1088 #: src/Model/User.php:1087
msgid "Invalid OpenID url" msgid "Invalid OpenID url"
msgstr "" msgstr ""
#: src/Model/User.php:1101 src/Security/Authentication.php:241 #: src/Model/User.php:1100 src/Security/Authentication.php:241
msgid "" msgid ""
"We encountered a problem while logging in with the OpenID you provided. " "We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID." "Please check the correct spelling of the ID."
msgstr "" msgstr ""
#: src/Model/User.php:1101 src/Security/Authentication.php:241 #: src/Model/User.php:1100 src/Security/Authentication.php:241
msgid "The error message was:" msgid "The error message was:"
msgstr "" msgstr ""
#: src/Model/User.php:1107 #: src/Model/User.php:1106
msgid "Please enter the required information." msgid "Please enter the required information."
msgstr "" msgstr ""
#: src/Model/User.php:1121 #: src/Model/User.php:1120
#, php-format #, php-format
msgid "" msgid ""
"system.username_min_length (%s) and system.username_max_length (%s) are " "system.username_min_length (%s) and system.username_max_length (%s) are "
"excluding each other, swapping values." "excluding each other, swapping values."
msgstr "" msgstr ""
#: src/Model/User.php:1128 #: src/Model/User.php:1127
#, php-format #, php-format
msgid "Username should be at least %s character." msgid "Username should be at least %s character."
msgid_plural "Username should be at least %s characters." msgid_plural "Username should be at least %s characters."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/User.php:1132 #: src/Model/User.php:1131
#, php-format #, php-format
msgid "Username should be at most %s character." msgid "Username should be at most %s character."
msgid_plural "Username should be at most %s characters." msgid_plural "Username should be at most %s characters."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/User.php:1140 #: src/Model/User.php:1139
msgid "That doesn't appear to be your full (First Last) name." msgid "That doesn't appear to be your full (First Last) name."
msgstr "" msgstr ""
#: src/Model/User.php:1145 #: src/Model/User.php:1144
msgid "Your email domain is not among those allowed on this site." msgid "Your email domain is not among those allowed on this site."
msgstr "" msgstr ""
#: src/Model/User.php:1149 #: src/Model/User.php:1148
msgid "Not a valid email address." msgid "Not a valid email address."
msgstr "" msgstr ""
#: src/Model/User.php:1152 #: src/Model/User.php:1151
msgid "The nickname was blocked from registration by the nodes admin." msgid "The nickname was blocked from registration by the nodes admin."
msgstr "" msgstr ""
#: src/Model/User.php:1156 src/Model/User.php:1162 #: src/Model/User.php:1155 src/Model/User.php:1161
msgid "Cannot use that email." msgid "Cannot use that email."
msgstr "" msgstr ""
#: src/Model/User.php:1168 #: src/Model/User.php:1167
msgid "Your nickname can only contain a-z, 0-9 and _." msgid "Your nickname can only contain a-z, 0-9 and _."
msgstr "" msgstr ""
#: src/Model/User.php:1176 src/Model/User.php:1233 #: src/Model/User.php:1175 src/Model/User.php:1232
msgid "Nickname is already registered. Please choose another." msgid "Nickname is already registered. Please choose another."
msgstr "" msgstr ""
#: src/Model/User.php:1220 src/Model/User.php:1224 #: src/Model/User.php:1219 src/Model/User.php:1223
msgid "An error occurred during registration. Please try again." msgid "An error occurred during registration. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1247 #: src/Model/User.php:1246
msgid "An error occurred creating your default profile. Please try again." msgid "An error occurred creating your default profile. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1254 #: src/Model/User.php:1253
msgid "An error occurred creating your self contact. Please try again." msgid "An error occurred creating your self contact. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1259 #: src/Model/User.php:1258
msgid "Friends" msgid "Friends"
msgstr "" msgstr ""
#: src/Model/User.php:1263 #: src/Model/User.php:1262
msgid "" msgid ""
"An error occurred creating your default contact circle. Please try again." "An error occurred creating your default contact circle. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1307 #: src/Model/User.php:1306
msgid "Profile Photos" msgid "Profile Photos"
msgstr "" msgstr ""
#: src/Model/User.php:1487 #: src/Model/User.php:1486
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3770,7 +3771,7 @@ msgid ""
"\t\t\tthe administrator of %2$s has set up an account for you." "\t\t\tthe administrator of %2$s has set up an account for you."
msgstr "" msgstr ""
#: src/Model/User.php:1490 #: src/Model/User.php:1489
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3808,12 +3809,12 @@ msgid ""
"\t\tThank you and welcome to %4$s." "\t\tThank you and welcome to %4$s."
msgstr "" msgstr ""
#: src/Model/User.php:1523 src/Model/User.php:1630 #: src/Model/User.php:1522 src/Model/User.php:1629
#, php-format #, php-format
msgid "Registration details for %s" msgid "Registration details for %s"
msgstr "" msgstr ""
#: src/Model/User.php:1543 #: src/Model/User.php:1542
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3829,12 +3830,12 @@ msgid ""
"\t\t" "\t\t"
msgstr "" msgstr ""
#: src/Model/User.php:1562 #: src/Model/User.php:1561
#, php-format #, php-format
msgid "Registration at %s" msgid "Registration at %s"
msgstr "" msgstr ""
#: src/Model/User.php:1586 #: src/Model/User.php:1585
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3843,7 +3844,7 @@ msgid ""
"\t\t\t" "\t\t\t"
msgstr "" msgstr ""
#: src/Model/User.php:1594 #: src/Model/User.php:1593
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3882,6 +3883,11 @@ msgid ""
"\t\t\tThank you and welcome to %2$s." "\t\t\tThank you and welcome to %2$s."
msgstr "" msgstr ""
#: src/Model/User.php:1656
msgid ""
"User with delegates can't be removed, please remove delegate users first"
msgstr ""
#: src/Module/Admin/Addons/Details.php:65 #: src/Module/Admin/Addons/Details.php:65
msgid "Addon not found." msgid "Addon not found."
msgstr "" msgstr ""
@ -3952,7 +3958,7 @@ msgstr ""
#: src/Module/Settings/Account.php:561 src/Module/Settings/Addons.php:78 #: src/Module/Settings/Account.php:561 src/Module/Settings/Addons.php:78
#: src/Module/Settings/Connectors.php:160 #: src/Module/Settings/Connectors.php:160
#: src/Module/Settings/Connectors.php:246 #: src/Module/Settings/Connectors.php:246
#: src/Module/Settings/Delegation.php:171 src/Module/Settings/Display.php:303 #: src/Module/Settings/Delegation.php:193 src/Module/Settings/Display.php:303
#: src/Module/Settings/Features.php:76 #: src/Module/Settings/Features.php:76
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
@ -5351,9 +5357,9 @@ msgstr ""
#: src/Module/Admin/Summary.php:98 #: src/Module/Admin/Summary.php:98
msgid "" msgid ""
"The last update failed. Please run \"php bin/console.php dbstructure update" "The last update failed. Please run \"php bin/console.php dbstructure "
"\" from the command line and have a look at the errors that might appear. " "update\" from the command line and have a look at the errors that might "
"(Some of the errors are possibly inside the logfile.)" "appear. (Some of the errors are possibly inside the logfile.)"
msgstr "" msgstr ""
#: src/Module/Admin/Summary.php:102 #: src/Module/Admin/Summary.php:102
@ -5504,8 +5510,8 @@ msgstr ""
#, php-format #, php-format
msgid "" msgid ""
"Show some informations regarding the needed information to operate the node " "Show some informations regarding the needed information to operate the node "
"according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer" "according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener "
"\">EU-GDPR</a>." "noreferrer\">EU-GDPR</a>."
msgstr "" msgstr ""
#: src/Module/Admin/Tos.php:81 #: src/Module/Admin/Tos.php:81
@ -5547,7 +5553,7 @@ msgstr ""
msgid "Only starting posts can be muted" msgid "Only starting posts can be muted"
msgstr "" msgstr ""
#: src/Module/Api/Mastodon/Statuses/Reblog.php:56 #: src/Module/Api/Mastodon/Statuses/Reblog.php:58
#, php-format #, php-format
msgid "Posts from %s can't be shared" msgid "Posts from %s can't be shared"
msgstr "" msgstr ""
@ -5560,7 +5566,7 @@ msgstr ""
msgid "Only starting posts can be unmuted" msgid "Only starting posts can be unmuted"
msgstr "" msgstr ""
#: src/Module/Api/Mastodon/Statuses/Unreblog.php:62 #: src/Module/Api/Mastodon/Statuses/Unreblog.php:64
#, php-format #, php-format
msgid "Posts from %s can't be unshared" msgid "Posts from %s can't be unshared"
msgstr "" msgstr ""
@ -5656,26 +5662,26 @@ msgstr ""
msgid "User registrations waiting for confirmation" msgid "User registrations waiting for confirmation"
msgstr "" msgstr ""
#: src/Module/BaseApi.php:451 src/Module/BaseApi.php:467 #: src/Module/BaseApi.php:455 src/Module/BaseApi.php:471
#: src/Module/BaseApi.php:483 #: src/Module/BaseApi.php:487
msgid "Too Many Requests" msgid "Too Many Requests"
msgstr "" msgstr ""
#: src/Module/BaseApi.php:452 #: src/Module/BaseApi.php:456
#, php-format #, php-format
msgid "Daily posting limit of %d post reached. The post was rejected." msgid "Daily posting limit of %d post reached. The post was rejected."
msgid_plural "Daily posting limit of %d posts reached. The post was rejected." msgid_plural "Daily posting limit of %d posts reached. The post was rejected."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Module/BaseApi.php:468 #: src/Module/BaseApi.php:472
#, php-format #, php-format
msgid "Weekly posting limit of %d post reached. The post was rejected." msgid "Weekly posting limit of %d post reached. The post was rejected."
msgid_plural "Weekly posting limit of %d posts reached. The post was rejected." msgid_plural "Weekly posting limit of %d posts reached. The post was rejected."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Module/BaseApi.php:484 #: src/Module/BaseApi.php:488
#, php-format #, php-format
msgid "Monthly posting limit of %d post reached. The post was rejected." msgid "Monthly posting limit of %d post reached. The post was rejected."
msgid_plural "" msgid_plural ""
@ -5790,7 +5796,7 @@ msgstr ""
msgid "Social Networks" msgid "Social Networks"
msgstr "" msgstr ""
#: src/Module/BaseSettings.php:146 src/Module/Settings/Delegation.php:172 #: src/Module/BaseSettings.php:146 src/Module/Settings/Delegation.php:194
msgid "Manage Accounts" msgid "Manage Accounts"
msgstr "" msgstr ""
@ -7049,29 +7055,6 @@ msgstr ""
msgid "Lookup address:" msgid "Lookup address:"
msgstr "" msgstr ""
#: src/Module/Delegation.php:110
#, php-format
msgid "You are now logged in as %s"
msgstr ""
#: src/Module/Delegation.php:142
msgid "Switch between your accounts"
msgstr ""
#: src/Module/Delegation.php:143
msgid "Manage your accounts"
msgstr ""
#: src/Module/Delegation.php:144
msgid ""
"Toggle between different identities or community/group pages which share "
"your account details or which you have been granted \"manage\" permissions"
msgstr ""
#: src/Module/Delegation.php:145
msgid "Select an identity to manage: "
msgstr ""
#: src/Module/Directory.php:74 #: src/Module/Directory.php:74
msgid "No entries (some entries may be hidden)." msgid "No entries (some entries may be hidden)."
msgstr "" msgstr ""
@ -8791,7 +8774,7 @@ msgstr ""
msgid "Select a tag to remove: " msgid "Select a tag to remove: "
msgstr "" msgstr ""
#: src/Module/Post/Tag/Remove.php:108 src/Module/Settings/Delegation.php:180 #: src/Module/Post/Tag/Remove.php:108
#: src/Module/Settings/TwoFactor/Trusted.php:144 #: src/Module/Settings/TwoFactor/Trusted.php:144
msgid "Remove" msgid "Remove"
msgstr "" msgstr ""
@ -8856,8 +8839,8 @@ msgstr ""
#: src/Module/Profile/Profile.php:158 #: src/Module/Profile/Profile.php:158
#, php-format #, php-format
msgid "" msgid ""
"You're currently viewing your profile as <b>%s</b> <a href=\"%s\" class=" "You're currently viewing your profile as <b>%s</b> <a href=\"%s\" "
"\"btn btn-sm pull-right\">Cancel</a>" "class=\"btn btn-sm pull-right\">Cancel</a>"
msgstr "" msgstr ""
#: src/Module/Profile/Profile.php:167 #: src/Module/Profile/Profile.php:167
@ -9105,11 +9088,11 @@ msgstr ""
msgid "Note: This node explicitly contains adult content" msgid "Note: This node explicitly contains adult content"
msgstr "" msgstr ""
#: src/Module/Register.php:183 src/Module/Settings/Delegation.php:156 #: src/Module/Register.php:183 src/Module/Settings/Delegation.php:181
msgid "Parent Password:" msgid "Parent Password:"
msgstr "" msgstr ""
#: src/Module/Register.php:183 src/Module/Settings/Delegation.php:156 #: src/Module/Register.php:183 src/Module/Settings/Delegation.php:181
msgid "" msgid ""
"Please enter the password of the parent account to legitimize your request." "Please enter the password of the parent account to legitimize your request."
msgstr "" msgstr ""
@ -9405,8 +9388,8 @@ msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:100 #: src/Module/Security/TwoFactor/Verify.php:100
#, php-format #, php-format
msgid "" msgid ""
"If you do not have access to your authentication code you can use a <a href=" "If you do not have access to your authentication code you can use a <a "
"\"%s\">two-factor recovery code</a>." "href=\"%s\">two-factor recovery code</a>."
msgstr "" msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101 #: src/Module/Security/TwoFactor/Verify.php:101
@ -10020,7 +10003,7 @@ msgstr ""
msgid "Add new entry to the channel list" msgid "Add new entry to the channel list"
msgstr "" msgstr ""
#: src/Module/Settings/Channels.php:160 src/Module/Settings/Delegation.php:181 #: src/Module/Settings/Channels.php:160
msgid "Add" msgid "Add"
msgstr "" msgstr ""
@ -10232,76 +10215,76 @@ msgstr ""
msgid "Move to folder:" msgid "Move to folder:"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:54 #: src/Module/Settings/Delegation.php:73
msgid "Delegation successfully granted." msgid "Delegation successfully granted."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:56 #: src/Module/Settings/Delegation.php:75
msgid "Parent user not found, unavailable or password doesn't match." msgid "Parent user not found, unavailable or password doesn't match."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:60 #: src/Module/Settings/Delegation.php:79
msgid "Delegation successfully revoked." msgid "Delegation successfully revoked."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:82 src/Module/Settings/Delegation.php:104 #: src/Module/Settings/Delegation.php:98 src/Module/Settings/Delegation.php:120
msgid "" msgid ""
"Delegated administrators can view but not change delegation permissions." "Delegated administrators can view but not change delegation permissions."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:96 #: src/Module/Settings/Delegation.php:112
msgid "Delegate user not found." msgid "Delegate user not found."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:144 #: src/Module/Settings/Delegation.php:169
msgid "No parent user" msgid "No parent user"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:155 #: src/Module/Settings/Delegation.php:180
#: src/Module/Settings/Delegation.php:166 #: src/Module/Settings/Delegation.php:191
msgid "Parent User" msgid "Parent User"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:163 #: src/Module/Settings/Delegation.php:188
msgid "Additional Accounts" msgid "Additional Accounts"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:164 #: src/Module/Settings/Delegation.php:189
msgid "" msgid ""
"Register additional accounts that are automatically connected to your " "Register additional accounts that are automatically connected to your "
"existing account so you can manage them from this account." "existing account so you can manage them from this account."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:165 #: src/Module/Settings/Delegation.php:190
msgid "Register an additional account" msgid "Register an additional account"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:169 #: src/Module/Settings/Delegation.php:192
msgid "" msgid ""
"Parent users have total control about this account, including the account " "Parent users have total control about this account, including the account "
"settings. Please double check whom you give this access." "settings. Please double check whom you give this access."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:173 #: src/Module/Settings/Delegation.php:195
msgid "Delegates" msgid "Delegates"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:175 #: src/Module/Settings/Delegation.php:196
msgid "" msgid ""
"Delegates are able to manage all aspects of this account/page except for " "Delegates are able to manage all aspects of this account/page except for "
"basic account settings. Please do not delegate your personal account to " "basic account settings. Please do not delegate your personal account to "
"anybody that you do not trust completely." "anybody that you do not trust completely."
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:176 #: src/Module/Settings/Delegation.php:197
msgid "Existing Page Delegates" msgid "Existing Page Delegates"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:178 #: src/Module/Settings/Delegation.php:198
msgid "Potential Delegates" msgid "Potential Delegates"
msgstr "" msgstr ""
#: src/Module/Settings/Delegation.php:182 #: src/Module/Settings/Delegation.php:199
msgid "No entries." msgid "No entries."
msgstr "" msgstr ""
@ -10695,42 +10678,52 @@ msgstr ""
msgid "select a photo from your photo albums" msgid "select a photo from your photo albums"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:94 #: src/Module/Settings/RemoveMe.php:76
msgid ""
"There was a validation error, please make sure you're logged in with the "
"account you want to remove and try again."
msgstr ""
#: src/Module/Settings/RemoveMe.php:76
msgid "If this error persists, please contact your administrator."
msgstr ""
#: src/Module/Settings/RemoveMe.php:90
#: src/Navigation/Notifications/Repository/Notify.php:471 #: src/Navigation/Notifications/Repository/Notify.php:471
#: src/Navigation/Notifications/Repository/Notify.php:492 #: src/Navigation/Notifications/Repository/Notify.php:492
msgid "[Friendica System Notify]" msgid "[Friendica System Notify]"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:94 #: src/Module/Settings/RemoveMe.php:90
msgid "User deleted their account" msgid "User deleted their account"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:95 #: src/Module/Settings/RemoveMe.php:91
msgid "" msgid ""
"On your Friendica node an user deleted their account. Please ensure that " "On your Friendica node an user deleted their account. Please ensure that "
"their data is removed from the backups." "their data is removed from the backups."
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:96 #: src/Module/Settings/RemoveMe.php:92
#, php-format #, php-format
msgid "The user id is %d" msgid "The user id is %d"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:108 #: src/Module/Settings/RemoveMe.php:105
msgid "Your user account has been successfully removed. Bye bye!" msgid "Your account has been successfully removed. Bye bye!"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:128 #: src/Module/Settings/RemoveMe.php:130
msgid "Remove My Account" msgid "Remove My Account"
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:129 #: src/Module/Settings/RemoveMe.php:131
msgid "" msgid ""
"This will completely remove your account. Once this has been done it is not " "This will completely remove your account. Once this has been done it is not "
"recoverable." "recoverable."
msgstr "" msgstr ""
#: src/Module/Settings/RemoveMe.php:131 #: src/Module/Settings/RemoveMe.php:136
msgid "Please enter your password for verification:" msgid "Please enter your password for verification:"
msgstr "" msgstr ""
@ -11047,8 +11040,8 @@ msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:149 #: src/Module/Settings/TwoFactor/Verify.php:149
#, php-format #, php-format
msgid "" msgid ""
"<p>Or you can open the following URL in your mobile device:</p><p><a href=" "<p>Or you can open the following URL in your mobile device:</p><p><a "
"\"%s\">%s</a></p>" "href=\"%s\">%s</a></p>"
msgstr "" msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:156 #: src/Module/Settings/TwoFactor/Verify.php:156
@ -11157,9 +11150,9 @@ msgstr ""
msgid "" msgid ""
"At any point in time a logged in user can export their account data from the " "At any point in time a logged in user can export their account data from the "
"<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants " "<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants "
"to delete their account they can do so at <a href=\"%1$s/settings/removeme\">" "to delete their account they can do so at <a href=\"%1$s/settings/"
"%1$s/settings/removeme</a>. The deletion of the account will be permanent. " "removeme\">%1$s/settings/removeme</a>. The deletion of the account will be "
"Deletion of the data will also be requested from the nodes of the " "permanent. Deletion of the data will also be requested from the nodes of the "
"communication partners." "communication partners."
msgstr "" msgstr ""
@ -11179,6 +11172,29 @@ msgstr ""
msgid "The requested item doesn't exist or has been deleted." msgid "The requested item doesn't exist or has been deleted."
msgstr "" msgstr ""
#: src/Module/User/Delegation.php:146
#, php-format
msgid "You are now logged in as %s"
msgstr ""
#: src/Module/User/Delegation.php:185
msgid "Switch between your accounts"
msgstr ""
#: src/Module/User/Delegation.php:186
msgid "Manage your accounts"
msgstr ""
#: src/Module/User/Delegation.php:187
msgid ""
"Toggle between different identities or community/group pages which share "
"your account details or which you have been granted \"manage\" permissions"
msgstr ""
#: src/Module/User/Delegation.php:188
msgid "Select an identity to manage: "
msgstr ""
#: src/Module/User/Import.php:103 #: src/Module/User/Import.php:103
msgid "User imports on closed servers can only be done by an administrator." msgid "User imports on closed servers can only be done by an administrator."
msgstr "" msgstr ""

View File

@ -1,11 +1,12 @@
<h1>{{$title}}</h1> <div id="delegation" class="generic-page-wrapper">
<p id="identity-delegation-desc">{{$desc nofilter}}</p> <h2>{{$l10n.title}}</h2>
<p id="identity-delegation-choose">{{$choose}}</p> <p id="identity-delegation-desc">{{$l10n.desc}}</p>
<p id="identity-delegation-choose">{{$l10n.choose}}</p>
<div id="identity-selector-wrapper" role="menu"> <div id="identity-selector-wrapper" role="menu">
<form action="delegation" method="post"> <form action="delegation" method="post">
{{foreach $identities as $identity}} {{foreach $identities as $identity}}
<div class="identity-match-wrapper {{if $identity.selected}}selected-identity{{/if}}" id="identity-match-{{$identity.uid}}"> <div class="identity-match-wrapper {{if $identity.selected}}selected-identity{{/if}}" id="identity-match-{{$identity.uid}}">
<div class="identity-match-photo" id="identity-match-photo-{{$identity.uid}}"> <div class="identity-match-photo" id="identity-match-photo-{{$identity.uid}}">
<button type="submit" name="identity" value="{{$identity.uid}}" title="{{$identity.username}}"> <button type="submit" name="identity" value="{{$identity.uid}}" title="{{$identity.username}}">
@ -28,13 +29,14 @@
</div> </div>
<div class="identity-match-end"></div> <div class="identity-match-end"></div>
</div> </div>
{{/foreach}} {{/foreach}}
<div class="identity-match-break"></div> <div class="identity-match-break"></div>
</form> </form>
</div>
<p>
<a href="settings/delegation" class="btn btn-primary"><i class="fa fa-cog"></i> {{$l10n.settings_label}}</a>
</p>
</div> </div>
<p>
<a href="settings/delegation" class="btn btn-primary"><i class="fa fa-cog"></i> {{$settings_label}}</a>
</p>

View File

@ -1,54 +1,56 @@
<div id="delegation" class="generic-page-wrapper"> <div id="delegation" class="generic-page-wrapper">
<h1>{{$header}}</h1> <h2>{{$l10n.header}}</h2>
{{if !$is_child_user}} {{if !$is_child_user}}
<h2>{{$account_header}}</h2> <h3>{{$l10n.account_header}}</h3>
<div id="add-account-desc" class="add-account-desc"><p>{{$account_desc}}</p></div> <div id="add-account-desc" class="add-account-desc"><p>{{$l10n.account_desc}}</p></div>
<p><a href='register'>{{$add_account}}</a></p> <p><a href="register">{{$l10n.add_account}}</a></p>
{{/if}} {{/if}}
{{if $parent_user}} {{if $parent_user}}
<h2>{{$parent_header}}</h2> <h3>{{$l10n.parent_header}}</h3>
<div id="delegate-parent-desc" class="delegate-parent-desc"><p>{{$parent_desc}}</p></div> <div id="delegate-parent-desc" class="delegate-parent-desc"><p>{{$l10n.parent_desc}}</p></div>
<div id="delegate-parent" class="delegate-parent"> <div id="delegate-parent" class="delegate-parent">
<form action="settings/delegation" method="post"> <form action="settings/delegation" method="post">
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'> <input type="hidden" name='form_security_token' value="{{$form_security_token}}">
{{include file="field_select.tpl" field=$parent_user}} {{include file="field_select.tpl" field=$parent_user}}
{{include file="field_password.tpl" field=$parent_password}} {{include file="field_password.tpl" field=$parent_password}}
<div class="submit"><input type="submit" name="delegate" value="{{$submit}}"/></div> <div class="submit">
</form> <button type="submit" name="delegate" value="{{$l10n.submit}}">{{$l10n.submit}}</button>
</div> </div>
</form>
</div>
{{/if}} {{/if}}
<h2>{{$delegates_header}}</h2> <h3>{{$l10n.delegates_header}}</h3>
<div id="delegate-desc" class="delegate-desc"><p>{{$desc nofilter}}</p></div> <div id="delegate-desc" class="delegate-desc"><p>{{$l10n.desc}}</p></div>
<h3>{{$head_delegates}}</h3> <h4>{{$l10n.head_delegates}}</h4>
{{if $delegates}} {{if $delegates}}
{{foreach $delegates as $x}} {{foreach $delegates as $delegate}}
<div class="contact-block-div"> <div class="contact-block-div">
<a class="contact-block-link" href="settings/delegation/remove/{{$x.uid}}"> <a class="contact-block-link" href="settings/delegation/remove/{{$delegate.uid}}">
<img class="contact-block-img" src="photo/thumb/{{$x.uid}}" title="{{$x.username}} ({{$x.nickname}})"> <img class="contact-block-img" src="photo/thumb/{{$delegate.uid}}" title="{{$delegate.username}} ({{$delegate.nickname}})">
</a> </a>
</div> </div>
{{/foreach}} {{/foreach}}
<div class="clear"></div> <div class="clear"></div>
{{else}} {{else}}
<p>{{$none}}</p> <p>{{$l10n.none}}</p>
{{/if}} {{/if}}
<h3>{{$head_potentials}}</h3> <h4>{{$l10n.head_potentials}}</h4>
{{if $potentials}} {{if $potentials}}
{{foreach $potentials as $x}} {{foreach $potentials as $potential}}
<div class="contact-block-div"> <div class="contact-block-div">
<a class="contact-block-link" href="settings/delegation/add/{{$x.uid}}"> <a class="contact-block-link" href="settings/delegation/add/{{$potential.uid}}">
<img class="contact-block-img" src="photo/thumb/{{$x.uid}}" title="{{$x.username}} ({{$x.nickname}})"> <img class="contact-block-img" src="photo/thumb/{{$potential.uid}}" title="{{$potential.username}} ({{$potential.nickname}})">
</a> </a>
</div> </div>
{{/foreach}} {{/foreach}}
<div class="clear"></div> <div class="clear"></div>
{{else}} {{else}}
<p>{{$none}}</p> <p>{{$l10n.none}}</p>
{{/if}} {{/if}}
</div> </div>

View File

@ -4,6 +4,8 @@
<div id="remove-account-wrapper"> <div id="remove-account-wrapper">
<div id="remove-account-desc">{{$l10n.desc nofilter}}</div> <div id="remove-account-desc">{{$l10n.desc nofilter}}</div>
{{$hovercard nofilter}}
<form action="settings/removeme" autocomplete="off" method="post"> <form action="settings/removeme" autocomplete="off" method="post">
{{include file="field_password.tpl" field=$password}} {{include file="field_password.tpl" field=$password}}