diff --git a/lib/Command/PhoneNumber/AddPhoneNumber.php b/lib/Command/PhoneNumber/AddPhoneNumber.php index e65e76259a9..8785684ecb3 100644 --- a/lib/Command/PhoneNumber/AddPhoneNumber.php +++ b/lib/Command/PhoneNumber/AddPhoneNumber.php @@ -11,8 +11,8 @@ use OC\Core\Command\Base; use OCA\Talk\Model\PhoneNumber; use OCA\Talk\Model\PhoneNumberMapper; +use OCA\Talk\Service\PhoneNumberValidation; use OCP\AppFramework\Db\DoesNotExistException; -use OCP\IPhoneNumberUtil; use OCP\IUser; use OCP\IUserManager; use Symfony\Component\Console\Input\InputArgument; @@ -24,7 +24,7 @@ class AddPhoneNumber extends Base { public function __construct( private IUserManager $userManager, - private IPhoneNumberUtil $phoneNumberUtil, + private PhoneNumberValidation $phoneNumberValidation, private PhoneNumberMapper $mapper, ) { parent::__construct(); @@ -66,12 +66,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $userId = $user->getUID(); - $phoneNumberStandard = preg_match('/^[0-9]{1,20}$/', $phoneNumber) ? $phoneNumber : $this->phoneNumberUtil->convertToStandardFormat($phoneNumber); - if ($phoneNumberStandard === null) { + try { + $phoneNumber = $this->phoneNumberValidation->validateNumber($phoneNumber); + } catch (\InvalidArgumentException) { $output->writeln('Not a valid phone number ' . $phoneNumber . '. The format is invalid.'); return self::FAILURE; } - $phoneNumber = $phoneNumberStandard; try { $entry = $this->mapper->findByPhoneNumber($phoneNumber); diff --git a/lib/Command/PhoneNumber/ImportPhoneNumbers.php b/lib/Command/PhoneNumber/ImportPhoneNumbers.php index ac9d4098426..32c46978369 100644 --- a/lib/Command/PhoneNumber/ImportPhoneNumbers.php +++ b/lib/Command/PhoneNumber/ImportPhoneNumbers.php @@ -11,8 +11,8 @@ use OC\Core\Command\Base; use OCA\Talk\Model\PhoneNumber; use OCA\Talk\Model\PhoneNumberMapper; +use OCA\Talk\Service\PhoneNumberValidation; use OCP\IDBConnection; -use OCP\IPhoneNumberUtil; use OCP\IUser; use OCP\IUserManager; use Symfony\Component\Console\Input\InputInterface; @@ -23,7 +23,7 @@ class ImportPhoneNumbers extends Base { public function __construct( private IUserManager $userManager, - private IPhoneNumberUtil $phoneNumberUtil, + private PhoneNumberValidation $phoneNumberValidation, private PhoneNumberMapper $mapper, private IDBConnection $db, ) { @@ -72,12 +72,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int continue; } - $phoneNumberStandard = preg_match('/^[0-9]{1,20}$/', $row[0]) ? $row[0] : $this->phoneNumberUtil->convertToStandardFormat($row[0]); - if ($phoneNumberStandard === null) { + try { + $row[0] = $this->phoneNumberValidation->validateNumber($row[0]); + } catch (\InvalidArgumentException) { $output->writeln('Not a valid phone number ' . $row[0] . '. The format is invalid.'); return self::FAILURE; } - $row[0] = $phoneNumberStandard; $user = $this->userManager->get($row[1]); if (!$user instanceof IUser) { diff --git a/lib/Service/PhoneNumberValidation.php b/lib/Service/PhoneNumberValidation.php new file mode 100644 index 00000000000..01c88c2d30d --- /dev/null +++ b/lib/Service/PhoneNumberValidation.php @@ -0,0 +1,62 @@ +config->getSystemValueString('default_phone_region') ?: null; + $standardPhoneNumber = $this->phoneNumberUtil->convertToStandardFormat($phoneNumber, $defaultRegion); + + if ($standardPhoneNumber === null) { + throw new \InvalidArgumentException(); + } + + if (str_starts_with($standardPhoneNumber, '+')) { + return substr($standardPhoneNumber, 1); + } + + return $standardPhoneNumber; + } +} diff --git a/lib/SetupCheck/SIPConfiguration.php b/lib/SetupCheck/SIPConfiguration.php index 0f2fb2a387b..83cbf94b77b 100644 --- a/lib/SetupCheck/SIPConfiguration.php +++ b/lib/SetupCheck/SIPConfiguration.php @@ -9,6 +9,7 @@ namespace OCA\Talk\SetupCheck; use OCA\Talk\Config; +use OCP\IDBConnection; use OCP\IL10N; use OCP\SetupCheck\ISetupCheck; use OCP\SetupCheck\SetupResult; @@ -16,6 +17,7 @@ class SIPConfiguration implements ISetupCheck { public function __construct( protected readonly Config $talkConfig, + protected readonly IDBConnection $connection, protected readonly IL10N $l, ) { } @@ -39,9 +41,35 @@ public function run(): SetupResult { if ($this->talkConfig->getSignalingMode() === Config::SIGNALING_INTERNAL) { return SetupResult::success($this->l->t('Using the SIP functionality requires a High-performance backend.')); } + + $query = $this->connection->getQueryBuilder(); + $query->select('phone_number') + ->from('talk_phone_numbers') + ->where($query->expr()->like('phone_number', $query->createNamedParameter( + $this->connection->escapeLikeParameter('+') . '%' + ))) + ->orWhere($query->expr()->like('phone_number', $query->createNamedParameter( + $this->connection->escapeLikeParameter('00') . '%' + ))); + + $result = $query->executeQuery(); + $invalidNumbers = $result->fetchFirstColumn(); + $result->closeCursor(); + + if (!empty($invalidNumbers)) { + $message = $this->l->t("Assigned Talk phone numbers must not start with + or 00. Please remove the following numbers:\n{list}"); + $message = str_replace( + '{list}', + implode("\n", $invalidNumbers), + $message + ); + return SetupResult::error($message, 'https://portal.nextcloud.com/article/Nextcloud-Talk/Nextcloud-Talk-Phone/Direct-Dial-in#content-provisioning'); + } + if ($this->talkConfig->getSIPSharedSecret() === '' && $this->talkConfig->getDialInInfo() === '') { return SetupResult::info($this->l->t('No SIP backend configured')); } + return SetupResult::success(); } }