Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2021-10-14 11:19:40 +0300
committerChristopher Ng <chrng8@gmail.com>2021-10-19 07:59:35 +0300
commit309354852f12ae88d5eef05d311d6ebcba8ee762 (patch)
tree640c4e2394ba2a868d8d1cb6b5271fd1271bbdab /core
parent7215148a242815a5064ce5d00a387c634dc936f3 (diff)
Profile backend
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'core')
-rw-r--r--core/Controller/ProfileApiController.php98
-rw-r--r--core/Controller/ProfilePageController.php131
-rw-r--r--core/Db/ProfileConfig.php172
-rw-r--r--core/Db/ProfileConfigMapper.php48
-rw-r--r--core/Migrations/Version23000Date20210930122352.php69
-rw-r--r--core/img/actions/phone.svg1
-rw-r--r--core/img/actions/profile.svg1
-rw-r--r--core/img/actions/timezone.svg4
-rw-r--r--core/img/actions/twitter.svg1
-rw-r--r--core/routes.php4
10 files changed, 526 insertions, 3 deletions
diff --git a/core/Controller/ProfileApiController.php b/core/Controller/ProfileApiController.php
new file mode 100644
index 00000000000..d9e20701eaa
--- /dev/null
+++ b/core/Controller/ProfileApiController.php
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Controller;
+
+use OC\Core\Db\ProfileConfigMapper;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSBadRequestException;
+use OCP\AppFramework\OCS\OCSForbiddenException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\AppFramework\OCSController;
+use OCP\IRequest;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OC\Profile\ProfileManager;
+
+class ProfileApiController extends OCSController {
+
+ /** @var ProfileConfigMapper */
+ private $configMapper;
+
+ /** @var ProfileManager */
+ private $profileManager;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IUserSession */
+ private $userSession;
+
+ public function __construct(
+ IRequest $request,
+ ProfileConfigMapper $configMapper,
+ ProfileManager $profileManager,
+ IUserManager $userManager,
+ IUserSession $userSession
+ ) {
+ parent::__construct('core', $request);
+ $this->configMapper = $configMapper;
+ $this->profileManager = $profileManager;
+ $this->userManager = $userManager;
+ $this->userSession = $userSession;
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoSubAdminRequired
+ * @PasswordConfirmationRequired
+ */
+ public function setVisibility(string $targetUserId, string $paramId, string $visibility): DataResponse {
+ $requestingUser = $this->userSession->getUser();
+ $targetUser = $this->userManager->get($targetUserId);
+
+ if (!$this->userManager->userExists($targetUserId)) {
+ throw new OCSNotFoundException('User does not exist');
+ }
+
+ if ($requestingUser !== $targetUser) {
+ throw new OCSForbiddenException('Users can only edit their own visibility settings');
+ }
+
+ // Ensure that a profile config is created in the database
+ $this->profileManager->getProfileConfig($targetUser, $targetUser);
+ $config = $this->configMapper->get($targetUserId);
+
+ if (!in_array($paramId, array_keys($config->getVisibilityMap()), true)) {
+ throw new OCSBadRequestException('User does not have a profile parameter with ID: ' . $paramId);
+ }
+
+ $config->setVisibility($paramId, $visibility);
+ $this->configMapper->update($config);
+
+ return new DataResponse();
+ }
+}
diff --git a/core/Controller/ProfilePageController.php b/core/Controller/ProfilePageController.php
new file mode 100644
index 00000000000..a7ceb404fbc
--- /dev/null
+++ b/core/Controller/ProfilePageController.php
@@ -0,0 +1,131 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Controller;
+
+use OCP\Accounts\IAccountManager;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\IRequest;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OC\Profile\ProfileManager;
+use OCP\UserStatus\IManager as IUserStatusManager;
+
+class ProfilePageController extends Controller {
+ use \OC\Profile\TProfileHelper;
+
+ /** @var IInitialState */
+ private $initialStateService;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var ProfileManager */
+ private $profileManager;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IUserSession */
+ private $userSession;
+
+ /** @var IUserStatusManager */
+ private $userStatusManager;
+
+ public function __construct(
+ $appName,
+ IRequest $request,
+ IInitialState $initialStateService,
+ IAccountManager $accountManager,
+ ProfileManager $profileManager,
+ IUserManager $userManager,
+ IUserSession $userSession,
+ IUserStatusManager $userStatusManager
+ ) {
+ parent::__construct($appName, $request);
+ $this->initialStateService = $initialStateService;
+ $this->accountManager = $accountManager;
+ $this->profileManager = $profileManager;
+ $this->userManager = $userManager;
+ $this->userSession = $userSession;
+ $this->userStatusManager = $userStatusManager;
+ }
+
+ /**
+ * @PublicPage
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ * @NoSubAdminRequired
+ */
+ public function index(string $targetUserId): TemplateResponse {
+ if (!$this->userManager->userExists($targetUserId)) {
+ return new TemplateResponse(
+ 'core',
+ '404-profile',
+ [],
+ TemplateResponse::RENDER_AS_GUEST,
+ );
+ }
+
+ $visitingUser = $this->userSession->getUser();
+ $targetUser = $this->userManager->get($targetUserId);
+ $targetAccount = $this->accountManager->getAccount($targetUser);
+
+ if (!$this->isProfileEnabled($targetAccount)) {
+ return new TemplateResponse(
+ 'core',
+ '404-profile',
+ [],
+ TemplateResponse::RENDER_AS_GUEST,
+ );
+ }
+
+ $userStatuses = $this->userStatusManager->getUserStatuses([$targetUserId]);
+ $status = array_shift($userStatuses);
+ if (!empty($status)) {
+ $this->initialStateService->provideInitialState('status', [
+ 'icon' => $status->getIcon(),
+ 'message' => $status->getMessage(),
+ ]);
+ }
+
+ $this->initialStateService->provideInitialState(
+ 'profileParameters',
+ $this->profileManager->getProfileParams($targetUser, $visitingUser),
+ );
+
+ \OCP\Util::addScript('core', 'dist/profile');
+
+ return new TemplateResponse(
+ 'core',
+ 'profile',
+ [],
+ $this->userSession->isLoggedIn() ? TemplateResponse::RENDER_AS_USER : TemplateResponse::RENDER_AS_PUBLIC,
+ );
+ }
+}
diff --git a/core/Db/ProfileConfig.php b/core/Db/ProfileConfig.php
new file mode 100644
index 00000000000..eb50da37a64
--- /dev/null
+++ b/core/Db/ProfileConfig.php
@@ -0,0 +1,172 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Db;
+
+use function Safe\json_decode;
+use function Safe\json_encode;
+use \JsonSerializable;
+use OCP\Accounts\IAccountManager;
+use OCP\AppFramework\Db\Entity;
+use OCP\Profile\ParameterDoesNotExistException;
+
+/**
+ * @method string getUserId()
+ * @method void setUserId(string $userId)
+ * @method string getConfig()
+ * @method void setConfig(string $config)
+ */
+class ProfileConfig extends Entity implements JsonSerializable {
+
+ /**
+ * Visible to users, guests, and public access
+ *
+ * @since 23.0.0
+ */
+ public const VISIBILITY_SHOW = 'show';
+
+ /**
+ * Visible to users and guests
+ *
+ * @since 23.0.0
+ */
+ public const VISIBILITY_SHOW_USERS_ONLY = 'show_users_only';
+
+ /**
+ * Visible to nobody
+ *
+ * @since 23.0.0
+ */
+ public const VISIBILITY_HIDE = 'hide';
+
+ /**
+ * Default account property visibility
+ *
+ * @since 23.0.0
+ */
+ public const DEFAULT_PROPERTY_VISIBILITY = [
+ IAccountManager::PROPERTY_ADDRESS => self::VISIBILITY_SHOW_USERS_ONLY,
+ IAccountManager::PROPERTY_AVATAR => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_BIOGRAPHY => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_DISPLAYNAME => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_HEADLINE => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_ORGANISATION => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_ROLE => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY,
+ IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY,
+ IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW,
+ IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW,
+ ];
+
+ /**
+ * Default visibility
+ *
+ * @since 23.0.0
+ */
+ public const DEFAULT_VISIBILITY = self::VISIBILITY_SHOW_USERS_ONLY;
+
+ /** @var string */
+ protected $userId;
+
+ /** @var string */
+ protected $config;
+
+ public function __construct() {
+ $this->addType('userId', 'string');
+ $this->addType('config', 'string');
+ }
+
+ /**
+ * Returns the config in an associative array
+ */
+ public function getConfigArray(): array {
+ return json_decode($this->config, true);
+ }
+
+ /**
+ * Set the config
+ */
+ public function setConfigArray(array $config): void {
+ $this->setConfig(json_encode($config));
+ }
+
+ /**
+ * Returns the visibility map in an associative array
+ */
+ public function getVisibilityMap(): array {
+ $config = $this->getConfigArray();
+ $visibilityMap = [];
+ foreach ($config as $paramId => $paramConfig) {
+ $visibilityMap[$paramId] = $paramConfig['visibility'];
+ }
+
+ return $visibilityMap;
+ }
+
+ /**
+ * Set the visibility map
+ */
+ public function setVisibilityMap(array $visibilityMap): void {
+ $config = $this->getConfigArray();
+ foreach ($visibilityMap as $paramId => $visibility) {
+ $config[$paramId] = array_merge(
+ $config[$paramId] ?: [],
+ ['visibility' => $visibility],
+ );
+ }
+
+ $this->setConfigArray($config);
+ }
+
+ /**
+ * Returns the visibility of the parameter
+ *
+ * @throws ParameterDoesNotExistException
+ */
+ public function getVisibility(string $paramId): string {
+ $visibilityMap = $this->getVisibilityMap();
+ if (isset($visibilityMap[$paramId])) {
+ return $visibilityMap[$paramId];
+ }
+ throw new ParameterDoesNotExistException($paramId);
+ }
+
+ /**
+ * Set the visibility of the parameter
+ */
+ public function setVisibility(string $paramId, string $visibility): void {
+ $visibilityMap = $this->getVisibilityMap();
+ $visibilityMap[$paramId] = $visibility;
+ $this->setVisibilityMap($visibilityMap);
+ }
+
+ public function jsonSerialize(): array {
+ return [
+ 'userId' => $this->userId,
+ 'config' => $this->getConfigArray(),
+ ];
+ }
+}
diff --git a/core/Db/ProfileConfigMapper.php b/core/Db/ProfileConfigMapper.php
new file mode 100644
index 00000000000..a8b1e35f747
--- /dev/null
+++ b/core/Db/ProfileConfigMapper.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Db;
+
+use OCP\AppFramework\Db\QBMapper;
+use OCP\IDBConnection;
+
+class ProfileConfigMapper extends QBMapper {
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'profile_config', ProfileConfig::class);
+ }
+
+ public function get(string $userId): ProfileConfig {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
+ return $this->findEntity($qb);
+ }
+
+ public function getArray(string $userId): array {
+ return $this->get($userId)->getConfigArray();
+ }
+}
diff --git a/core/Migrations/Version23000Date20210930122352.php b/core/Migrations/Version23000Date20210930122352.php
new file mode 100644
index 00000000000..e3eb9af7eba
--- /dev/null
+++ b/core/Migrations/Version23000Date20210930122352.php
@@ -0,0 +1,69 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Migrations;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version23000Date20210930122352 extends SimpleMigrationStep {
+ private const TABLE_NAME = 'profile_config';
+
+ /**
+ * @param IOutput $output
+ * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $hasTable = $schema->hasTable(self::TABLE_NAME);
+ if (!$hasTable) {
+ $table = $schema->createTable(self::TABLE_NAME);
+ $table->addColumn('id', Types::INTEGER, [
+ 'autoincrement' => true,
+ 'notnull' => true,
+ ]);
+ $table->addColumn('user_id', Types::STRING, [
+ 'notnull' => true,
+ 'length' => 64,
+ ]);
+ $table->addColumn('config', Types::TEXT, [
+ 'notnull' => true,
+ ]);
+ $table->setPrimaryKey(['id']);
+ $table->addUniqueIndex(['user_id'], 'user_id');
+ return $schema;
+ }
+
+ return null;
+ }
+}
diff --git a/core/img/actions/phone.svg b/core/img/actions/phone.svg
new file mode 100644
index 00000000000..79bb9100b13
--- /dev/null
+++ b/core/img/actions/phone.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.41333 7.19333C5.37333 9.08 6.92 10.62 8.80667 11.5867L10.2733 10.12C10.4533 9.94 10.72 9.88 10.9533 9.96C11.7 10.2067 12.5067 10.34 13.3333 10.34C13.7 10.34 14 10.64 14 11.0067V13.3333C14 13.7 13.7 14 13.3333 14C7.07333 14 2 8.92667 2 2.66667C2 2.3 2.3 2 2.66667 2H5C5.36667 2 5.66667 2.3 5.66667 2.66667C5.66667 3.5 5.8 4.3 6.04667 5.04667C6.12 5.28 6.06667 5.54 5.88 5.72667L4.41333 7.19333Z" fill="black"/></svg>
diff --git a/core/img/actions/profile.svg b/core/img/actions/profile.svg
new file mode 100644
index 00000000000..90b95f619aa
--- /dev/null
+++ b/core/img/actions/profile.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 1C8.92826 1 9.8185 1.36875 10.4749 2.02513C11.1313 2.6815 11.5 3.57174 11.5 4.5C11.5 5.42826 11.1313 6.3185 10.4749 6.97487C9.8185 7.63125 8.92826 8 8 8C7.07174 8 6.1815 7.63125 5.52513 6.97487C4.86875 6.3185 4.5 5.42826 4.5 4.5C4.5 3.57174 4.86875 2.6815 5.52513 2.02513C6.1815 1.36875 7.07174 1 8 1V1ZM8 9.75C11.8675 9.75 15 11.3162 15 13.25V15H1V13.25C1 11.3162 4.1325 9.75 8 9.75Z" fill="black"/></svg>
diff --git a/core/img/actions/timezone.svg b/core/img/actions/timezone.svg
index f12c3665749..1da05c67df1 100644
--- a/core/img/actions/timezone.svg
+++ b/core/img/actions/timezone.svg
@@ -1,3 +1 @@
-<svg enable-background="new 0 0 15 15" version="1.1" viewBox="0 0 15 15" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
- <path d="m14.982 7c-0.246-3.744-3.238-6.737-6.982-6.983v-0.017h-1v0.017c-3.744 0.246-6.737 3.239-6.983 6.983h-0.017v1h0.017c0.246 3.744 3.239 6.736 6.983 6.982v0.018h1v-0.018c3.744-0.246 6.736-3.238 6.982-6.982h0.018v-1h-0.018zm-10.287-5.365c-0.483 0.642-0.884 1.447-1.176 2.365h-1.498c0.652-1.017 1.578-1.84 2.674-2.365zm-3.197 3.365h1.758c-0.134 0.632-0.219 1.303-0.246 2h-1.991c0.053-0.704 0.219-1.377 0.479-2zm-0.479 3h1.991c0.027 0.697 0.112 1.368 0.246 2h-1.758c-0.26-0.623-0.426-1.296-0.479-2zm1.002 3h1.497c0.292 0.918 0.693 1.723 1.177 2.365-1.096-0.525-2.022-1.347-2.674-2.365zm4.979 2.936c-1.028-0.275-1.913-1.379-2.45-2.936h2.45v2.936zm0-3.936h-2.731c-0.141-0.623-0.23-1.296-0.259-2h2.99v2zm0-3h-2.99c0.029-0.704 0.118-1.377 0.259-2h2.731v2zm0-3h-2.45c0.537-1.557 1.422-2.661 2.45-2.935v2.935zm5.979 0h-1.496c-0.293-0.918-0.693-1.723-1.178-2.365 1.095 0.525 2.022 1.348 2.674 2.365zm-4.979-2.935c1.027 0.274 1.913 1.378 2.45 2.935h-2.45v-2.935zm0 3.935h2.73c0.142 0.623 0.229 1.296 0.26 2h-2.99v-2zm0 3h2.99c-0.029 0.704-0.118 1.377-0.26 2h-2.73v-2zm0 5.936v-2.936h2.45c-0.537 1.557-1.423 2.661-2.45 2.936zm2.305-0.571c0.483-0.643 0.885-1.447 1.178-2.365h1.496c-0.652 1.018-1.579 1.84-2.674 2.365zm3.197-3.365h-1.758c0.134-0.632 0.219-1.303 0.246-2h1.99c-0.052 0.704-0.218 1.377-0.478 2zm-1.512-3c-0.027-0.697-0.112-1.368-0.246-2h1.758c0.26 0.623 0.426 1.296 0.479 2h-1.991z"/>
-</svg>
+<svg enable-background="new 0 0 15 15" version="1.1" viewBox="0 0 15 15" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="m14.982 7c-0.246-3.744-3.238-6.737-6.982-6.983v-0.017h-1v0.017c-3.744 0.246-6.737 3.239-6.983 6.983h-0.017v1h0.017c0.246 3.744 3.239 6.736 6.983 6.982v0.018h1v-0.018c3.744-0.246 6.736-3.238 6.982-6.982h0.018v-1h-0.018zm-10.287-5.365c-0.483 0.642-0.884 1.447-1.176 2.365h-1.498c0.652-1.017 1.578-1.84 2.674-2.365zm-3.197 3.365h1.758c-0.134 0.632-0.219 1.303-0.246 2h-1.991c0.053-0.704 0.219-1.377 0.479-2zm-0.479 3h1.991c0.027 0.697 0.112 1.368 0.246 2h-1.758c-0.26-0.623-0.426-1.296-0.479-2zm1.002 3h1.497c0.292 0.918 0.693 1.723 1.177 2.365-1.096-0.525-2.022-1.347-2.674-2.365zm4.979 2.936c-1.028-0.275-1.913-1.379-2.45-2.936h2.45v2.936zm0-3.936h-2.731c-0.141-0.623-0.23-1.296-0.259-2h2.99v2zm0-3h-2.99c0.029-0.704 0.118-1.377 0.259-2h2.731v2zm0-3h-2.45c0.537-1.557 1.422-2.661 2.45-2.935v2.935zm5.979 0h-1.496c-0.293-0.918-0.693-1.723-1.178-2.365 1.095 0.525 2.022 1.348 2.674 2.365zm-4.979-2.935c1.027 0.274 1.913 1.378 2.45 2.935h-2.45v-2.935zm0 3.935h2.73c0.142 0.623 0.229 1.296 0.26 2h-2.99v-2zm0 3h2.99c-0.029 0.704-0.118 1.377-0.26 2h-2.73v-2zm0 5.936v-2.936h2.45c-0.537 1.557-1.423 2.661-2.45 2.936zm2.305-0.571c0.483-0.643 0.885-1.447 1.178-2.365h1.496c-0.652 1.018-1.579 1.84-2.674 2.365zm3.197-3.365h-1.758c0.134-0.632 0.219-1.303 0.246-2h1.99c-0.052 0.704-0.218 1.377-0.478 2zm-1.512-3c-0.027-0.697-0.112-1.368-0.246-2h1.758c0.26 0.623 0.426 1.296 0.479 2h-1.991z"/></svg>
diff --git a/core/img/actions/twitter.svg b/core/img/actions/twitter.svg
new file mode 100644
index 00000000000..c21a67b32a5
--- /dev/null
+++ b/core/img/actions/twitter.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14.3194 5.30903C14.329 5.44903 14.329 5.58903 14.329 5.73032C14.329 10.0355 11.0516 15.0006 5.05871 15.0006V14.9981C3.28839 15.0006 1.55484 14.4935 0.0645161 13.5374C0.321935 13.5684 0.580645 13.5839 0.84 13.5845C2.3071 13.5858 3.73226 13.0935 4.88645 12.1871C3.49226 12.1606 2.26968 11.2516 1.84258 9.92452C2.33097 10.0187 2.83419 9.99935 3.31355 9.86839C1.79355 9.56129 0.7 8.22581 0.7 6.67484C0.7 6.66064 0.7 6.6471 0.7 6.63355C1.1529 6.88581 1.66 7.02581 2.17871 7.04129C0.747097 6.08451 0.305806 4.18 1.17032 2.69097C2.82452 4.72645 5.26516 5.96387 7.88516 6.09484C7.62258 4.96322 7.98129 3.77742 8.82774 2.98193C10.14 1.74839 12.2039 1.81161 13.4374 3.12322C14.1671 2.97935 14.8665 2.71161 15.5065 2.33226C15.2632 3.08645 14.7542 3.7271 14.0742 4.13419C14.72 4.05806 15.351 3.88516 15.9452 3.62129C15.5077 4.27677 14.9568 4.84774 14.3194 5.30903Z" fill="black"/></svg>
diff --git a/core/routes.php b/core/routes.php
index 0625690b2d2..59988404cd4 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -33,6 +33,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
use OC\Core\Application;
/** @var Application $application */
@@ -42,6 +43,7 @@ $application->registerRoutes($this, [
['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
+ ['name' => 'ProfilePage#index', 'url' => '/u/{targetUserId}', 'verb' => 'GET'],
['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
@@ -117,6 +119,8 @@ $application->registerRoutes($this, [
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
+ ['root' => '/profile', 'name' => 'ProfileApi#setVisibility', 'url' => '/{targetUserId}', 'verb' => 'PUT'],
+
// Unified search
['root' => '/search', 'name' => 'UnifiedSearch#getProviders', 'url' => '/providers', 'verb' => 'GET'],
['root' => '/search', 'name' => 'UnifiedSearch#search', 'url' => '/providers/{providerId}/search', 'verb' => 'GET'],