UPSTREAM BASELINE: nextcloud/spreed v22.0.12 (без изменений)
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Источник: https://github.com/nextcloud/spreed/archive/refs/tags/v22.0.12.tar.gz С этого коммита ветка официального Nextcloud Talk отрезана (решение владельца 2026-07-06). Все дальнейшие изменения — только наши; версии релизов: 22.0.12-f7.N.
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\AppInfo\Application;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Service\CertificateService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\Notification\IManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class CheckCertificates extends TimedJob {
|
||||
public function __construct(
|
||||
protected CertificateService $certService,
|
||||
protected Config $talkConfig,
|
||||
protected ITimeFactory $timeFactory,
|
||||
protected IGroupManager $groupManager,
|
||||
protected IManager $notificationManager,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Run once a week
|
||||
$this->setInterval(60 * 60 * 24 * 7);
|
||||
$this->setTimeSensitivity(IJob::TIME_INSENSITIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @return string[]
|
||||
*/
|
||||
private function getUsersToNotify(): array {
|
||||
$users = [];
|
||||
|
||||
$groupToNotify = $this->groupManager->get('admin');
|
||||
if ($groupToNotify instanceof IGroup) {
|
||||
foreach ($groupToNotify->getUsers() as $user) {
|
||||
$users[] = $user->getUID();
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a notification and inform admins about the certificate which is about to expire
|
||||
*
|
||||
* @param string $host The host which was checked
|
||||
* @param int $days Number of days until the certificate expires
|
||||
*/
|
||||
private function createNotifications(string $host, int $days): void {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
|
||||
try {
|
||||
$notification->setApp(Application::APP_ID)
|
||||
->setDateTime(new \DateTime())
|
||||
->setObject('certificate_expiration', $host);
|
||||
|
||||
$notification->setSubject('certificate_expiration', [
|
||||
'host' => $host,
|
||||
'days_to_expire' => $days,
|
||||
]);
|
||||
|
||||
foreach ($this->getUsersToNotify() as $uid) {
|
||||
$notification->setUser($uid);
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the certificate of the specified host
|
||||
*
|
||||
* @param string $host The host to check the certificate of without scheme
|
||||
*/
|
||||
private function checkServerCertificate(string $host): void {
|
||||
$expirationInDays = $this->certService->getCertificateExpirationInDays($host);
|
||||
|
||||
if ($expirationInDays == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($expirationInDays < 10) {
|
||||
$this->logger->warning('Certificate of ' . $host . ' expires in less than ' . $expirationInDays . ' days');
|
||||
|
||||
$this->createNotifications($host, $expirationInDays);
|
||||
} else {
|
||||
$this->logger->debug('Certificate of ' . $host . ' is valid for ' . $expirationInDays . ' days');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$turnServers = $this->talkConfig->getTurnServers(false);
|
||||
|
||||
foreach ($turnServers as $turnServer) {
|
||||
// Only check server which support the 'turns' protocol
|
||||
if (!str_contains($turnServer['schemes'], 'turns')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->checkServerCertificate($turnServer['server']);
|
||||
}
|
||||
|
||||
$signalingServers = $this->talkConfig->getSignalingServers();
|
||||
|
||||
foreach ($signalingServers as $signalingServer) {
|
||||
if ((bool)$signalingServer['verify']) {
|
||||
$this->checkServerCertificate($signalingServer['server']);
|
||||
}
|
||||
}
|
||||
|
||||
$recordingServers = $this->talkConfig->getRecordingServers();
|
||||
|
||||
foreach ($recordingServers as $recordingServer) {
|
||||
if ((bool)$recordingServer['verify']) {
|
||||
$this->checkServerCertificate($recordingServer['server']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\DataObjects\AccountId;
|
||||
use OCA\Talk\Exceptions\HostedSignalingServerAPIException;
|
||||
use OCA\Talk\Service\HostedSignalingServerService;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Notification\IManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class CheckHostedSignalingServer extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
private HostedSignalingServerService $hostedSignalingServerService,
|
||||
private IConfig $config,
|
||||
private IManager $notificationManager,
|
||||
private IGroupManager $groupManager,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private LoggerInterface $logger,
|
||||
private Config $talkConfig,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every hour
|
||||
$this->setInterval(3600);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
|
||||
}
|
||||
|
||||
private function formatTurnSchemes(array $schemes): string {
|
||||
if (in_array('turn', $schemes, true) && in_array('turns', $schemes, true)) {
|
||||
return 'turn,turns';
|
||||
} elseif (in_array('turn', $schemes, true)) {
|
||||
return 'turn';
|
||||
} elseif (in_array('turns', $schemes, true)) {
|
||||
return 'turns';
|
||||
} else {
|
||||
return 'turn';
|
||||
}
|
||||
}
|
||||
|
||||
private function formatTurnProtocols(array $protocols): string {
|
||||
if (in_array('udp', $protocols, true) && in_array('tcp', $protocols, true)) {
|
||||
return 'udp,tcp';
|
||||
} elseif (in_array('udp', $protocols, true)) {
|
||||
return 'udp';
|
||||
} elseif (in_array('tcp', $protocols, true)) {
|
||||
return 'tcp';
|
||||
} else {
|
||||
return 'udp';
|
||||
}
|
||||
}
|
||||
|
||||
private function updateStunTurnSettings(array $oldAccountInfo, array $accountInfo) {
|
||||
if (!empty($accountInfo['stun']['servers'])) {
|
||||
if ($this->talkConfig->getStunServers() !== $accountInfo['stun']['servers']) {
|
||||
// STUN servers were added / changed
|
||||
$this->config->setAppValue('spreed', 'stun_servers', json_encode($accountInfo['stun']['servers']));
|
||||
}
|
||||
} elseif (!empty($oldAccountInfo['stun']['servers'])) {
|
||||
// STUN servers are no longer available, reset to default.
|
||||
$this->config->deleteAppValue('spreed', 'stun_servers');
|
||||
}
|
||||
|
||||
if (!empty($accountInfo['turn']['servers'])) {
|
||||
$newTurnServers = [];
|
||||
foreach ($accountInfo['turn']['servers'] as $server) {
|
||||
$newTurnServers[] = [
|
||||
'server' => $server['server'],
|
||||
'secret' => $server['secret'],
|
||||
'schemes' => $this->formatTurnSchemes($server['schemes']),
|
||||
'protocols' => $this->formatTurnProtocols($server['protocols']),
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->talkConfig->getTurnServers() !== $newTurnServers) {
|
||||
// TURN servers were added / changed
|
||||
$this->config->setAppValue('spreed', 'turn_servers', json_encode($newTurnServers));
|
||||
}
|
||||
} elseif (!empty($oldAccountInfo['turn']['servers'])) {
|
||||
// TURN servers are no longer available, reset to default.
|
||||
$this->config->deleteAppValue('spreed', 'turn_servers');
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$accountId = $this->config->getAppValue('spreed', 'hosted-signaling-server-account-id', '');
|
||||
$oldAccountInfo = json_decode($this->config->getAppValue('spreed', 'hosted-signaling-server-account', '{}'), true);
|
||||
|
||||
if ($accountId === '') {
|
||||
return;
|
||||
}
|
||||
$accountId = new AccountId($accountId);
|
||||
try {
|
||||
$accountInfo = $this->hostedSignalingServerService->fetchAccountInfo($accountId);
|
||||
} catch (HostedSignalingServerAPIException $e) {
|
||||
if ($e->getCode() === Http::STATUS_NOT_FOUND) {
|
||||
// Account was deleted, so remove the information locally
|
||||
$accountInfo = ['status' => 'deleted'];
|
||||
} else {
|
||||
// API or connection issues - do nothing and just try again later
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$oldStatus = $oldAccountInfo['status'] ?? '';
|
||||
$newStatus = $accountInfo['status'];
|
||||
|
||||
$notificationSubject = null;
|
||||
$notificationParameters = [];
|
||||
|
||||
// the status has changed
|
||||
if ($oldStatus !== $newStatus) {
|
||||
if ($newStatus === 'deleted') {
|
||||
// remove signaling servers if account is not active anymore
|
||||
$this->config->deleteAppValue('spreed', 'signaling_mode');
|
||||
$this->config->deleteAppValue('spreed', 'signaling_servers');
|
||||
|
||||
$notificationSubject = 'removed';
|
||||
} elseif ($newStatus === 'active') {
|
||||
// add signaling servers if account got active
|
||||
$this->config->deleteAppValue('spreed', 'signaling_mode');
|
||||
$this->config->setAppValue('spreed', 'signaling_servers', json_encode([
|
||||
'servers' => [
|
||||
[
|
||||
'server' => $accountInfo['signaling']['url'],
|
||||
'verify' => true,
|
||||
]
|
||||
],
|
||||
'secret' => $accountInfo['signaling']['secret'],
|
||||
]));
|
||||
$this->updateStunTurnSettings($oldAccountInfo, $accountInfo);
|
||||
|
||||
$notificationSubject = 'added';
|
||||
}
|
||||
|
||||
if (is_null($notificationSubject)) {
|
||||
$notificationSubject = 'changed-status';
|
||||
$notificationParameters = [
|
||||
'oldstatus' => $oldAccountInfo['status'],
|
||||
'newstatus' => $accountInfo['status'],
|
||||
];
|
||||
}
|
||||
|
||||
// only credentials have changed
|
||||
} elseif ($newStatus === 'active') {
|
||||
if ($oldAccountInfo['signaling']['url'] !== $accountInfo['signaling']['url']
|
||||
|| $oldAccountInfo['signaling']['secret'] !== $accountInfo['signaling']['secret']) {
|
||||
$this->config->setAppValue('spreed', 'signaling_servers', json_encode([
|
||||
'servers' => [
|
||||
[
|
||||
'server' => $accountInfo['signaling']['url'],
|
||||
'verify' => true,
|
||||
]
|
||||
],
|
||||
'secret' => $accountInfo['signaling']['secret'],
|
||||
]));
|
||||
}
|
||||
$this->updateStunTurnSettings($oldAccountInfo, $accountInfo);
|
||||
}
|
||||
|
||||
// store new account info
|
||||
if ($oldAccountInfo !== $accountInfo) {
|
||||
$this->config->setAppValue('spreed', 'hosted-signaling-server-account', json_encode($accountInfo));
|
||||
}
|
||||
|
||||
if (!is_null($notificationSubject)) {
|
||||
$this->logger->info('Hosted signaling server background job caused a notification: ' . $notificationSubject . ' ' . json_encode($notificationParameters));
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('spreed')
|
||||
->setDateTime(new \DateTime())
|
||||
->setObject('hosted-signaling-server', $notificationSubject)
|
||||
->setSubject($notificationSubject, $notificationParameters)
|
||||
->setLink($this->urlGenerator->linkToRouteAbsolute('settings.AdminSettings.index', ['section' => 'talk']) . '#signaling_server')
|
||||
->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('spreed', 'app-dark.svg')))
|
||||
;
|
||||
|
||||
$adminGroup = $this->groupManager->get('admin');
|
||||
if ($adminGroup instanceof IGroup) {
|
||||
$users = $adminGroup->getUsers();
|
||||
foreach ($users as $user) {
|
||||
// Now add the new notification
|
||||
$notification->setUser($user->getUID());
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\MatterbridgeManager;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\IConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class CheckMatterbridges
|
||||
*
|
||||
* @package OCA\Talk\BackgroundJob
|
||||
*/
|
||||
class CheckMatterbridges extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
protected IConfig $serverConfig,
|
||||
protected MatterbridgeManager $bridgeManager,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
parent::__construct($time);
|
||||
|
||||
// Every 15 minutes
|
||||
$this->setInterval(60 * 15);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
if ($this->serverConfig->getAppValue('spreed', 'enable_matterbridge', '0') === '1') {
|
||||
$this->bridgeManager->checkAllBridges();
|
||||
$this->bridgeManager->killZombieBridges();
|
||||
$this->logger->info('Checked if Matterbridge instances are running correctly.');
|
||||
} else {
|
||||
if ($this->bridgeManager->stopAllBridges()) {
|
||||
$this->logger->info('Stopped all Matterbridge instances as it is disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Chat\ChatManager;
|
||||
use OCA\Talk\Service\ProxyCacheMessageService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
class ExpireChatMessages extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
private ChatManager $chatManager,
|
||||
private ProxyCacheMessageService $pcmService,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every 5 minutes
|
||||
$this->setInterval(5 * 60);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$this->chatManager->deleteExpiredMessages();
|
||||
$this->pcmService->deleteExpiredMessages();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExpireObjectRooms extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
protected Manager $manager,
|
||||
protected RoomService $roomService,
|
||||
protected LoggerInterface $logger,
|
||||
protected IAppConfig $appConfig,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
$this->setInterval(60 * 60);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$phoneRetention = $this->appConfig->getAppValueInt('retention_phone_rooms', 7);
|
||||
if ($phoneRetention !== 0) {
|
||||
$this->executeRetention(Room::OBJECT_TYPE_PHONE_TEMPORARY, $phoneRetention);
|
||||
}
|
||||
|
||||
$eventRetention = $this->appConfig->getAppValueInt('retention_event_rooms', 28);
|
||||
if ($eventRetention !== 0) {
|
||||
$this->executeRetention(Room::OBJECT_TYPE_EVENT, $eventRetention);
|
||||
}
|
||||
|
||||
$instantMeetingRetention = $this->appConfig->getAppValueInt('retention_instant_meetings', 1);
|
||||
if ($instantMeetingRetention !== 0) {
|
||||
$this->executeRetention(Room::OBJECT_TYPE_INSTANT_MEETING, $instantMeetingRetention);
|
||||
}
|
||||
}
|
||||
|
||||
protected function executeRetention(string $objectType, int $retention): void {
|
||||
$now = $this->time->getTime();
|
||||
$minimumLastActivity = $now - $retention * 24 * 3600;
|
||||
$rooms = $this->manager->getExpiringRoomsForObjectType($objectType, $minimumLastActivity);
|
||||
|
||||
$numDeletedRooms = 0;
|
||||
foreach ($rooms as $room) {
|
||||
if ($objectType === Room::OBJECT_TYPE_EVENT) {
|
||||
[, $endTime] = explode('#', $room->getObjectId());
|
||||
if ($endTime >= $minimumLastActivity) {
|
||||
// Event time is in the future, so don't even consider deleting
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->roomService->deleteRoom($room);
|
||||
$numDeletedRooms++;
|
||||
}
|
||||
|
||||
$this->logger->info('Deleted {numDeletedRooms} {objectType} rooms because they did not have activity since {minimumLastActivity} days', [
|
||||
'objectType' => $objectType,
|
||||
'numDeletedRooms' => $numDeletedRooms,
|
||||
'minimumLastActivity' => $retention,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Signaling\Messages;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
/**
|
||||
* Class ExpireSignalingMessage
|
||||
*
|
||||
* @package OCA\Talk\BackgroundJob
|
||||
*/
|
||||
class ExpireSignalingMessage extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
protected Messages $messages,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every 5 minutes
|
||||
$this->setInterval(60 * 5);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
// Older than 5 minutes
|
||||
$this->messages->expireOlderThan(5 * 60);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCA\Talk\Webinary;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class LockInactiveRooms extends TimedJob {
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
private RoomService $roomService,
|
||||
private Config $appConfig,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every hour
|
||||
$this->setInterval(60 * 60 * 24);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[\Override]
|
||||
public function run($argument): void {
|
||||
$interval = $this->appConfig->getInactiveLockTime();
|
||||
$forceLobby = $this->appConfig->enableLobbyOnLockedRooms();
|
||||
if ($interval === 0) {
|
||||
return;
|
||||
}
|
||||
$timestamp = $this->time->getTime() - $interval * 60 * 60 * 24;
|
||||
$time = $this->time->getDateTime('@' . $timestamp);
|
||||
$rooms = $this->roomService->getInactiveRooms($time);
|
||||
array_map(function (Room $room) use ($forceLobby) {
|
||||
$this->roomService->setReadOnly($room, Room::READ_ONLY);
|
||||
$this->logger->debug("Locking room {$room->getId()} due to inactivity");
|
||||
if ($forceLobby) {
|
||||
$this->roomService->setLobby($room, Webinary::LOBBY_NON_MODERATORS, $this->time->getDateTime());
|
||||
$this->logger->debug("Enabling lobby for room {$room->getId()}");
|
||||
}
|
||||
}, $rooms);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
class MaximumCallDuration extends TimedJob {
|
||||
public function __construct(
|
||||
private IAppConfig $appConfig,
|
||||
private Manager $manager,
|
||||
private RoomService $roomService,
|
||||
private ParticipantService $participantService,
|
||||
ITimeFactory $time,
|
||||
) {
|
||||
parent::__construct($time);
|
||||
|
||||
// Every time the jobs run
|
||||
$this->setInterval(1);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$maxCallDuration = $this->appConfig->getAppValueInt('max_call_duration');
|
||||
if ($maxCallDuration <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = $this->time->getDateTime();
|
||||
$maxActiveSince = $now->sub(new \DateInterval('PT' . $maxCallDuration . 'S'));
|
||||
$rooms = $this->manager->getRoomsLongerActiveSince($maxActiveSince);
|
||||
|
||||
foreach ($rooms as $room) {
|
||||
if ($room->isFederatedConversation()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = $this->roomService->resetActiveSinceInDatabaseOnly($room);
|
||||
if (!$result) {
|
||||
// Someone else won the race condition, make sure this user disconnects directly and then return
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->participantService->endCallForEveryone($room, null);
|
||||
$this->roomService->resetActiveSinceInModelOnly($room);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Service\ReminderService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
class Reminder extends TimedJob {
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
protected ReminderService $reminderService,
|
||||
) {
|
||||
parent::__construct($time);
|
||||
// Every minute
|
||||
$this->setInterval(60);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$this->reminderService->executeReminders($this->time->getDateTime());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Federation\FederationManager;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\Files\Config\IUserMountCache;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class RemoveEmptyRooms
|
||||
*
|
||||
* @package OCA\Talk\BackgroundJob
|
||||
*/
|
||||
class RemoveEmptyRooms extends TimedJob {
|
||||
|
||||
protected int $numDeletedRooms = 0;
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $timeFactory,
|
||||
protected Manager $manager,
|
||||
protected RoomService $roomService,
|
||||
protected ParticipantService $participantService,
|
||||
protected FederationManager $federationManager,
|
||||
protected LoggerInterface $logger,
|
||||
protected IUserMountCache $userMountCache,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every 5 minutes
|
||||
$this->setInterval(60 * 5);
|
||||
$this->setTimeSensitivity(IJob::TIME_INSENSITIVE);
|
||||
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$this->manager->forAllRooms([$this, 'callback']);
|
||||
|
||||
if ($this->numDeletedRooms) {
|
||||
$this->logger->info('Deleted {numDeletedRooms} rooms because they were empty', [
|
||||
'numDeletedRooms' => $this->numDeletedRooms,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function callback(Room $room): void {
|
||||
if ($room->getType() === Room::TYPE_CHANGELOG) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->deleteIfIsEmpty($room)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->deleteIfFileIsRemoved($room);
|
||||
}
|
||||
|
||||
private function deleteIfIsEmpty(Room $room): bool {
|
||||
if ($room->getObjectType() === 'file') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->participantService->getNumberOfActors($room) !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($room->isFederatedConversation()
|
||||
&& $this->federationManager->getNumberOfInvitations($room) !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->doDeleteRoom($room);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function deleteIfFileIsRemoved(Room $room): bool {
|
||||
if ($room->getObjectType() !== 'file') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$mountsForFile = $this->userMountCache->getMountsForFileId((int)$room->getObjectId());
|
||||
if (!empty($mountsForFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->doDeleteRoom($room);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function doDeleteRoom(Room $room): void {
|
||||
$this->roomService->deleteRoom($room);
|
||||
$this->numDeletedRooms++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\CachePrefix;
|
||||
use OCA\Talk\Manager;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
|
||||
class ResetAssignedSignalingServer extends TimedJob {
|
||||
protected ICache $cache;
|
||||
|
||||
/**
|
||||
* @param ITimeFactory $time
|
||||
* @param Manager $manager
|
||||
* @param ICacheFactory $cacheFactory
|
||||
*/
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
protected Manager $manager,
|
||||
ICacheFactory $cacheFactory,
|
||||
) {
|
||||
parent::__construct($time);
|
||||
|
||||
// Every 5 minutes
|
||||
$this->setInterval(60 * 5);
|
||||
$this->setTimeSensitivity(IJob::TIME_SENSITIVE);
|
||||
|
||||
$this->cache = $cacheFactory->createDistributed(CachePrefix::SIGNALING_ASSIGNED_SERVER);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$this->manager->resetAssignedSignalingServers($this->cache);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Talk\BackgroundJob;
|
||||
|
||||
use OCA\Talk\Federation\BackendNotifier;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
/**
|
||||
* Retry to send OCM notifications
|
||||
*/
|
||||
class RetryNotificationsJob extends TimedJob {
|
||||
public function __construct(
|
||||
private BackendNotifier $backendNotifier,
|
||||
ITimeFactory $timeFactory,
|
||||
) {
|
||||
parent::__construct($timeFactory);
|
||||
|
||||
// Every time the jobs run
|
||||
$this->setInterval(1);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function run($argument): void {
|
||||
$this->backendNotifier->retrySendingFailedNotifications($this->time->getDateTime());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user