10namespace Bitrix\Main\Authentication;
14use Bitrix\Main\Security;
15use Bitrix\Main\Config\Option;
16use Bitrix\Main\Authentication\Internal\EO_UserDevice;
17use Bitrix\Main\Authentication\Internal\EO_UserDeviceLogin;
18use Bitrix\Main\Web\UserAgent\Browser;
19use Bitrix\Main\Web\UserAgent\DeviceType;
20use Bitrix\Main\Service\GeoIp;
21use Bitrix\Main\Service\GeoIp\Internal\GeonameTable;
23use Bitrix\Main\Localization\LanguageTable;
24use Bitrix\Main\Localization\Loc;
25use Bitrix\ImBot\Bot\Marta;
26use Bitrix\Im\V2\Message;
27use Bitrix\Im\V2\Entity\User\User;
36 $device = static::findByCookie(
$context);
41 $device = static::findByUserAgent(
$context);
43 if ($device ===
null &&
$context->getApplicationPasswordId())
45 $device = static::findByAppPasswordId(
$context);
58 $deviceLogin = static::addDeviceLogin($device,
$context);
60 $notifyByEmail = (Option::get(
'main',
'user_device_notify',
'N') ===
'Y');
63 if ($notifyByEmail || $notifyByIm)
66 static::notifyUser($device, $deviceLogin,
$user);
72 static::update($device,
$context, $cookable);
73 static::addDeviceLogin($device,
$context);
76 static::setCookie($device->getDeviceUid());
81 $request = Main\Context::getCurrent()->getRequest();
82 $deviceUid =
$request->getCookie(static::COOKIE_NAME);
84 if (is_string($deviceUid) && $deviceUid !=
'')
88 ->where(
'USER_ID',
$context->getUserId())
89 ->where(
'DEVICE_UID', $deviceUid)
99 $request = Main\Context::getCurrent()->getRequest();
100 $userAgent =
$request->getUserAgent();
105 ->where(
'USER_ID',
$context->getUserId())
106 ->where(
'COOKABLE',
false)
110 while ($device =
$query->fetchObject())
112 if (static::match($userAgent, $device->getUserAgent()))
123 $request = Main\Context::getCurrent()->getRequest();
124 $userAgent =
$request->getUserAgent();
129 ->where(
'USER_ID',
$context->getUserId())
130 ->where(
'COOKABLE',
true)
131 ->where(
'APP_PASSWORD_ID',
$context->getApplicationPasswordId())
135 while ($device =
$query->fetchObject())
137 if (static::match($userAgent, $device->getUserAgent()))
146 protected static function match(?
string $userAgent, ?
string $patternAgent): bool
148 $pattern = preg_replace(
'/\\d+/i',
'\\d+', preg_quote((
string)$patternAgent,
'/'));
150 return preg_match(
"/{$pattern}/i", (
string)$userAgent);
160 ->setDeviceUid(
Security\Random::getString(32))
161 ->setDeviceType($browser->getDeviceType())
162 ->setBrowser($browser->getName())
163 ->setPlatform($browser->getPlatform())
164 ->setUserAgent($browser->getUserAgent())
165 ->setAppPasswordId(
$context->getApplicationPasswordId())
177 ->setDeviceType($browser->getDeviceType())
178 ->setBrowser($browser->getName())
179 ->setPlatform($browser->getPlatform())
180 ->setUserAgent($browser->getUserAgent())
181 ->setCookable($cookable)
182 ->setAppPasswordId(
$context->getApplicationPasswordId())
187 protected static function setCookie(
string $value): void
189 $cookie =
new Web\Cookie(static::COOKIE_NAME, $value, time() + 60 * 60 * 24 * 30 * 12);
190 Main\Context::getCurrent()->getResponse()->addCookie($cookie);
200 ->setDeviceId($device->getId())
203 ->setAppPasswordId(
$context->getApplicationPasswordId())
204 ->setStoredAuthId(
$context->getStoredAuthId())
205 ->setHitAuthId(
$context->getHitAuthId())
208 if (Option::get(
'main',
'user_device_geodata',
'N') ===
'Y')
212 if ($ipData && $ipData->isSuccess())
214 $data = $ipData->getGeoData();
217 ->setCityGeoid(
$data->cityGeonameId)
218 ->setRegionGeoid(
$data->subRegionGeonameId ??
$data->regionGeonameId)
219 ->setCountryIsoCode(
$data->countryCode)
232 $codes = unserialize(Option::get(
'main',
'user_device_notify_codes'), [
'allowed_classes' =>
false]);
235 $userCodes = \CAccess::GetUserCodesArray(
$user[
'ID']);
236 if (empty(array_intersect($codes, $userCodes)))
243 $currentLang = Main\Context::getCurrent()->getLanguage();
244 $lang =
$user[
'LANGUAGE_ID'] !=
'' ?
$user[
'LANGUAGE_ID'] : $currentLang;
251 if (Option::get(
'main',
'user_device_geodata',
'N') ===
'Y')
253 $geonames = static::getGeoNames($deviceLogin,
$lang);
257 'USER_ID' =>
$user[
'ID'],
258 'EMAIL' =>
$user[
'EMAIL'],
259 'LOGIN' =>
$user[
'LOGIN'],
260 'NAME' =>
$user[
'NAME'],
261 'LAST_NAME' =>
$user[
'LAST_NAME'],
262 'DEVICE' => $deviceTypes[$device->getDeviceType()],
263 'BROWSER' => $device->getBrowser(),
264 'PLATFORM' => $device->getPlatform(),
265 'USER_AGENT' => $device->getUserAgent(),
266 'IP' => $deviceLogin->getIp(),
267 'DATE' => $deviceLogin->getLoginDate(),
268 'COUNTRY' => $geonames[
'COUNTRY'] ??
'',
269 'REGION' => $geonames[
'REGION'] ??
'',
270 'CITY' => $geonames[
'CITY'] ??
'',
271 'LOCATION' => $geonames[
'LOCATION'] ??
'',
274 if (Option::get(
'main',
'user_device_notify',
'N') ===
'Y')
280 $site = Main\Context::getCurrent()->getSite();
283 $site = \CSite::GetDefSite();
288 'EVENT_NAME' => self::EMAIL_EVENT,
291 'LANGUAGE_ID' =>
$lang,
301 $replace[
"#$key#"] = $value;
303 $message = Loc::getMessage(
'main_device_message', $replace,
$lang);
304 $pushMessage = Loc::getMessage(
'main_device_push_message',
null,
$lang);
306 $infoBotId = Marta::getBotId();
309 $chat = User::getInstance(
$user[
'ID'])->getChatWith($infoBotId);
315 ->setPushMessage($pushMessage)
316 ->setAuthorId($infoBotId)
318 $chat->sendMessage($chatMessage);
327 $geoids = array_filter([$deviceLogin->getCityGeoid(), $deviceLogin->getRegionGeoid()]);
332 if (!empty($geonames))
334 $currentLang = Main\Context::getCurrent()->getLanguage();
337 if (
$lang != $currentLang)
339 $language = LanguageTable::getList([
340 'filter' => [
'=LID' =>
$lang,
'=ACTIVE' =>
'Y'],
341 'cache' => [
'ttl' => 86400],
346 $langCode = $language->getCode();
351 $langCode = Main\Context::getCurrent()->getLanguageObject()->getCode();
354 if (($cityCode = $deviceLogin->getCityGeoid()) > 0)
356 $city = $geonames[$cityCode][$langCode] ?? $geonames[$cityCode][
'en'] ??
'';
358 if (($regionCode = $deviceLogin->getRegionGeoid()) > 0)
360 $region = $geonames[$regionCode][$langCode] ?? $geonames[$regionCode][
'en'] ??
'';
366 if (($countryCode = $deviceLogin->getCountryIsoCode()) !=
'')
368 $countries = \GetCountries(
$lang);
369 $country = $countries[$countryCode][
'NAME'];
395 where USER_ID > {$lastId}
402 while (
$user = $users->fetch())
409 where USER_ID = {$userId}
411 and APP_PASSWORD_ID is not null
418 $device = $devices[
$i];
420 if (isset($deleted[$device[
'ID']]))
425 for ($j =
$i + 1; $j <
$count; $j++)
427 $deviceDouble = $devices[$j];
429 if ($deviceDouble[
'APP_PASSWORD_ID'] == $device[
'APP_PASSWORD_ID'] && static::match($deviceDouble[
'USER_AGENT'], $device[
'USER_AGENT']))
432 update b_user_device_login
433 set DEVICE_ID = {$device['ID']}
434 where DEVICE_ID = {$deviceDouble['ID']}
438 delete from b_user_device
439 where ID = {$deviceDouble['ID']}
442 $deleted[$deviceDouble[
'ID']] = 1;
450 return "\\Bitrix\\Main\\Authentication\\Device::deleteDuplicatesAgent({$userId});";
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static getConnection($name="")
static update(EO_UserDevice $device, Context $context, bool $cookable)
static findByAppPasswordId(Context $context)
static getGeoNames(EO_UserDeviceLogin $deviceLogin, string $lang)
static match(?string $userAgent, ?string $patternAgent)
static addDeviceLogin(EO_UserDevice $device, Context $context)
static notifyUser(EO_UserDevice $device, EO_UserDeviceLogin $deviceLogin, array $user)
static findByCookie(Context $context)
static findByUserAgent(Context $context)
static addLogin(Context $context, array $user)
static setCookie(string $value)
static add(Context $context)
static deleteDuplicatesAgent(int $lastId=0)
static includeModule($moduleName)
static isModuleInstalled($moduleName)
static createObject($setDefaultValues=true)
static getDataResult($ip='', $lang='', array $required=[])
static detect(?string $userAgent=null)
static getDescription($lang=null)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(!defined('SITE_ID')) $lang
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if(!Loader::includeModule('sale')) $pattern