From be26cd248cc4aa0492296681d6a7dcc6a0e2d6d4 Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Sat, 31 Dec 2016 20:03:41 +0300 Subject: [PATCH] Fix typo --- .flowconfig | 25 - {asserts => assets}/android-icon.png | Bin {asserts => assets}/apple-touch-icon.png | Bin {asserts => assets}/browsers/chrome.gif | Bin {asserts => assets}/browsers/firefox.gif | Bin {asserts => assets}/browsers/opera.gif | Bin {asserts => assets}/browsers/safari.gif | Bin {asserts => assets}/css/default-skin.png | Bin {asserts => assets}/css/default-skin.svg | 0 {asserts => assets}/css/flags.png | Bin {asserts => assets}/css/images/editor.png | Bin .../css/images/empty-contact.png | Bin {asserts => assets}/css/images/grey.png | Bin .../css/images/icom-message-notification.png | Bin {asserts => assets}/css/images/loading.gif | Bin .../css/images/rainloop-logo.png | Bin {asserts => assets}/css/images/sync.gif | Bin {asserts => assets}/css/images/sync.png | Bin {asserts => assets}/css/images/white.png | Bin {asserts => assets}/css/img/loading.gif | Bin {asserts => assets}/css/loading.gif | Bin {asserts => assets}/css/preloader.gif | Bin {asserts => assets}/favicon.ico | Bin {asserts => assets}/favicon.png | Bin {asserts => assets}/manifest.json | 0 {asserts => assets}/sounds/new-mail.mp3 | Bin {asserts => assets}/sounds/new-mail.ogg | Bin dev/admin.js | 2 +- dev/app.js | 2 +- dev/bootstrap.js | 2 +- gulpfile.js | 14 +- package.json | 2 +- .../0.0.0/app/libraries/RainLoop/Actions.php | 9 +- .../v/0.0.0/app/libraries/RainLoop/Social.php | 1612 ++++++++--------- yarn.lock | 6 +- 35 files changed, 825 insertions(+), 849 deletions(-) delete mode 100644 .flowconfig rename {asserts => assets}/android-icon.png (100%) rename {asserts => assets}/apple-touch-icon.png (100%) rename {asserts => assets}/browsers/chrome.gif (100%) rename {asserts => assets}/browsers/firefox.gif (100%) rename {asserts => assets}/browsers/opera.gif (100%) rename {asserts => assets}/browsers/safari.gif (100%) rename {asserts => assets}/css/default-skin.png (100%) rename {asserts => assets}/css/default-skin.svg (100%) rename {asserts => assets}/css/flags.png (100%) rename {asserts => assets}/css/images/editor.png (100%) rename {asserts => assets}/css/images/empty-contact.png (100%) rename {asserts => assets}/css/images/grey.png (100%) rename {asserts => assets}/css/images/icom-message-notification.png (100%) rename {asserts => assets}/css/images/loading.gif (100%) rename {asserts => assets}/css/images/rainloop-logo.png (100%) rename {asserts => assets}/css/images/sync.gif (100%) rename {asserts => assets}/css/images/sync.png (100%) rename {asserts => assets}/css/images/white.png (100%) rename {asserts => assets}/css/img/loading.gif (100%) rename {asserts => assets}/css/loading.gif (100%) rename {asserts => assets}/css/preloader.gif (100%) rename {asserts => assets}/favicon.ico (100%) rename {asserts => assets}/favicon.png (100%) rename {asserts => assets}/manifest.json (100%) rename {asserts => assets}/sounds/new-mail.mp3 (100%) rename {asserts => assets}/sounds/new-mail.ogg (100%) diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index f0d79f28e..000000000 --- a/.flowconfig +++ /dev/null @@ -1,25 +0,0 @@ - -[ignore] -.*/node_modules/.* -.*/vendors/.* -.*/rainloop/.* -.*/plugins/.* -.*/build/.* -.*/asserts/.* - -[include] - -[libs] -./dev/ - -[options] -strip_root=true -module.system=haste - -esproposal.class_static_fields=enable -esproposal.class_instance_fields=enable -esproposal.decorators=ignore - -experimental.strict_type_args=true - -unsafe.enable_getters_and_setters=true diff --git a/asserts/android-icon.png b/assets/android-icon.png similarity index 100% rename from asserts/android-icon.png rename to assets/android-icon.png diff --git a/asserts/apple-touch-icon.png b/assets/apple-touch-icon.png similarity index 100% rename from asserts/apple-touch-icon.png rename to assets/apple-touch-icon.png diff --git a/asserts/browsers/chrome.gif b/assets/browsers/chrome.gif similarity index 100% rename from asserts/browsers/chrome.gif rename to assets/browsers/chrome.gif diff --git a/asserts/browsers/firefox.gif b/assets/browsers/firefox.gif similarity index 100% rename from asserts/browsers/firefox.gif rename to assets/browsers/firefox.gif diff --git a/asserts/browsers/opera.gif b/assets/browsers/opera.gif similarity index 100% rename from asserts/browsers/opera.gif rename to assets/browsers/opera.gif diff --git a/asserts/browsers/safari.gif b/assets/browsers/safari.gif similarity index 100% rename from asserts/browsers/safari.gif rename to assets/browsers/safari.gif diff --git a/asserts/css/default-skin.png b/assets/css/default-skin.png similarity index 100% rename from asserts/css/default-skin.png rename to assets/css/default-skin.png diff --git a/asserts/css/default-skin.svg b/assets/css/default-skin.svg similarity index 100% rename from asserts/css/default-skin.svg rename to assets/css/default-skin.svg diff --git a/asserts/css/flags.png b/assets/css/flags.png similarity index 100% rename from asserts/css/flags.png rename to assets/css/flags.png diff --git a/asserts/css/images/editor.png b/assets/css/images/editor.png similarity index 100% rename from asserts/css/images/editor.png rename to assets/css/images/editor.png diff --git a/asserts/css/images/empty-contact.png b/assets/css/images/empty-contact.png similarity index 100% rename from asserts/css/images/empty-contact.png rename to assets/css/images/empty-contact.png diff --git a/asserts/css/images/grey.png b/assets/css/images/grey.png similarity index 100% rename from asserts/css/images/grey.png rename to assets/css/images/grey.png diff --git a/asserts/css/images/icom-message-notification.png b/assets/css/images/icom-message-notification.png similarity index 100% rename from asserts/css/images/icom-message-notification.png rename to assets/css/images/icom-message-notification.png diff --git a/asserts/css/images/loading.gif b/assets/css/images/loading.gif similarity index 100% rename from asserts/css/images/loading.gif rename to assets/css/images/loading.gif diff --git a/asserts/css/images/rainloop-logo.png b/assets/css/images/rainloop-logo.png similarity index 100% rename from asserts/css/images/rainloop-logo.png rename to assets/css/images/rainloop-logo.png diff --git a/asserts/css/images/sync.gif b/assets/css/images/sync.gif similarity index 100% rename from asserts/css/images/sync.gif rename to assets/css/images/sync.gif diff --git a/asserts/css/images/sync.png b/assets/css/images/sync.png similarity index 100% rename from asserts/css/images/sync.png rename to assets/css/images/sync.png diff --git a/asserts/css/images/white.png b/assets/css/images/white.png similarity index 100% rename from asserts/css/images/white.png rename to assets/css/images/white.png diff --git a/asserts/css/img/loading.gif b/assets/css/img/loading.gif similarity index 100% rename from asserts/css/img/loading.gif rename to assets/css/img/loading.gif diff --git a/asserts/css/loading.gif b/assets/css/loading.gif similarity index 100% rename from asserts/css/loading.gif rename to assets/css/loading.gif diff --git a/asserts/css/preloader.gif b/assets/css/preloader.gif similarity index 100% rename from asserts/css/preloader.gif rename to assets/css/preloader.gif diff --git a/asserts/favicon.ico b/assets/favicon.ico similarity index 100% rename from asserts/favicon.ico rename to assets/favicon.ico diff --git a/asserts/favicon.png b/assets/favicon.png similarity index 100% rename from asserts/favicon.png rename to assets/favicon.png diff --git a/asserts/manifest.json b/assets/manifest.json similarity index 100% rename from asserts/manifest.json rename to assets/manifest.json diff --git a/asserts/sounds/new-mail.mp3 b/assets/sounds/new-mail.mp3 similarity index 100% rename from asserts/sounds/new-mail.mp3 rename to assets/sounds/new-mail.mp3 diff --git a/asserts/sounds/new-mail.ogg b/assets/sounds/new-mail.ogg similarity index 100% rename from asserts/sounds/new-mail.ogg rename to assets/sounds/new-mail.ogg diff --git a/dev/admin.js b/dev/admin.js index d551991ad..75b836765 100644 --- a/dev/admin.js +++ b/dev/admin.js @@ -1,4 +1,4 @@ -/* @flow */ + import bootstrap from 'bootstrap'; import App from 'App/Admin'; diff --git a/dev/app.js b/dev/app.js index 7c6b53d1c..08aa049d5 100644 --- a/dev/app.js +++ b/dev/app.js @@ -1,4 +1,4 @@ -/* @flow */ + import bootstrap from 'bootstrap'; import App from 'App/User'; diff --git a/dev/bootstrap.js b/dev/bootstrap.js index 5ded282af..1a7b99f79 100644 --- a/dev/bootstrap.js +++ b/dev/bootstrap.js @@ -1,4 +1,4 @@ -/* @flow */ + import window from 'window'; import {killCtrlACtrlS, detectDropdownVisibility, createCommandLegacy, domReady} from 'Common/Utils'; import {$win, $html, data as GlobalsData, bMobileDevice} from 'Common/Globals'; diff --git a/gulpfile.js b/gulpfile.js index 61f9acc54..3a5a19c01 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -167,8 +167,8 @@ cfg.paths.staticMinJS = 'rainloop/v/' + cfg.devVersion + '/static/js/min/'; cfg.paths.staticCSS = 'rainloop/v/' + cfg.devVersion + '/static/css/'; cfg.paths.momentLocales = 'rainloop/v/' + cfg.devVersion + '/app/localization/moment/'; -cfg.paths.asserts = { - src: 'asserts/**/*.*' +cfg.paths.assets = { + src: 'assets/**/*.*' }; cfg.paths.less = { @@ -269,12 +269,12 @@ cfg.paths.js = { // assers -gulp.task('asserts:clean', function() { +gulp.task('assets:clean', function() { return cleanDir(cfg.paths.static); }); -gulp.task('asserts', function() { - return gulp.src(cfg.paths.asserts.src) +gulp.task('assets', function() { + return gulp.src(cfg.paths.assets.src) .pipe(gulp.dest(cfg.paths.static)); }); @@ -284,7 +284,7 @@ gulp.task('css:clean', function() { return cleanDir(cfg.paths.staticCSS + '/*.css'); }); -gulp.task('css:main', ['asserts'], function() { +gulp.task('css:main', ['assets'], function() { var autoprefixer = require('gulp-autoprefixer'), less = require('gulp-less'), lessFilter = filter('**/*.less', {restore: true}), @@ -614,7 +614,7 @@ gulp.task('css', ['css:min']); gulp.task('vendors', ['moment', 'ckeditor', 'fontastic', 'lightgallery']); -gulp.task('clean', ['js:clean', 'css:clean', 'asserts:clean']); +gulp.task('clean', ['js:clean', 'css:clean', 'assets:clean']); gulp.task('rainloop:start', ['rainloop:copy', 'rainloop:setup']); diff --git a/package.json b/package.json index 5cad19312..11ede194a 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "autolinker": "1.4.0", "babel-core": "6.20.0", "babel-eslint": "7.1.1", - "babel-loader": "6.2.9", + "babel-loader": "6.2.10", "babel-plugin-transform-decorators-legacy": "1.3.4", "babel-plugin-transform-runtime": "6.15.0", "babel-preset-es2015": "6.18.0", diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index 01caf0a92..260e5ba46 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -2137,12 +2137,13 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack * @param string $sSignMeToken = '' * @param string $sAdditionalCode = '' * @param string $bAdditionalCodeSignMe = false + * @param string $bSkipTwoFactorAuth = false * * @return \RainLoop\Model\Account * @throws \RainLoop\Exceptions\ClientException */ public function LoginProcess(&$sEmail, &$sPassword, $sSignMeToken = '', - $sAdditionalCode = '', $bAdditionalCodeSignMe = false) + $sAdditionalCode = '', $bAdditionalCodeSignMe = false, $bSkipTwoFactorAuth = false) { $sInputEmail = $sEmail; @@ -2265,8 +2266,8 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack throw $oException; } - // Two factor auth - if ($this->TwoFactorAuthProvider()->IsActive()) + // 2FA + if (!$bSkipTwoFactorAuth && $this->TwoFactorAuthProvider()->IsActive()) { $aData = $this->getTwoFactorInfo($oAccount); if ($aData && isset($aData['IsSet'], $aData['Enable']) && !empty($aData['Secret']) && $aData['IsSet'] && $aData['Enable']) @@ -2852,7 +2853,7 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountDoesNotExist); } - $oNewAccount = $this->LoginProcess($sEmail, $sPassword); + $oNewAccount = $this->LoginProcess($sEmail, $sPassword, '', '', false, true); $oNewAccount->SetParentEmail($sParentEmail); $aAccounts[$oNewAccount->Email()] = $oNewAccount->GetAuthToken(); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php index 3515a6a1e..52c03c9fa 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php @@ -1,807 +1,807 @@ -oHttp = $oHttp; - $this->oActions = $oActions; - } - - /** - * @return bool - */ - public function GoogleDisconnect($oAccount) - { - $oGoogle = $this->GoogleConnector(); - if ($oAccount && $oGoogle) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $sEncodedeData = $oSettings->GetConf('GoogleAccessToken', ''); - - if (!empty($sEncodedeData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); - if (\is_array($aData) && !empty($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aData['id']) - ); - } - } - - $oSettings->SetConf('GoogleAccessToken', ''); - $oSettings->SetConf('GoogleSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return bool - */ - public function FacebookDisconnect($oAccount) - { - $oFacebook = $this->FacebookConnector($oAccount ? $oAccount : null); - if ($oAccount && $oFacebook) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - - $sEncodedeData = $oSettings->GetConf('FacebookAccessToken', ''); - - if (!empty($sEncodedeData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); - if (is_array($aData) && isset($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $aData['id']) - ); - } - } - - $oSettings->SetConf('FacebookAccessToken', ''); - $oSettings->SetConf('FacebookSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return bool - */ - public function TwitterDisconnect($oAccount) - { - $oTwitter = $this->TwitterConnector(); - if ($oAccount && $oTwitter) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $sEncodedData = $oSettings->GetConf('TwitterAccessToken', ''); - - if (!empty($sEncodedData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedData); - if (is_array($aData) && isset($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aData['id']) - ); - } - } - - $oSettings->SetConf('TwitterAccessToken', ''); - $oSettings->SetConf('TwitterSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return string - */ - public function popupServiceResult($sTypeStr, $sLoginUrl, $bLogin, $iErrorCode) - { - $sResult = ''; - $bNiceSocialRedirect = $this->oActions->Config()->Get('labs', 'nice_social_redirect', true); - $bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false); - - $sIcon = $sTypeStr; - if ('facebook' === $sIcon) - { - $sIcon = $sIcon.'-alt'; - } - - if ($sLoginUrl) - { - if (!$bNiceSocialRedirect) - { - $this->oActions->Location($sLoginUrl); - } - else - { - $this->oHttp->ServerNoCache(); - @\header('Content-Type: text/html; charset=utf-8'); - - $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( - '{{RefreshMeta}}' => '', - '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), - '{{Icon}}' => $sIcon, - '{{Script}}' => '' - )); - } - } - else - { - $this->oHttp->ServerNoCache(); - @\header('Content-Type: text/html; charset=utf-8'); - - $sCallBackType = $bLogin ? '_login' : ''; - $sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_'.$sTypeStr.$sCallBackType.'_service'; - - if (!$bNiceSocialRedirect) - { - $sResult = ''; - } - else - { - $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( - '{{RefreshMeta}}' => '', - '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), - '{{Icon}}' => $sIcon, - '{{Script}}' => '' - )); - } - } - - return $sResult; - } - - /** - * @return string - */ - public function GooglePopupService($bGmail = false) - { - $sLoginUrl = ''; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - try - { - $oGoogle = $this->GoogleConnector(); - if ($this->oHttp->HasQuery('error')) - { - $iErrorCode = ('access_denied' === $this->oHttp->GetQuery('error')) ? - \RainLoop\Notifications::SocialGoogleLoginAccessDisable : \RainLoop\Notifications::UnknownError; - } - else if ($oGoogle) - { - $oAccount = $this->oActions->GetAccount(); - $bLogin = !$oAccount; - - $sCheckToken = ''; - $sCheckAuth = ''; - $sState = $this->oHttp->GetQuery('state'); - if (!empty($sState)) - { - $aParts = explode('|', $sState, 3); - - if (!$bGmail) - { - $bGmail = !empty($aParts[0]) ? '1' === (string) $aParts[0] : false; - } - - $sCheckToken = !empty($aParts[1]) ? $aParts[1] : ''; - $sCheckAuth = !empty($aParts[2]) ? $aParts[2] : ''; - } - - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle'; - if (!$this->oHttp->HasQuery('code')) - { - $aParams = array( - 'scope' => \trim(\implode(' ', array( - 'https://www.googleapis.com/auth/userinfo.email', - 'https://www.googleapis.com/auth/userinfo.profile', - $bGmail ? 'https://mail.google.com/' : '' - ))), - 'state' => ($bGmail ? '1' : '0').'|'.\RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(), - 'response_type' => 'code' - ); - -// if ($bGmail) -// { -// $aParams['access_type'] = 'offline'; -// $aParams['approval_prompt'] = 'force'; -// } - - $sLoginUrl = $oGoogle->getAuthenticationUrl('https://accounts.google.com/o/oauth2/auth', $sRedirectUrl, $aParams); - } - else if (!empty($sState) && $sCheckToken === \RainLoop\Utils::GetConnectionToken()) - { - if (!empty($sCheckAuth)) - { - $this->oActions->SetSpecAuthToken($sCheckAuth); - $oAccount = $this->oActions->GetAccount(); - $bLogin = !$oAccount; - } - - $aParams = array('code' => $this->oHttp->GetQuery('code'), 'redirect_uri' => $sRedirectUrl); - $aAuthorizationResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', $aParams); - - if (!empty($aAuthorizationResponse['result']['access_token'])) - { - $oGoogle->setAccessToken($aAuthorizationResponse['result']['access_token']); - $aUserInfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo'); - - if (!empty($aUserInfoResponse['result']['id'])) - { - if ($bLogin) - { - $aUserData = null; - if ($bGmail) - { - if (!empty($aUserInfoResponse['result']['email'])) - { - $aUserData = array( - 'Email' => $aUserInfoResponse['result']['email'], - 'Password' => APP_GOOGLE_ACCESS_TOKEN_PREFIX.$aAuthorizationResponse['result']['access_token'] - ); - } - } - else - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']) - ); - - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - } - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable; - } - } - - if ($oAccount && !$bGmail) - { - $aUserData = array( - 'ID' => $aUserInfoResponse['result']['id'], - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $sSocialName = !empty($aUserInfoResponse['result']['name']) ? $aUserInfoResponse['result']['name'] : ''; - $sSocialName .= !empty($aUserInfoResponse['result']['email']) ? ' ('.$aUserInfoResponse['result']['email'].')' : ''; - $sSocialName = \trim($sSocialName); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - - $oSettings->SetConf('GoogleAccessToken', \RainLoop\Utils::EncodeKeyValues(array( - 'id' => $aUserInfoResponse['result']['id'] - ))); - - $oSettings->SetConf('GoogleSocialName', $sSocialName); - - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - - return $this->popupServiceResult('google', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return string - */ - public function FacebookPopupService() - { - $sLoginUrl = ''; - $sSocialName = ''; - - $mData = false; - $sUserData = ''; - $aUserData = false; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - if (0 === \strlen($this->oActions->GetSpecAuthToken()) && $this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - } - - $oAccount = $this->oActions->GetAccount(); - - $oFacebook = $this->FacebookConnector($oAccount); - if ($oFacebook) - { - try - { - $oSession = $oFacebook->getSessionFromRedirect(); - if (!$oSession && !$this->oHttp->HasQuery('state')) - { - $sLoginUrl = $oFacebook->getLoginUrl().'&display=popup'; - } - else if ($oSession) - { - $oRequest = new \Facebook\FacebookRequest($oSession, 'GET', '/me'); - $oResponse = $oRequest->execute(); - $oGraphObject = $oResponse->getGraphObject(); - - $mData = $oGraphObject->getProperty('id'); - $sSocialName = $oGraphObject->getProperty('name'); - - if ($oAccount) - { - if ($mData && 0 < \strlen($mData)) - { - $aUserData = array( - 'id' => $mData, - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $oSettings->SetConf('FacebookSocialName', $sSocialName); - $oSettings->SetConf('FacebookAccessToken', \RainLoop\Utils::EncodeKeyValues(array('id' => $mData))); - - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $mData), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - else - { - $bLogin = true; - - if ($mData && 0 < \strlen($mData)) - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $mData)); - - if ($sUserData) - { - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - } - } - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable; - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return $this->popupServiceResult('facebook', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return string - */ - public function TwitterPopupService() - { - $sLoginUrl = ''; - - $sSocialName = ''; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialTwitter'; - if (0 < strlen($this->oActions->GetSpecAuthToken())) - { - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - else if ($this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - - try - { - $oTwitter = $this->TwitterConnector(); - if ($oTwitter) - { - $sSessionKey = \implode('_', array('twitter', - \md5($oTwitter->config['consumer_secret']), \md5(\RainLoop\Utils::GetConnectionToken()), 'AuthSessionData')); - - $oAccount = $this->oActions->GetAccount(); - if ($oAccount) - { - if (isset($_REQUEST['oauth_verifier'])) - { - $sAuth = $this->oActions->Cacher()->Get($sSessionKey); - $oAuth = $sAuth ? \json_decode($sAuth, true) : null; - - if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) - { - $oTwitter->config['user_token'] = $oAuth['oauth_token']; - $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( - 'oauth_callback' => $sRedirectUrl, - 'oauth_verifier' => $_REQUEST['oauth_verifier'] - )); - - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); - if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) - { - $aAccessToken['id'] = $aAccessToken['user_id']; - - $oTwitter->config['user_token'] = $aAccessToken['oauth_token']; - $oTwitter->config['user_secret'] = $aAccessToken['oauth_token_secret']; - - $sSocialName = !empty($aAccessToken['screen_name']) ? '@'.$aAccessToken['screen_name'] : $aAccessToken['user_id']; - $sSocialName = \trim($sSocialName); - - $aUserData = array( - 'id' => $aAccessToken['id'], - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $oSettings->SetConf('TwitterAccessToken', \RainLoop\Utils::EncodeKeyValues($aAccessToken)); - $oSettings->SetConf('TwitterSocialName', $sSocialName); - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['id']), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - } - } - else - { - $aParams = array( - 'oauth_callback' => $sRedirectUrl, - 'x_auth_access_type' => 'read' - ); - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $oAuth = $oTwitter->extract_params($oTwitter->response['response']); - if (!empty($oAuth['oauth_token'])) - { - $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); - $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; - } - } - } - } - else - { - $bLogin = true; - - if (isset($_REQUEST['oauth_verifier'])) - { - $sAuth = $this->oActions->Cacher()->Get($sSessionKey); - $oAuth = $sAuth ? \json_decode($sAuth, true) : null; - if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) - { - $oTwitter->config['user_token'] = $oAuth['oauth_token']; - $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( - 'oauth_callback' => $sRedirectUrl, - 'oauth_verifier' => $_REQUEST['oauth_verifier'] - )); - - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); - if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id']) - ); - - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialTwitterLoginAccessDisable; - } - - $this->oActions->Cacher()->Delete($sSessionKey); - } - } - } - } - else - { - $aParams = array( - 'oauth_callback' => $sRedirectUrl, - 'x_auth_access_type' => 'read' - ); - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $oAuth = $oTwitter->extract_params($oTwitter->response['response']); - if (!empty($oAuth['oauth_token'])) - { - $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); - $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; - } - } - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - - return $this->popupServiceResult('twitter', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return \OAuth2\Client|null - */ - public function GoogleConnector() - { - $oGoogle = false; - $oConfig = $this->oActions->Config(); - if ($oConfig->Get('social', 'google_enable', false) && - '' !== \trim($oConfig->Get('social', 'google_client_id', '')) && - '' !== \trim($oConfig->Get('social', 'google_client_secret', ''))) - { - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/Client.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/IGrantType.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/RefreshToken.php'; - - try - { - $oGoogle = new \OAuth2\Client( - \trim($oConfig->Get('social', 'google_client_id', '')), - \trim($oConfig->Get('social', 'google_client_secret', ''))); - - $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); - if (0 < \strlen($sProxy)) - { - $oGoogle->setCurlOption(CURLOPT_PROXY, $sProxy); - - $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); - if (0 < \strlen($sProxyAuth)) - { - $oGoogle->setCurlOption(CURLOPT_PROXYUSERPWD, $sProxyAuth); - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return false === $oGoogle ? null : $oGoogle; - } - - /** - * @return \tmhOAuth|null - */ - public function TwitterConnector() - { - $oTwitter = false; - $oConfig = $this->oActions->Config(); - if ($oConfig->Get('social', 'twitter_enable', false) && - '' !== \trim($oConfig->Get('social', 'twitter_consumer_key', '')) && - '' !== \trim($oConfig->Get('social', 'twitter_consumer_secret', ''))) - { - include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhOAuth.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhUtilities.php'; - - $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); - $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); - - $oTwitter = new \tmhOAuth(array( - 'consumer_key' => \trim($oConfig->Get('social', 'twitter_consumer_key', '')), - 'consumer_secret' => \trim($oConfig->Get('social', 'twitter_consumer_secret', '')), - 'curl_proxy' => 0 < \strlen($sProxy) ? $sProxy : false, - 'curl_proxyuserpwd' => 0 < \strlen($sProxyAuth) ? $sProxyAuth : false - )); - } - - return false === $oTwitter ? null : $oTwitter; - } - - /** - * @param \RainLoop\Model\Account|null $oAccount = null - * - * @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null - */ - public function FacebookConnector($oAccount = null) - { - $oFacebook = false; - $oConfig = $this->oActions->Config(); - $sAppID = \trim($oConfig->Get('social', 'fb_app_id', '')); - - if (\version_compare(PHP_VERSION, '5.4.0', '>=') && - $oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID && - '' !== \trim($oConfig->Get('social', 'fb_app_secret', '')) && - \class_exists('Facebook\FacebookSession') - ) - { - \Facebook\FacebookSession::setDefaultApplication($sAppID, - \trim($oConfig->Get('social', 'fb_app_secret', ''))); - - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialFacebook'; - if (0 < \strlen($this->oActions->GetSpecAuthToken())) - { - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - else if ($this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - - try - { - $oAccount = $this->oActions->GetAccount(); - - $oFacebook = new \RainLoop\Common\RainLoopFacebookRedirectLoginHelper($sRedirectUrl); - $oFacebook->initRainLoopData(array( - 'rlAppId' => $sAppID, - 'rlAccount' => $oAccount, - 'rlUserHash' => \RainLoop\Utils::GetConnectionToken(), - 'rlStorageProvaider' => $this->oActions->StorageProvider() - )); - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return false === $oFacebook ? null : $oFacebook; - } - - /** - * @return string - */ - public function GoogleUserLoginStorageKey($oGoogle, $sGoogleUserId) - { - return \implode('_', array('google', \md5($oGoogle->getClientId()), $sGoogleUserId, APP_SALT)); - } - - /** - * @return string - */ - public function FacebookUserLoginStorageKey($oFacebook, $sFacebookUserId) - { - return \implode('_', array('facebookNew', \md5($oFacebook->GetRLAppId()), $sFacebookUserId, APP_SALT)); - } - - /** - * @return string - */ - public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId) - { - return \implode('_', array('twitter_2', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT)); - } - - /** - * @param \RainLoop\Model\Account|null $oAccount - * @param string $sEmail - * @param string $sPassword - * - * @return int - */ - private function loginProcess(&$oAccount, $sEmail, $sPassword) - { - $iErrorCode = \RainLoop\Notifications::UnknownError; - - try - { - $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); - if ($oAccount instanceof \RainLoop\Model\Account) - { - $this->oActions->AuthToken($oAccount); - $iErrorCode = 0; - } - else - { - $oAccount = null; - $iErrorCode = \RainLoop\Notifications::AuthError; - } - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - $iErrorCode = $oException->getCode(); - } - catch (\Exception $oException) - { - unset($oException); - $iErrorCode = \RainLoop\Notifications::UnknownError; - } - - return $iErrorCode; - } +oHttp = $oHttp; + $this->oActions = $oActions; + } + + /** + * @return bool + */ + public function GoogleDisconnect($oAccount) + { + $oGoogle = $this->GoogleConnector(); + if ($oAccount && $oGoogle) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $sEncodedeData = $oSettings->GetConf('GoogleAccessToken', ''); + + if (!empty($sEncodedeData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); + if (\is_array($aData) && !empty($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aData['id']) + ); + } + } + + $oSettings->SetConf('GoogleAccessToken', ''); + $oSettings->SetConf('GoogleSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return bool + */ + public function FacebookDisconnect($oAccount) + { + $oFacebook = $this->FacebookConnector($oAccount ? $oAccount : null); + if ($oAccount && $oFacebook) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + + $sEncodedeData = $oSettings->GetConf('FacebookAccessToken', ''); + + if (!empty($sEncodedeData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); + if (is_array($aData) && isset($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $aData['id']) + ); + } + } + + $oSettings->SetConf('FacebookAccessToken', ''); + $oSettings->SetConf('FacebookSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return bool + */ + public function TwitterDisconnect($oAccount) + { + $oTwitter = $this->TwitterConnector(); + if ($oAccount && $oTwitter) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $sEncodedData = $oSettings->GetConf('TwitterAccessToken', ''); + + if (!empty($sEncodedData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedData); + if (is_array($aData) && isset($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aData['id']) + ); + } + } + + $oSettings->SetConf('TwitterAccessToken', ''); + $oSettings->SetConf('TwitterSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return string + */ + public function popupServiceResult($sTypeStr, $sLoginUrl, $bLogin, $iErrorCode) + { + $sResult = ''; + $bNiceSocialRedirect = $this->oActions->Config()->Get('labs', 'nice_social_redirect', true); + $bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false); + + $sIcon = $sTypeStr; + if ('facebook' === $sIcon) + { + $sIcon = $sIcon.'-alt'; + } + + if ($sLoginUrl) + { + if (!$bNiceSocialRedirect) + { + $this->oActions->Location($sLoginUrl); + } + else + { + $this->oHttp->ServerNoCache(); + @\header('Content-Type: text/html; charset=utf-8'); + + $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( + '{{RefreshMeta}}' => '', + '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), + '{{Icon}}' => $sIcon, + '{{Script}}' => '' + )); + } + } + else + { + $this->oHttp->ServerNoCache(); + @\header('Content-Type: text/html; charset=utf-8'); + + $sCallBackType = $bLogin ? '_login' : ''; + $sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_'.$sTypeStr.$sCallBackType.'_service'; + + if (!$bNiceSocialRedirect) + { + $sResult = ''; + } + else + { + $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( + '{{RefreshMeta}}' => '', + '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), + '{{Icon}}' => $sIcon, + '{{Script}}' => '' + )); + } + } + + return $sResult; + } + + /** + * @return string + */ + public function GooglePopupService($bGmail = false) + { + $sLoginUrl = ''; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + try + { + $oGoogle = $this->GoogleConnector(); + if ($this->oHttp->HasQuery('error')) + { + $iErrorCode = ('access_denied' === $this->oHttp->GetQuery('error')) ? + \RainLoop\Notifications::SocialGoogleLoginAccessDisable : \RainLoop\Notifications::UnknownError; + } + else if ($oGoogle) + { + $oAccount = $this->oActions->GetAccount(); + $bLogin = !$oAccount; + + $sCheckToken = ''; + $sCheckAuth = ''; + $sState = $this->oHttp->GetQuery('state'); + if (!empty($sState)) + { + $aParts = explode('|', $sState, 3); + + if (!$bGmail) + { + $bGmail = !empty($aParts[0]) ? '1' === (string) $aParts[0] : false; + } + + $sCheckToken = !empty($aParts[1]) ? $aParts[1] : ''; + $sCheckAuth = !empty($aParts[2]) ? $aParts[2] : ''; + } + + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle'; + if (!$this->oHttp->HasQuery('code')) + { + $aParams = array( + 'scope' => \trim(\implode(' ', array( + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile', + $bGmail ? 'https://mail.google.com/' : '' + ))), + 'state' => ($bGmail ? '1' : '0').'|'.\RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(), + 'response_type' => 'code' + ); + +// if ($bGmail) +// { +// $aParams['access_type'] = 'offline'; +// $aParams['approval_prompt'] = 'force'; +// } + + $sLoginUrl = $oGoogle->getAuthenticationUrl('https://accounts.google.com/o/oauth2/auth', $sRedirectUrl, $aParams); + } + else if (!empty($sState) && $sCheckToken === \RainLoop\Utils::GetConnectionToken()) + { + if (!empty($sCheckAuth)) + { + $this->oActions->SetSpecAuthToken($sCheckAuth); + $oAccount = $this->oActions->GetAccount(); + $bLogin = !$oAccount; + } + + $aParams = array('code' => $this->oHttp->GetQuery('code'), 'redirect_uri' => $sRedirectUrl); + $aAuthorizationResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', $aParams); + + if (!empty($aAuthorizationResponse['result']['access_token'])) + { + $oGoogle->setAccessToken($aAuthorizationResponse['result']['access_token']); + $aUserInfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo'); + + if (!empty($aUserInfoResponse['result']['id'])) + { + if ($bLogin) + { + $aUserData = null; + if ($bGmail) + { + if (!empty($aUserInfoResponse['result']['email'])) + { + $aUserData = array( + 'Email' => $aUserInfoResponse['result']['email'], + 'Password' => APP_GOOGLE_ACCESS_TOKEN_PREFIX.$aAuthorizationResponse['result']['access_token'] + ); + } + } + else + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']) + ); + + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + } + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable; + } + } + + if ($oAccount && !$bGmail) + { + $aUserData = array( + 'ID' => $aUserInfoResponse['result']['id'], + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $sSocialName = !empty($aUserInfoResponse['result']['name']) ? $aUserInfoResponse['result']['name'] : ''; + $sSocialName .= !empty($aUserInfoResponse['result']['email']) ? ' ('.$aUserInfoResponse['result']['email'].')' : ''; + $sSocialName = \trim($sSocialName); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + + $oSettings->SetConf('GoogleAccessToken', \RainLoop\Utils::EncodeKeyValues(array( + 'id' => $aUserInfoResponse['result']['id'] + ))); + + $oSettings->SetConf('GoogleSocialName', $sSocialName); + + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + return $this->popupServiceResult('google', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return string + */ + public function FacebookPopupService() + { + $sLoginUrl = ''; + $sSocialName = ''; + + $mData = false; + $sUserData = ''; + $aUserData = false; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + if (0 === \strlen($this->oActions->GetSpecAuthToken()) && $this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + } + + $oAccount = $this->oActions->GetAccount(); + + $oFacebook = $this->FacebookConnector($oAccount); + if ($oFacebook) + { + try + { + $oSession = $oFacebook->getSessionFromRedirect(); + if (!$oSession && !$this->oHttp->HasQuery('state')) + { + $sLoginUrl = $oFacebook->getLoginUrl().'&display=popup'; + } + else if ($oSession) + { + $oRequest = new \Facebook\FacebookRequest($oSession, 'GET', '/me'); + $oResponse = $oRequest->execute(); + $oGraphObject = $oResponse->getGraphObject(); + + $mData = $oGraphObject->getProperty('id'); + $sSocialName = $oGraphObject->getProperty('name'); + + if ($oAccount) + { + if ($mData && 0 < \strlen($mData)) + { + $aUserData = array( + 'id' => $mData, + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $oSettings->SetConf('FacebookSocialName', $sSocialName); + $oSettings->SetConf('FacebookAccessToken', \RainLoop\Utils::EncodeKeyValues(array('id' => $mData))); + + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $mData), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + else + { + $bLogin = true; + + if ($mData && 0 < \strlen($mData)) + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $mData)); + + if ($sUserData) + { + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + } + } + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable; + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return $this->popupServiceResult('facebook', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return string + */ + public function TwitterPopupService() + { + $sLoginUrl = ''; + + $sSocialName = ''; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialTwitter'; + if (0 < strlen($this->oActions->GetSpecAuthToken())) + { + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + else if ($this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + + try + { + $oTwitter = $this->TwitterConnector(); + if ($oTwitter) + { + $sSessionKey = \implode('_', array('twitter', + \md5($oTwitter->config['consumer_secret']), \md5(\RainLoop\Utils::GetConnectionToken()), 'AuthSessionData')); + + $oAccount = $this->oActions->GetAccount(); + if ($oAccount) + { + if (isset($_REQUEST['oauth_verifier'])) + { + $sAuth = $this->oActions->Cacher()->Get($sSessionKey); + $oAuth = $sAuth ? \json_decode($sAuth, true) : null; + + if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) + { + $oTwitter->config['user_token'] = $oAuth['oauth_token']; + $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( + 'oauth_callback' => $sRedirectUrl, + 'oauth_verifier' => $_REQUEST['oauth_verifier'] + )); + + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); + if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) + { + $aAccessToken['id'] = $aAccessToken['user_id']; + + $oTwitter->config['user_token'] = $aAccessToken['oauth_token']; + $oTwitter->config['user_secret'] = $aAccessToken['oauth_token_secret']; + + $sSocialName = !empty($aAccessToken['screen_name']) ? '@'.$aAccessToken['screen_name'] : $aAccessToken['user_id']; + $sSocialName = \trim($sSocialName); + + $aUserData = array( + 'id' => $aAccessToken['id'], + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $oSettings->SetConf('TwitterAccessToken', \RainLoop\Utils::EncodeKeyValues($aAccessToken)); + $oSettings->SetConf('TwitterSocialName', $sSocialName); + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['id']), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + } + } + else + { + $aParams = array( + 'oauth_callback' => $sRedirectUrl, + 'x_auth_access_type' => 'read' + ); + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $oAuth = $oTwitter->extract_params($oTwitter->response['response']); + if (!empty($oAuth['oauth_token'])) + { + $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); + $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; + } + } + } + } + else + { + $bLogin = true; + + if (isset($_REQUEST['oauth_verifier'])) + { + $sAuth = $this->oActions->Cacher()->Get($sSessionKey); + $oAuth = $sAuth ? \json_decode($sAuth, true) : null; + if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) + { + $oTwitter->config['user_token'] = $oAuth['oauth_token']; + $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( + 'oauth_callback' => $sRedirectUrl, + 'oauth_verifier' => $_REQUEST['oauth_verifier'] + )); + + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); + if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id']) + ); + + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialTwitterLoginAccessDisable; + } + + $this->oActions->Cacher()->Delete($sSessionKey); + } + } + } + } + else + { + $aParams = array( + 'oauth_callback' => $sRedirectUrl, + 'x_auth_access_type' => 'read' + ); + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $oAuth = $oTwitter->extract_params($oTwitter->response['response']); + if (!empty($oAuth['oauth_token'])) + { + $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); + $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; + } + } + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + return $this->popupServiceResult('twitter', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return \OAuth2\Client|null + */ + public function GoogleConnector() + { + $oGoogle = false; + $oConfig = $this->oActions->Config(); + if ($oConfig->Get('social', 'google_enable', false) && + '' !== \trim($oConfig->Get('social', 'google_client_id', '')) && + '' !== \trim($oConfig->Get('social', 'google_client_secret', ''))) + { + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/Client.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/IGrantType.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/RefreshToken.php'; + + try + { + $oGoogle = new \OAuth2\Client( + \trim($oConfig->Get('social', 'google_client_id', '')), + \trim($oConfig->Get('social', 'google_client_secret', ''))); + + $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); + if (0 < \strlen($sProxy)) + { + $oGoogle->setCurlOption(CURLOPT_PROXY, $sProxy); + + $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); + if (0 < \strlen($sProxyAuth)) + { + $oGoogle->setCurlOption(CURLOPT_PROXYUSERPWD, $sProxyAuth); + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return false === $oGoogle ? null : $oGoogle; + } + + /** + * @return \tmhOAuth|null + */ + public function TwitterConnector() + { + $oTwitter = false; + $oConfig = $this->oActions->Config(); + if ($oConfig->Get('social', 'twitter_enable', false) && + '' !== \trim($oConfig->Get('social', 'twitter_consumer_key', '')) && + '' !== \trim($oConfig->Get('social', 'twitter_consumer_secret', ''))) + { + include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhOAuth.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhUtilities.php'; + + $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); + $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); + + $oTwitter = new \tmhOAuth(array( + 'consumer_key' => \trim($oConfig->Get('social', 'twitter_consumer_key', '')), + 'consumer_secret' => \trim($oConfig->Get('social', 'twitter_consumer_secret', '')), + 'curl_proxy' => 0 < \strlen($sProxy) ? $sProxy : false, + 'curl_proxyuserpwd' => 0 < \strlen($sProxyAuth) ? $sProxyAuth : false + )); + } + + return false === $oTwitter ? null : $oTwitter; + } + + /** + * @param \RainLoop\Model\Account|null $oAccount = null + * + * @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null + */ + public function FacebookConnector($oAccount = null) + { + $oFacebook = false; + $oConfig = $this->oActions->Config(); + $sAppID = \trim($oConfig->Get('social', 'fb_app_id', '')); + + if (\version_compare(PHP_VERSION, '5.4.0', '>=') && + $oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID && + '' !== \trim($oConfig->Get('social', 'fb_app_secret', '')) && + \class_exists('Facebook\FacebookSession') + ) + { + \Facebook\FacebookSession::setDefaultApplication($sAppID, + \trim($oConfig->Get('social', 'fb_app_secret', ''))); + + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialFacebook'; + if (0 < \strlen($this->oActions->GetSpecAuthToken())) + { + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + else if ($this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + + try + { + $oAccount = $this->oActions->GetAccount(); + + $oFacebook = new \RainLoop\Common\RainLoopFacebookRedirectLoginHelper($sRedirectUrl); + $oFacebook->initRainLoopData(array( + 'rlAppId' => $sAppID, + 'rlAccount' => $oAccount, + 'rlUserHash' => \RainLoop\Utils::GetConnectionToken(), + 'rlStorageProvaider' => $this->oActions->StorageProvider() + )); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return false === $oFacebook ? null : $oFacebook; + } + + /** + * @return string + */ + public function GoogleUserLoginStorageKey($oGoogle, $sGoogleUserId) + { + return \implode('_', array('google', \md5($oGoogle->getClientId()), $sGoogleUserId, APP_SALT)); + } + + /** + * @return string + */ + public function FacebookUserLoginStorageKey($oFacebook, $sFacebookUserId) + { + return \implode('_', array('facebookNew', \md5($oFacebook->GetRLAppId()), $sFacebookUserId, APP_SALT)); + } + + /** + * @return string + */ + public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId) + { + return \implode('_', array('twitter_2', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT)); + } + + /** + * @param \RainLoop\Model\Account|null $oAccount + * @param string $sEmail + * @param string $sPassword + * + * @return int + */ + private function loginProcess(&$oAccount, $sEmail, $sPassword) + { + $iErrorCode = \RainLoop\Notifications::UnknownError; + + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword, '', '', false, true); + if ($oAccount instanceof \RainLoop\Model\Account) + { + $this->oActions->AuthToken($oAccount); + $iErrorCode = 0; + } + else + { + $oAccount = null; + $iErrorCode = \RainLoop\Notifications::AuthError; + } + } + catch (\RainLoop\Exceptions\ClientException $oException) + { + $iErrorCode = $oException->getCode(); + } + catch (\Exception $oException) + { + unset($oException); + $iErrorCode = \RainLoop\Notifications::UnknownError; + } + + return $iErrorCode; + } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4edff796b..ebd654828 100644 --- a/yarn.lock +++ b/yarn.lock @@ -401,9 +401,9 @@ babel-helpers@^6.16.0: babel-runtime "^6.0.0" babel-template "^6.16.0" -babel-loader@6.2.9: - version "6.2.9" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.2.9.tgz#2bce6a1c29b47afa90b937ba1fb1f87084d61c61" +babel-loader@6.2.10: + version "6.2.10" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.2.10.tgz#adefc2b242320cd5d15e65b31cea0e8b1b02d4b0" dependencies: find-cache-dir "^0.1.1" loader-utils "^0.2.11"