You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
8.4 KiB

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2018, Joas Schilling <coding@schilljs.com>
  5. *
  6. * @author Joas Schilling <coding@schilljs.com>
  7. * @author Kate Döen <kate.doeen@nextcloud.com>
  8. *
  9. * @license GNU AGPL version 3 or any later version
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace OCA\Talk;
  26. use OCA\Talk\Chat\ChatManager;
  27. use OCP\App\IAppManager;
  28. use OCP\AppFramework\Services\IAppConfig;
  29. use OCP\Capabilities\IPublicCapability;
  30. use OCP\Comments\ICommentsManager;
  31. use OCP\ICache;
  32. use OCP\ICacheFactory;
  33. use OCP\IConfig;
  34. use OCP\IUser;
  35. use OCP\IUserSession;
  36. use OCP\Translation\ITranslationManager;
  37. use OCP\Util;
  38. /**
  39. * @psalm-import-type TalkCapabilities from ResponseDefinitions
  40. */
  41. class Capabilities implements IPublicCapability {
  42. protected ICache $talkCache;
  43. public function __construct(
  44. protected IConfig $serverConfig,
  45. protected Config $talkConfig,
  46. protected IAppConfig $appConfig,
  47. protected ICommentsManager $commentsManager,
  48. protected IUserSession $userSession,
  49. protected IAppManager $appManager,
  50. protected ITranslationManager $translationManager,
  51. ICacheFactory $cacheFactory,
  52. ) {
  53. $this->talkCache = $cacheFactory->createLocal('talk::');
  54. }
  55. /**
  56. * @return array{
  57. * spreed: TalkCapabilities,
  58. * }|array<empty>
  59. */
  60. public function getCapabilities(): array {
  61. $user = $this->userSession->getUser();
  62. if ($user instanceof IUser && $this->talkConfig->isDisabledForUser($user)) {
  63. return [];
  64. }
  65. $capabilities = [
  66. 'features' => [
  67. 'audio',
  68. 'video',
  69. 'chat-v2',
  70. 'conversation-v4',
  71. 'guest-signaling',
  72. 'empty-group-room',
  73. 'guest-display-names',
  74. 'multi-room-users',
  75. 'favorites',
  76. 'last-room-activity',
  77. 'no-ping',
  78. 'system-messages',
  79. 'delete-messages',
  80. 'mention-flag',
  81. 'in-call-flags',
  82. 'conversation-call-flags',
  83. 'notification-levels',
  84. 'invite-groups-and-mails',
  85. 'locked-one-to-one-rooms',
  86. 'read-only-rooms',
  87. 'listable-rooms',
  88. 'chat-read-marker',
  89. 'chat-unread',
  90. 'webinary-lobby',
  91. 'start-call-flag',
  92. 'chat-replies',
  93. 'circles-support',
  94. 'force-mute',
  95. 'sip-support',
  96. 'sip-support-nopin',
  97. 'chat-read-status',
  98. 'phonebook-search',
  99. 'raise-hand',
  100. 'room-description',
  101. 'rich-object-sharing',
  102. 'temp-user-avatar-api',
  103. 'geo-location-sharing',
  104. 'voice-message-sharing',
  105. 'signaling-v3',
  106. 'publishing-permissions',
  107. 'clear-history',
  108. 'direct-mention-flag',
  109. 'notification-calls',
  110. 'conversation-permissions',
  111. 'rich-object-list-media',
  112. 'rich-object-delete',
  113. 'unified-search',
  114. 'chat-permission',
  115. 'silent-send',
  116. 'silent-call',
  117. 'send-call-notification',
  118. 'talk-polls',
  119. 'breakout-rooms-v1',
  120. 'recording-v1',
  121. 'avatar',
  122. 'chat-get-context',
  123. 'single-conversation-status',
  124. 'chat-keep-notifications',
  125. 'typing-privacy',
  126. 'remind-me-later',
  127. 'bots-v1',
  128. 'markdown-messages',
  129. 'media-caption',
  130. 'session-state',
  131. 'note-to-self',
  132. 'recording-consent',
  133. 'sip-support-dialout',
  134. 'delete-messages-unlimited',
  135. 'edit-messages',
  136. 'silent-send-state',
  137. 'chat-read-last',
  138. 'federation-v1',
  139. ],
  140. 'config' => [
  141. 'attachments' => [
  142. 'allowed' => $user instanceof IUser,
  143. ],
  144. 'call' => [
  145. 'enabled' => ((int) $this->serverConfig->getAppValue('spreed', 'start_calls', (string) Room::START_CALL_EVERYONE)) !== Room::START_CALL_NOONE,
  146. 'breakout-rooms' => $this->talkConfig->isBreakoutRoomsEnabled(),
  147. 'recording' => $this->talkConfig->isRecordingEnabled(),
  148. 'recording-consent' => $this->talkConfig->recordingConsentRequired(),
  149. 'supported-reactions' => ['❤️', '🎉', '👏', '👍', '👎', '😂', '🤩', '🤔', '😲', '😥'],
  150. 'sip-enabled' => $this->talkConfig->isSIPConfigured(),
  151. 'sip-dialout-enabled' => $this->talkConfig->isSIPDialOutEnabled(),
  152. ],
  153. 'chat' => [
  154. 'max-length' => ChatManager::MAX_CHAT_LENGTH,
  155. 'read-privacy' => Participant::PRIVACY_PUBLIC,
  156. 'has-translation-providers' => $this->translationManager->hasProviders(),
  157. 'typing-privacy' => Participant::PRIVACY_PUBLIC,
  158. ],
  159. 'conversations' => [
  160. 'can-create' => $user instanceof IUser && !$this->talkConfig->isNotAllowedToCreateConversations($user)
  161. ],
  162. 'federation' => [
  163. 'enabled' => false,
  164. 'incoming-enabled' => false,
  165. 'outgoing-enabled' => false,
  166. 'only-trusted-servers' => true,
  167. ],
  168. 'previews' => [
  169. 'max-gif-size' => (int)$this->serverConfig->getAppValue('spreed', 'max-gif-size', '3145728'),
  170. ],
  171. 'signaling' => [
  172. 'session-ping-limit' => max(0, (int)$this->serverConfig->getAppValue('spreed', 'session-ping-limit', '200')),
  173. ],
  174. ],
  175. 'version' => $this->appManager->getAppVersion('spreed'),
  176. ];
  177. if ($this->serverConfig->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron') {
  178. $capabilities['features'][] = 'message-expiration';
  179. }
  180. if ($this->commentsManager->supportReactions()) {
  181. $capabilities['features'][] = 'reactions';
  182. }
  183. if ($user instanceof IUser) {
  184. if ($this->talkConfig->isFederationEnabled() && $this->talkConfig->isFederationEnabledForUserId($user)) {
  185. $capabilities['config']['federation'] = [
  186. 'enabled' => true,
  187. 'incoming-enabled' => $this->appConfig->getAppValueBool('federation_incoming_enabled', true),
  188. 'outgoing-enabled' => $this->appConfig->getAppValueBool('federation_outgoing_enabled', true),
  189. 'only-trusted-servers' => $this->appConfig->getAppValueBool('federation_only_trusted_servers'),
  190. ];
  191. }
  192. $capabilities['config']['attachments']['folder'] = $this->talkConfig->getAttachmentFolder($user->getUID());
  193. $capabilities['config']['chat']['read-privacy'] = $this->talkConfig->getUserReadPrivacy($user->getUID());
  194. $capabilities['config']['chat']['typing-privacy'] = $this->talkConfig->getUserTypingPrivacy($user->getUID());
  195. }
  196. $pubKey = $this->talkConfig->getSignalingTokenPublicKey();
  197. if ($pubKey) {
  198. $capabilities['config']['signaling']['hello-v2-token-key'] = $pubKey;
  199. }
  200. if ($this->serverConfig->getAppValue('spreed', 'has_reference_id', 'no') === 'yes') {
  201. $capabilities['features'][] = 'chat-reference-id';
  202. }
  203. /** @var ?string[] $predefinedBackgrounds */
  204. $predefinedBackgrounds = null;
  205. $cachedPredefinedBackgrounds = $this->talkCache->get('predefined_backgrounds');
  206. if ($cachedPredefinedBackgrounds !== null) {
  207. // Try using cached value
  208. /** @var string[]|null $predefinedBackgrounds */
  209. $predefinedBackgrounds = json_decode($cachedPredefinedBackgrounds, true);
  210. }
  211. if (!is_array($predefinedBackgrounds)) {
  212. // Cache was empty or invalid, regenerate
  213. /** @var string[] $predefinedBackgrounds */
  214. $predefinedBackgrounds = [];
  215. if (file_exists(__DIR__ . '/../img/backgrounds')) {
  216. $directoryIterator = new \DirectoryIterator(__DIR__ . '/../img/backgrounds');
  217. foreach ($directoryIterator as $file) {
  218. if (!$file->isFile()) {
  219. continue;
  220. }
  221. if ($file->isDot()) {
  222. continue;
  223. }
  224. if ($file->getFilename() === 'COPYING') {
  225. continue;
  226. }
  227. $predefinedBackgrounds[] = $file->getFilename();
  228. }
  229. sort($predefinedBackgrounds);
  230. }
  231. $this->talkCache->set('predefined_backgrounds', json_encode($predefinedBackgrounds), 300);
  232. }
  233. $capabilities['config']['call']['predefined-backgrounds'] = $predefinedBackgrounds;
  234. if ($user instanceof IUser) {
  235. $quota = $user->getQuota();
  236. if ($quota !== 'none') {
  237. $quota = Util::computerFileSize($quota);
  238. }
  239. $capabilities['config']['call']['can-upload-background'] = $quota === 'none' || $quota > 0;
  240. $capabilities['config']['call']['can-enable-sip'] = $this->talkConfig->canUserEnableSIP($user);
  241. } else {
  242. $capabilities['config']['call']['can-upload-background'] = false;
  243. $capabilities['config']['call']['can-enable-sip'] = false;
  244. }
  245. return [
  246. 'spreed' => $capabilities,
  247. ];
  248. }
  249. }