53 bool $isOAuth =
false,
54 bool $isSender =
false
60 foreach ($errors as $item)
62 if ($item->getCode() < 0)
72 if (count($messages) == 1 && reset($messages)->getCode() ==
Mail\Imap::ERR_AUTH)
74 $authError =
Loc::getMessage(
'MAIL_MAILBOX_CONNECTOR_CLIENT_IMAP_AUTH_ERR_EXT');
75 if ($isOAuth &&
Loc::getMessage(
'MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH'))
77 $authError =
Loc::getMessage(
'MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH');
79 if ($isOAuth && $isSender &&
Loc::getMessage(
'MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH_SMTP'))
81 $authError =
Loc::getMessage(
'MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH_SMTP');
88 $moreDetailsSection =
false;
92 $moreDetailsSection =
true;
95 $reduce =
function($error)
97 return $error->getMessage();
100 if($moreDetailsSection)
103 implode(
': ', array_map($reduce, $messages)),
105 implode(
': ', array_map($reduce, $details))
111 implode(
': ', array_map($reduce, $messages)),
236 string $password =
'',
241 string $storageOauthUid =
'',
242 bool $syncAfterConnection =
true,
243 bool $useSmtp =
true,
244 string $serverSmtp =
'',
246 bool $sslSmtp =
true,
247 string $loginSmtp =
'',
248 string $passwordSMTP =
'',
251 $login = trim($login);
252 $password = trim($password);
253 $server = trim($server);
255 $currentSite = \CSite::getById(SITE_ID)->fetch();
258 $this->setIsSmtpAvailable();
260 $service = Mail\MailServicesTable::getList([
263 'SERVICE_TYPE' =>
'imap',
269 $this->setError(self::NO_MAIL_SERVICES_ERROR_KEY);
273 if ($service[
'ACTIVE'] !==
'Y')
281 $this->setError(self::LIMIT_ERROR_KEY);
305 'SERVER' => $service[
'SERVER'] ?: trim($server),
306 'PORT' => $service[
'PORT'] ?: $port,
307 'USE_TLS' => $service[
'ENCRYPTION'] ?: $ssl,
308 'LINK' => $service[
'LINK'],
311 'PERIOD_CHECK' => 60 * 24,
314 'sync_from' => time(),
315 'crm_sync_from' => time(),
316 'activateSync' =>
false,
321 if (
'N' == $service[
'UPLOAD_OUTGOING'] || empty($service[
'UPLOAD_OUTGOING']))
323 $mailboxData[
'OPTIONS'][
'flags'][] =
'deny_upload';
329 $oauthHelper->getStoredToken($storageOauthUid);
330 $mailboxData[
'LOGIN'] = $mailboxData[
'EMAIL'];
331 $mailboxData[
'PASSWORD'] = $oauthHelper->buildMeta();
336 $mailboxData[
'LOGIN'] = $login;
337 $mailboxData[
'PASSWORD'] = $password;
340 if (empty($mailbox[
'EMAIL']))
342 $address =
new Address($mailboxData[
'EMAIL']);
343 if (!$address->validate())
345 $this->setError(self::OAUTH_ERROR_KEY);
349 $mailboxData[
'EMAIL'] = $address->getEmail();
350 $this->email = $mailboxData[
'EMAIL'];
354 $this->email = $mailbox[
'EMAIL'];
359 $mailbox = Mail\MailboxTable::getList([
361 '=EMAIL' => $mailboxData[
'EMAIL'],
362 '=USER_ID' => $USER->getId(),
364 '=LID' => $currentSite[
'LID'],
368 if (!empty($mailbox))
370 $this->setError(self::EXISTS_ERROR_KEY);
375 if (empty($mailboxData[
'NAME']))
377 $mailboxData[
'NAME'] = $mailboxData[
'EMAIL'];
380 if (!in_array($mailboxData[
'USE_TLS'], array(
'Y',
'S')))
382 $mailboxData[
'USE_TLS'] =
'N';
385 $unseen = Mail\Helper::getImapUnseen($mailboxData,
'inbox', $error, $errors);
386 if ($unseen ===
false)
401 if ($this->getSmtpAvailable() && !$useSmtp && !empty($mailbox))
403 $res = Main\Mail\Internal\SenderTable::getList(array(
405 'IS_CONFIRMED' =>
true,
406 '=EMAIL' => $mailboxData[
'EMAIL'],
409 while ($item = $res->fetch())
411 if (!empty($item[
'OPTIONS'][
'smtp'][
'server']))
413 unset($item[
'OPTIONS'][
'smtp']);
414 Main\Mail\Internal\SenderTable::update(
417 'OPTIONS' => $item[
'OPTIONS'],
423 Main\Mail\Sender::clearCustomSmtpCache($mailboxData[
'EMAIL']);
426 if ($this->getSmtpAvailable() && $useSmtp)
429 'NAME' => $mailboxData[
'USERNAME'],
430 'EMAIL' => $mailboxData[
'EMAIL'],
431 'USER_ID' => $USER->getId(),
432 'IS_CONFIRMED' =>
false,
433 'IS_PUBLIC' =>
false,
435 'source' =>
'mail.client.config',
439 $res = Main\Mail\Internal\SenderTable::getList(array(
441 'IS_CONFIRMED' =>
true,
442 '=EMAIL' => $mailboxData[
'EMAIL'],
449 while ($item = $res->fetch())
451 if (empty($smtpConfirmed))
453 if (!empty($item[
'OPTIONS'][
'smtp'][
'server']) && empty($item[
'OPTIONS'][
'smtp'][
'encrypted']))
455 $smtpConfirmed = $item[
'OPTIONS'][
'smtp'];
459 if ($senderFields[
'USER_ID'] == $item[
'USER_ID'] && $senderFields[
'NAME'] == $item[
'NAME'])
461 $senderFields = $item;
462 $senderFields[
'IS_CONFIRMED'] =
false;
463 $senderFields[
'OPTIONS'][
'__replaces'] = $item[
'ID'];
465 unset($senderFields[
'ID']);
467 if (!empty($smtpConfirmed))
475 if (!empty($senderFields))
478 'server' => $service[
'SMTP_SERVER'] ?: trim($serverSmtp),
479 'port' => $service[
'SMTP_PORT'] ?: $portSmtp,
480 'protocol' => (
'Y' == ($service[
'SMTP_ENCRYPTION'] ?: $sslSmtp) ?
'smtps' :
'smtp'),
481 'login' => $service[
'SMTP_LOGIN_AS_IMAP'] ==
'Y' ? $mailboxData[
'LOGIN'] : $loginSmtp,
485 if (!empty($smtpConfirmed) && is_array($smtpConfirmed))
488 $smtpConfig = array_filter($smtpConfig) + $smtpConfirmed;
491 if ($service[
'SMTP_PASSWORD_AS_IMAP'] ==
'Y')
493 $smtpConfig[
'password'] = $mailboxData[
'PASSWORD'];
494 $smtpConfig[
'isOauth'] = !empty($storageOauthUid);
496 else if ($passwordSMTP <>
'')
498 if (preg_match(
'/^\^/', $passwordSMTP))
500 $this->setError(self::SMTP_PASS_BAD_SYMBOLS_ERROR_KEY);
503 else if (preg_match(
'/\x00/', $passwordSMTP))
505 $this->setError(self::SMTP_PASS_BAD_SYMBOLS_ERROR_KEY);
509 $smtpConfig[
'password'] = $passwordSMTP;
512 if (!$service[
'SMTP_SERVER'])
514 $regex =
'/^(?:(?:http|https|ssl|tls|smtp):\/\/)?((?:[a-z0-9](?:-*[a-z0-9])*\.?)+)$/i';
515 if (!preg_match($regex, $smtpConfig[
'server'], $matches) && $matches[1] <>
'')
517 $this->setError(self::OAUTH_ERROR_KEY);
521 $smtpConfig[
'server'] = $matches[1];
523 if (!self::isValidMailHost($smtpConfig[
'server']))
525 $this->setError(self::OAUTH_ERROR_KEY);
530 if (!$service[
'SMTP_PORT'])
532 if ($smtpConfig[
'port'] <= 0 || $smtpConfig[
'port'] > 65535)
534 $this->setError(self::OAUTH_ERROR_KEY);
539 $senderFields[
'OPTIONS'][
'smtp'] = $smtpConfig;
541 if (!empty($smtpConfirmed))
543 $senderFields[
'IS_CONFIRMED'] = !array_diff(
544 array(
'server',
'port',
'protocol',
'login',
'password',
'isOauth'),
545 array_keys(array_intersect_assoc($smtpConfig, $smtpConfirmed))
550 if (Main\Loader::includeModule(
'crm') && \CCrmPerms::isAccessEnabled())
552 $crmAvailable = $USER->isAdmin() || $USER->canDoOperation(
'bitrix24_config')
553 || \COption::getOptionString(
'intranet',
'allow_external_mail_crm',
'Y', SITE_ID) ==
'Y';
555 $mailboxData[
'OPTIONS'][
'sync_from'] = strtotime(
'today UTC 00:00'.sprintf(
'-%u days', self::MESSAGE_MAX_AGE));
560 $mailboxData[
'OPTIONS'][
'flags'][] =
'crm_connect';
561 $mailboxData[
'OPTIONS'][
'crm_sync_from'] = strtotime(sprintf(
'-%u days', $maxAge));
562 $mailboxData[
'OPTIONS'][
'crm_new_entity_in'] = \CCrmOwnerType::LeadName;
563 $mailboxData[
'OPTIONS'][
'crm_new_entity_out'] = \CCrmOwnerType::ContactName;
564 $mailboxData[
'OPTIONS'][
'crm_lead_source'] =
'EMAIL';
565 $mailboxData[
'OPTIONS'][
'crm_lead_resp'] = [empty($mailbox) ? $USER->getId() : $mailbox[
'USER_ID']];
569 if (!empty($senderFields) && empty($senderFields[
'IS_CONFIRMED']))
571 $result = $this->
appendSender($senderFields, (
string)($fields[
'user_principal_name'] ??
''));
573 if (!empty($result[
'errors']) && $result[
'errors'] instanceof Main\
ErrorCollection)
575 $this->
addErrors($result[
'errors'], $isOAuth,
true);
578 else if (!empty($result[
'error']))
583 else if (empty($result[
'confirmed']))
585 $this->
addError(
'MAIL_CLIENT_CONFIG_SMTP_CONFIRM');
590 $mailboxData[
'OPTIONS'][
'version'] = 6;
594 $mailboxData = array_merge([
595 'LID' => $currentSite[
'LID'],
597 'SERVICE_ID' => $service[
'ID'],
598 'SERVER_TYPE' => $service[
'SERVICE_TYPE'],
599 'CHARSET' => $currentSite[
'CHARSET'],
600 'USER_ID' => $USER->getId(),
601 'SYNC_LOCK' => time()
604 $result = $mailboxId = \CMailbox::add($mailboxData);
606 addEventToStatFile(
'mail',
'add_mailbox', $service[
'NAME'], ($result > 0 ?
'success' :
'failed'));
610 $this->setError(self::EXISTS_ERROR_KEY);
620 $ownerAccessCode =
'U' . (empty($mailbox) ? $USER->getId() : $mailbox[
'USER_ID']);
621 $access = array($ownerAccessCode);
623 foreach (array_unique($access) as $item)
625 Mail\Internals\MailboxAccessTable::add(array(
626 'MAILBOX_ID' => $mailboxId,
628 'ACCESS_CODE' => $item,
633 $mailboxHelper->cacheDirs();
636 'MAILBOX_ID' => $mailboxId,
637 'NAME' => sprintf(
'CRM IMAP %u', $mailboxId),
638 'ACTION_TYPE' =>
'crm_imap',
639 'WHEN_MAIL_RECEIVED' =>
'Y',
640 'WHEN_MANUALLY_RUN' =>
'Y',
643 \CMailFilter::add($filterFields);
647 if ($syncAfterConnection)
649 $this->syncMailbox($mailboxId);
654 'email' => trim($mailboxData[
'EMAIL']),